Compare commits

..

1 Commits

Author SHA1 Message Date
Conrad Irwin
111583b863 WIP: enforce buffer ordering in multibuffer 2025-01-29 22:44:17 -07:00
973 changed files with 39798 additions and 57051 deletions

View File

@@ -0,0 +1,15 @@
name: Feature Request
description: "Tip: open this issue template from within Zed with the `request feature` command palette action"
type: "Feature"
body:
- type: textarea
attributes:
label: Describe the feature
description: A one line summary, and description of what you want to happen.
value: |
Summary:
Description:
Screenshots:
<!-- drag files here -->

View File

@@ -5,44 +5,21 @@ type: "Bug"
body:
- type: textarea
attributes:
label: Summary
description: Describe the bug with a one line summary, and provide detailed reproduction steps
label: Describe the bug / provide steps to reproduce it
description: A one line summary, and detailed reproduction steps
value: |
<!-- Please insert a one line summary of the issue below -->
SUMMARY_SENTENCE_HERE
<!-- Be verbose: Include all steps necessary to reproduce from a clean Zed installation. -->
<!-- Code snippets are better than images, a repository link that reproduces the issue is ideal. -->
Summary:
<!-- Include all steps necessary to reproduce from a clean Zed installation. Be verbose -->
Steps to trigger the problem:
1.
2.
3.
4.
Actual Behavior:
Expected Behavior:
<!--
Is there anything additional necessary to reproduce this issue?
- settings.json, keymap.json, .editorconfig etc?
- Does it happen intermittently or only with specific projects / file types?
- Have you found a workaround?
Did you check your Zed.log to see if there is any relevant details there?
- When including large items (videos, screenshots, logs, configs) please wrap with:
<details><summary>See inside for XXXXYYY</summary>
```shell
code
```
</details>
-->
validations:
required: true

View File

@@ -4,10 +4,10 @@ type: "Crash"
body:
- type: textarea
attributes:
label: Summary
description: Describe the bug with a one line summary, and provide detailed reproduction steps
label: Describe the bug / provide steps to reproduce it
description: A one line summary, and detailed reproduction steps
value: |
<!-- Please insert a one line summary of the issue below -->
Summary:
<!-- Include all steps necessary to reproduce from a clean Zed installation. Be verbose -->
Steps to trigger the problem:

View File

@@ -1,9 +1,6 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-issue-config.json
blank_issues_enabled: false
contact_links:
- name: Feature Request
url: https://github.com/zed-industries/zed/discussions/new/choose
about: To request a feature, open a new Discussion in one of the appropriate Discussion categories
- name: Zed Discussion Forum
url: https://github.com/zed-industries/zed/discussions
about: A community discussion forum

View File

@@ -10,7 +10,7 @@ runs:
cargo install cargo-nextest --locked
- name: Install Node
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
with:
node-version: "18"

View File

@@ -1,26 +0,0 @@
name: "Run tests on Windows"
description: "Runs the tests on Windows"
inputs:
working-directory:
description: "The working directory"
required: true
default: "."
runs:
using: "composite"
steps:
- name: Install Rust
shell: pwsh
working-directory: ${{ inputs.working-directory }}
run: cargo install cargo-nextest --locked
- name: Install Node
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
node-version: "18"
- name: Run tests
shell: pwsh
working-directory: ${{ inputs.working-directory }}
run: cargo nextest run --workspace --no-fail-fast

View File

@@ -109,16 +109,8 @@ jobs:
- name: cargo clippy
run: ./script/clippy
- name: Install cargo-machete
uses: clechasseur/rs-cargo@v2
with:
command: install
args: cargo-machete@0.7.0
- name: Check unused dependencies
uses: clechasseur/rs-cargo@v2
with:
command: machete
uses: bnjbvr/cargo-machete@main
- name: Check licenses
run: |
@@ -143,7 +135,6 @@ jobs:
cargo check -p gpui --features "macos-blade"
cargo check -p workspace
cargo build -p remote_server
cargo check -p gpui --examples
script/check-rust-livekit-macos
# Since the macOS runners are stateful, so we need to remove the config file to prevent potential bug.
@@ -190,7 +181,6 @@ jobs:
run: |
cargo build -p zed
cargo check -p workspace
cargo check -p gpui --examples
# Even the Linux runner is not stateful, in theory there is no need to do this cleanup.
# But, to avoid potential issues in the future if we choose to use a stateful Linux runner and forget to add code
@@ -236,6 +226,7 @@ jobs:
if: always()
run: rm -rf ./../.cargo
# todo(windows): Actually run the tests
windows_tests:
timeout-minutes: 60
name: (Windows) Run Clippy and tests
@@ -245,55 +236,33 @@ jobs:
# more info here:- https://github.com/rust-lang/cargo/issues/13020
- name: Enable longer pathnames for git
run: git config --system core.longpaths true
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
clean: false
- name: Create Dev Drive using ReFS
run: ./script/setup-dev-driver.ps1
# actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
- name: Copy Git Repo to Dev Drive
run: |
Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.ZED_WORKSPACE }}" -Recurse
- name: Cache dependencies
uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
workspaces: ${{ env.ZED_WORKSPACE }}
cache-provider: "github"
- name: Configure CI
run: |
mkdir -p ${{ env.CARGO_HOME }} -ErrorAction Ignore
cp ./.cargo/ci-config.toml ${{ env.CARGO_HOME }}/config.toml
mkdir -p ./../.cargo
cp ./.cargo/ci-config.toml ./../.cargo/config.toml
- name: cargo clippy
working-directory: ${{ env.ZED_WORKSPACE }}
# Windows can't run shell scripts, so we need to use `cargo xtask`.
run: cargo xtask clippy
- name: Run tests
uses: ./.github/actions/run_tests_windows
with:
working-directory: ${{ env.ZED_WORKSPACE }}
- name: Build Zed
working-directory: ${{ env.ZED_WORKSPACE }}
run: cargo build
- name: Check dev drive space
working-directory: ${{ env.ZED_WORKSPACE }}
# `setup-dev-driver.ps1` creates a 100GB drive, with CI taking up ~45GB of the drive.
run: ./script/exit-ci-if-dev-drive-is-full.ps1 95
# Since the Windows runners are stateful, so we need to remove the config file to prevent potential bug.
- name: Clean CI config file
if: always()
run: Remove-Item -Path "${{ env.CARGO_HOME }}/config.toml" -Force
run: Remove-Item -Path "./../.cargo" -Recurse -Force
bundle-mac:
timeout-minutes: 120
@@ -306,16 +275,15 @@ jobs:
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
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@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
with:
node-version: "18"
@@ -491,6 +459,6 @@ jobs:
- bundle
steps:
- name: gh release
run: gh release edit $GITHUB_REF_NAME --draft=true
run: gh release edit $GITHUB_REF_NAME --draft=false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -29,7 +29,8 @@ jobs:
maxLength: 2000
truncationSymbol: "..."
- name: Discord Webhook Action
uses: tsickert/discord-webhook@c840d45a03a323fbc3f7507ac7769dbd91bfb164 # v5.3.0
uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4 # v6.0.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: ${{ steps.get-content.outputs.string }}
flags: 4 # suppress embeds - https://discord.com/developers/docs/resources/message#message-object-message-flags

View File

@@ -1,25 +0,0 @@
name: Update All Top Ranking Issues
on:
schedule:
- cron: "0 */12 * * *"
workflow_dispatch:
jobs:
update_top_ranking_issues:
runs-on: ubuntu-latest
if: github.repository == 'zed-industries/zed'
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up uv
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
with:
version: "latest"
enable-cache: true
cache-dependency-glob: "script/update_top_ranking_issues/pyproject.toml"
- name: Install Python 3.13
run: uv python install 3.13
- name: Install dependencies
run: uv sync --project script/update_top_ranking_issues -p 3.13
- name: Run script
run: uv run --project script/update_top_ranking_issues script/update_top_ranking_issues/main.py --github-token ${{ secrets.GITHUB_TOKEN }} --issue-reference-number 5393

View File

@@ -1,25 +0,0 @@
name: Update Weekly Top Ranking Issues
on:
schedule:
- cron: "0 15 * * *"
workflow_dispatch:
jobs:
update_top_ranking_issues:
runs-on: ubuntu-latest
if: github.repository == 'zed-industries/zed'
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up uv
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
with:
version: "latest"
enable-cache: true
cache-dependency-glob: "script/update_top_ranking_issues/pyproject.toml"
- name: Install Python 3.13
run: uv python install 3.13
- name: Install dependencies
run: uv sync --project script/update_top_ranking_issues -p 3.13
- name: Run script
run: uv run --project script/update_top_ranking_issues script/update_top_ranking_issues/main.py --github-token ${{ secrets.GITHUB_TOKEN }} --issue-reference-number 6952 --query-day-interval 7

View File

@@ -22,7 +22,7 @@ jobs:
version: 9
- name: Setup Node
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
with:
node-version: "20"
cache: "pnpm"

View File

@@ -37,36 +37,29 @@ jobs:
mdbook build ./docs --dest-dir=../target/deploy/docs/
- name: Deploy Docs
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy target/deploy --project-name=docs
- name: Deploy Install
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: r2 object put -f script/install.sh zed-open-source-website-assets/install.sh
- name: Deploy Docs Workers
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy .cloudflare/docs-proxy/src/worker.js
- name: Deploy Install Workers
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
uses: cloudflare/wrangler-action@7a5f8bbdfeedcde38e6777a50fe685f89259d4ca # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy .cloudflare/docs-proxy/src/worker.js
- name: Preserve Wrangler logs
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
if: always()
with:
name: wrangler_logs
path: /home/runner/.config/.wrangler/logs/

View File

@@ -24,13 +24,11 @@ jobs:
- name: Prettier Check on /docs
working-directory: ./docs
run: |
pnpm dlx prettier@${PRETTIER_VERSION} . --check || {
pnpm dlx prettier . --check || {
echo "To fix, run from the root of the zed repo:"
echo " cd docs && pnpm dlx prettier@${PRETTIER_VERSION} . --write && cd .."
echo " cd docs && pnpm dlx prettier . --write && cd .."
false
}
env:
PRETTIER_VERSION: 3.5.0
- name: Check for Typos with Typos-CLI
uses: crate-ci/typos@8e6a4285bcbde632c5d79900a7779746e8b7ea3f # v1.24.6

View File

@@ -1,33 +0,0 @@
name: Issue Response
on:
schedule:
- cron: "0 12 * * 2"
workflow_dispatch:
jobs:
issue-response:
if: github.repository_owner == 'zed-industries'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
with:
version: 9
- name: Setup Node
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
node-version: "20"
cache: "pnpm"
cache-dependency-path: "script/issue_response/pnpm-lock.yaml"
- run: pnpm install --dir script/issue_response
- name: Run Issue Response
run: pnpm run --dir script/issue_response start
env:
ISSUE_RESPONSE_GITHUB_TOKEN: ${{ secrets.ISSUE_RESPONSE_GITHUB_TOKEN }}
SLACK_ISSUE_RESPONSE_WEBHOOK_URL: ${{ secrets.SLACK_ISSUE_RESPONSE_WEBHOOK_URL }}

View File

@@ -23,7 +23,7 @@ jobs:
- buildjet-16vcpu-ubuntu-2204
steps:
- name: Install Node
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
with:
node-version: "18"

View File

@@ -62,16 +62,15 @@ jobs:
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
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 }}
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
steps:
- name: Install Node
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
with:
node-version: "18"

55
.gitignore vendored
View File

@@ -1,36 +1,35 @@
**/*.db
**/cargo-target
**/target
**/venv
*.wasm
*.xcodeproj
.DS_Store
.blob_store
.build
.envrc
.flatpak-builder
.idea
.netrc
.pytest_cache
.swiftpm
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.venv
.vscode
.wrangler
/.direnv
/assets/*licenses.*
/crates/collab/seed.json
/crates/theme/schemas/theme.json
/crates/zed/resources/flatpak/flatpak-cargo-sources.json
/dev.zed.Zed*.json
.envrc
.idea
**/target
**/cargo-target
/zed.xcworkspace
.DS_Store
/plugins/bin
/script/node_modules
/snap
/zed.xcworkspace
DerivedData/
/crates/theme/schemas/theme.json
/crates/collab/seed.json
/crates/zed/resources/flatpak/flatpak-cargo-sources.json
/dev.zed.Zed*.json
/assets/*licenses.*
**/venv
.build
*.wasm
Packages
*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
.swiftpm
**/*.db
.pytest_cache
.venv
.blob_store
.vscode
.wrangler
.flatpak-builder
# Don't commit any secrets to the repo.
.env.secret.toml

View File

@@ -21,8 +21,6 @@ Andrei Zvonimir Crnković <andrei@0x7f.dev>
Andrei Zvonimir Crnković <andrei@0x7f.dev> <andreicek@0x7f.dev>
Antonio Scandurra <me@as-cii.com>
Antonio Scandurra <me@as-cii.com> <antonio@zed.dev>
Ben Kunkle <ben@zed.dev>
Ben Kunkle <ben@zed.dev> <ben.kunkle@gmail.com>
Bennet Bo Fenner <bennet@zed.dev>
Bennet Bo Fenner <bennet@zed.dev> <53836821+bennetbo@users.noreply.github.com>
Bennet Bo Fenner <bennet@zed.dev> <bennetbo@gmx.de>
@@ -114,8 +112,6 @@ Sebastijan Kelnerič <sebastijan.kelneric@sebba.dev> <sebastijan.kelneric@vichav
Sergey Onufrienko <sergey@onufrienko.com>
Shish <webmaster@shishnet.org>
Shish <webmaster@shishnet.org> <shish@shishnet.org>
Smit Barmase <0xtimsb@gmail.com>
Smit Barmase <0xtimsb@gmail.com> <smit@zed.dev>
Thorben Kröger <dev@thorben.net>
Thorben Kröger <dev@thorben.net> <thorben.kroeger@hexagon.com>
Thorsten Ball <thorsten@zed.dev>

View File

@@ -14,12 +14,12 @@
},
"JSON": {
"tab_size": 2,
"preferred_line_length": 120,
"preferred_line_length": 100,
"formatter": "prettier"
},
"JSONC": {
"tab_size": 2,
"preferred_line_length": 120,
"preferred_line_length": 100,
"formatter": "prettier"
},
"JavaScript": {

View File

@@ -37,16 +37,6 @@ We plan to set aside time each week to pair program with contributors on promisi
- Pair with us and watch us code to learn the codebase
- Low effort PRs, such as those that just re-arrange syntax, won't be merged without a compelling justification
## File icons
Zed's default icon theme consists of icons that are hand-designed to fit together in a cohesive manner.
We do not accept PRs for file icons that are just an off-the-shelf SVG taken from somewhere else.
### Adding new icons to the Zed icon theme
If you would like to add a new icon to the Zed icon theme, [open a Discussion](https://github.com/zed-industries/zed/discussions/new?category=ux-and-design) and we can work with you on getting an icon designed and added to Zed.
## Bird's-eye view of Zed
Zed is made up of several smaller crates - let's go over those you're most likely to interact with:
@@ -62,9 +52,3 @@ Zed is made up of several smaller crates - let's go over those you're most likel
- [`rpc`](/crates/rpc) defines messages to be exchanged with collaboration server.
- [`theme`](/crates/theme) defines the theme system and provides a default theme.
- [`ui`](/crates/ui) is a collection of UI components and common patterns used throughout Zed.
- [`cli`](/crates/cli) is the CLI crate which invokes the Zed binary.
- [`zed`](/crates/zed) is where all things come together, and the `main` entry point for Zed.
## Packaging Zed
Check our [notes for packaging Zed](https://zed.dev/docs/development/linux#notes-for-packaging-zed).

1830
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
resolver = "2"
members = [
"crates/activity_indicator",
"crates/zed_predict_tos",
"crates/anthropic",
"crates/assets",
"crates/assistant",
@@ -15,10 +16,7 @@ members = [
"crates/audio",
"crates/auto_update",
"crates/auto_update_ui",
"crates/aws_http_client",
"crates/bedrock",
"crates/breadcrumbs",
"crates/buffer_diff",
"crates/call",
"crates/channel",
"crates/cli",
@@ -29,15 +27,12 @@ members = [
"crates/collections",
"crates/command_palette",
"crates/command_palette_hooks",
"crates/component",
"crates/component_preview",
"crates/context_server",
"crates/context_server_settings",
"crates/copilot",
"crates/credentials_provider",
"crates/db",
"crates/deepseek",
"crates/diagnostics",
"crates/deepseek",
"crates/docs_preprocessor",
"crates/editor",
"crates/evals",
@@ -50,17 +45,16 @@ members = [
"crates/feedback",
"crates/file_finder",
"crates/file_icons",
"crates/fireworks",
"crates/fs",
"crates/fsevent",
"crates/fuzzy",
"crates/git",
"crates/git_hosting_providers",
"crates/git_ui",
"crates/go_to_line",
"crates/google_ai",
"crates/gpui",
"crates/gpui_macros",
"crates/gpui_tokio",
"crates/html_to_markdown",
"crates/http_client",
"crates/image_viewer",
@@ -77,17 +71,15 @@ members = [
"crates/language_selector",
"crates/language_tools",
"crates/languages",
"crates/livekit_api",
"crates/livekit_client",
"crates/livekit_client_macos",
"crates/livekit_server",
"crates/lmstudio",
"crates/lsp",
"crates/markdown",
"crates/markdown_preview",
"crates/media",
"crates/menu",
"crates/migrator",
"crates/mistral",
"crates/multi_buffer",
"crates/node_runtime",
"crates/notifications",
@@ -95,7 +87,6 @@ members = [
"crates/open_ai",
"crates/outline",
"crates/outline_panel",
"crates/panel",
"crates/paths",
"crates/picker",
"crates/prettier",
@@ -115,7 +106,6 @@ members = [
"crates/rich_text",
"crates/rope",
"crates/rpc",
"crates/schema_generator",
"crates/search",
"crates/semantic_index",
"crates/semantic_version",
@@ -151,8 +141,9 @@ members = [
"crates/ui",
"crates/ui_input",
"crates/ui_macros",
"crates/reqwest_client",
"crates/util",
"crates/util_macros",
"crates/vcs_menu",
"crates/vim",
"crates/vim_mode_setting",
"crates/welcome",
@@ -161,6 +152,7 @@ members = [
"crates/zed",
"crates/zed_actions",
"crates/zeta",
"crates/git_ui",
#
# Extensions
@@ -175,7 +167,9 @@ members = [
"extensions/haskell",
"extensions/html",
"extensions/lua",
"extensions/php",
"extensions/perplexity",
"extensions/prisma",
"extensions/proto",
"extensions/purescript",
"extensions/ruff",
@@ -207,6 +201,7 @@ edition = "2021"
activity_indicator = { path = "crates/activity_indicator" }
ai = { path = "crates/ai" }
zed_predict_tos = { path = "crates/zed_predict_tos" }
anthropic = { path = "crates/anthropic" }
assets = { path = "crates/assets" }
assistant = { path = "crates/assistant" }
@@ -220,8 +215,6 @@ assistant_tools = { path = "crates/assistant_tools" }
audio = { path = "crates/audio" }
auto_update = { path = "crates/auto_update" }
auto_update_ui = { path = "crates/auto_update_ui" }
aws_http_client = { path = "crates/aws_http_client" }
bedrock = { path = "crates/bedrock" }
breadcrumbs = { path = "crates/breadcrumbs" }
call = { path = "crates/call" }
channel = { path = "crates/channel" }
@@ -233,16 +226,12 @@ collab_ui = { path = "crates/collab_ui" }
collections = { path = "crates/collections" }
command_palette = { path = "crates/command_palette" }
command_palette_hooks = { path = "crates/command_palette_hooks" }
component = { path = "crates/component" }
component_preview = { path = "crates/component_preview" }
context_server = { path = "crates/context_server" }
context_server_settings = { path = "crates/context_server_settings" }
copilot = { path = "crates/copilot" }
credentials_provider = { path = "crates/credentials_provider" }
db = { path = "crates/db" }
deepseek = { path = "crates/deepseek" }
diagnostics = { path = "crates/diagnostics" }
buffer_diff = { path = "crates/buffer_diff" }
editor = { path = "crates/editor" }
extension = { path = "crates/extension" }
extension_host = { path = "crates/extension_host" }
@@ -251,19 +240,19 @@ feature_flags = { path = "crates/feature_flags" }
feedback = { path = "crates/feedback" }
file_finder = { path = "crates/file_finder" }
file_icons = { path = "crates/file_icons" }
fireworks = { path = "crates/fireworks" }
fs = { path = "crates/fs" }
fsevent = { path = "crates/fsevent" }
fuzzy = { path = "crates/fuzzy" }
git = { path = "crates/git" }
git_hosting_providers = { path = "crates/git_hosting_providers" }
git_ui = { path = "crates/git_ui" }
git_hosting_providers = { path = "crates/git_hosting_providers" }
go_to_line = { path = "crates/go_to_line" }
google_ai = { path = "crates/google_ai" }
gpui = { path = "crates/gpui", default-features = false, features = [
"http_client",
] }
gpui_macros = { path = "crates/gpui_macros" }
gpui_tokio = { path = "crates/gpui_tokio" }
html_to_markdown = { path = "crates/html_to_markdown" }
http_client = { path = "crates/http_client" }
image_viewer = { path = "crates/image_viewer" }
@@ -280,17 +269,15 @@ language_models = { path = "crates/language_models" }
language_selector = { path = "crates/language_selector" }
language_tools = { path = "crates/language_tools" }
languages = { path = "crates/languages" }
livekit_api = { path = "crates/livekit_api" }
livekit_client = { path = "crates/livekit_client" }
livekit_client_macos = { path = "crates/livekit_client_macos" }
livekit_server = { path = "crates/livekit_server" }
lmstudio = { path = "crates/lmstudio" }
lsp = { path = "crates/lsp" }
markdown = { path = "crates/markdown" }
markdown_preview = { path = "crates/markdown_preview" }
media = { path = "crates/media" }
menu = { path = "crates/menu" }
migrator = { path = "crates/migrator" }
mistral = { path = "crates/mistral" }
multi_buffer = { path = "crates/multi_buffer" }
node_runtime = { path = "crates/node_runtime" }
notifications = { path = "crates/notifications" }
@@ -299,7 +286,6 @@ open_ai = { path = "crates/open_ai" }
outline = { path = "crates/outline" }
outline_panel = { path = "crates/outline_panel" }
paths = { path = "crates/paths" }
panel = { path = "crates/panel" }
picker = { path = "crates/picker" }
plugin = { path = "crates/plugin" }
plugin_macros = { path = "crates/plugin_macros" }
@@ -355,7 +341,7 @@ ui = { path = "crates/ui" }
ui_input = { path = "crates/ui_input" }
ui_macros = { path = "crates/ui_macros" }
util = { path = "crates/util" }
util_macros = { path = "crates/util_macros" }
vcs_menu = { path = "crates/vcs_menu" }
vim = { path = "crates/vim" }
vim_mode_setting = { path = "crates/vim_mode_setting" }
welcome = { path = "crates/welcome" }
@@ -370,11 +356,12 @@ zeta = { path = "crates/zeta" }
#
aho-corasick = "1.1"
alacritty_terminal = { git = "https://github.com/zed-industries/alacritty.git", rev = "03c2907b44b4189aac5fdeaea331f5aab5c7072e"}
# TODO(#18342): Update to version 0.25 from crates.io when it is released.
alacritty_terminal = { git = "https://github.com/alacritty/alacritty.git", rev = "5e78d20c709cb1ab8d44ca7a8702cc26d779227c" }
any_vec = "0.14"
anyhow = "1.0.86"
arrayvec = { version = "0.7.4", features = ["serde"] }
ashpd = { version = "0.11", default-features = false, features = ["async-std"] }
ashpd = { version = "0.10", default-features = false, features = ["async-std"]}
async-compat = "0.2.1"
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
async-dispatcher = "0.1"
@@ -386,17 +373,11 @@ async-trait = "0.1"
async-tungstenite = "0.28"
async-watch = "0.3.1"
async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] }
aws-config = { version = "1.5.16", features = ["behavior-version-latest"] }
aws-credential-types = { version = "1.2.1", features = ["hardcoded-credentials"] }
aws-sdk-bedrockruntime = { version = "1.73.0", features = ["behavior-version-latest"] }
aws-smithy-runtime-api = { version = "1.7.3", features = ["http-1x", "client"] }
aws-smithy-types = { version = "1.2.13", features = ["http-body-1-x"] }
base64 = "0.22"
bitflags = "2.6.0"
blade-graphics = { git = "https://github.com/kvark/blade", rev = "b16f5c7bd873c7126f48c82c39e7ae64602ae74f" }
blade-macros = { git = "https://github.com/kvark/blade", rev = "b16f5c7bd873c7126f48c82c39e7ae64602ae74f" }
blade-util = { git = "https://github.com/kvark/blade", rev = "b16f5c7bd873c7126f48c82c39e7ae64602ae74f" }
naga = { version = "23.1.0", features = ["wgsl-in"] }
blade-graphics = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" }
blade-macros = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" }
blade-util = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" }
blake3 = "1.5.3"
bytes = "1.0"
cargo_metadata = "0.19"
@@ -408,7 +389,7 @@ cocoa-foundation = "0.2.0"
convert_case = "0.7.0"
core-foundation = "0.9.3"
core-foundation-sys = "0.8.6"
ctor = "0.3.0"
ctor = "0.2.6"
dashmap = "6.0"
derive_more = "0.99.17"
dirs = "4.0"
@@ -432,10 +413,8 @@ hyper = "0.14"
http = "1.1"
ignore = "0.4.22"
image = "0.25.1"
imara-diff = "0.1.8"
indexmap = { version = "2.7.0", features = ["serde"] }
indoc = "2"
inventory = "0.3.19"
itertools = "0.14.0"
jsonwebtoken = "9.3"
jupyter-protocol = { version = "0.6.0" }
@@ -443,19 +422,13 @@ jupyter-websocket-client = { version = "0.9.0" }
libc = "0.2"
libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
linkify = "0.10.0"
linkme = "0.3.31"
livekit = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "811ceae29fabee455f110c56cd66b3f49a7e5003", features = [
"dispatcher",
"services-dispatcher",
"rustls-tls-native-roots",
], default-features = false }
livekit = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev="060964da10574cd9bf06463a53bf6e0769c5c45e", features = ["dispatcher", "services-dispatcher", "rustls-tls-native-roots"], default-features = false }
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
markup5ever_rcdom = "0.3.0"
nanoid = "0.4"
nbformat = { version = "0.10.0" }
nix = "0.29"
num-format = "0.4.4"
once_cell = "1.20"
ordered-float = "2.1.1"
palette = { version = "0.7.5", default-features = false, features = ["std"] }
parking_lot = "0.12.1"
@@ -469,13 +442,11 @@ pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git"
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
postage = { version = "0.5", features = ["futures-traits"] }
pretty_assertions = { version = "1.3.0", features = ["unstable"] }
proc-macro2 = "1.0.93"
profiling = "1"
prost = "0.9"
prost-build = "0.9"
prost-types = "0.9"
pulldown-cmark = { version = "0.12.0", default-features = false }
quote = "1.0.9"
rand = "0.8.5"
rayon = "1.8"
regex = "1.5"
@@ -495,8 +466,8 @@ runtimelib = { version = "0.25.0", default-features = false, features = [
rustc-demangle = "0.1.23"
rust-embed = { version = "8.4", features = ["include-exclude"] }
rustc-hash = "2.1.0"
rustls = { version = "0.23.22" }
rustls-platform-verifier = "0.5.0"
rustls = "0.21.12"
rustls-native-certs = "0.8.0"
schemars = { version = "0.8", features = ["impl_json_schema", "indexmap2"] }
semver = "1.0"
serde = { version = "1.0", features = ["derive", "rc"] }
@@ -511,15 +482,14 @@ sha2 = "0.10"
shellexpand = "2.1.0"
shlex = "1.3.0"
signal-hook = "0.3.17"
similar = "1.3"
simplelog = "0.12.2"
smallvec = { version = "1.6", features = ["union"] }
smol = "2.0"
sqlformat = "0.2"
streaming-iterator = "0.1"
strsim = "0.11"
strum = { version = "0.26.0", features = ["derive"] }
subtle = "2.5.0"
syn = { version = "1.0.72", features = ["full", "extra-traits"] }
sys-locale = "0.3.1"
sysinfo = "0.31.0"
take-until = "0.2.0"
@@ -537,48 +507,46 @@ tiny_http = "0.8"
toml = "0.8"
tokio = { version = "1" }
tower-http = "0.4.4"
tree-sitter = { version = "0.25.2", features = ["wasm"] }
tree-sitter = { version = "0.23", features = ["wasm"] }
tree-sitter-bash = "0.23"
tree-sitter-c = "0.23"
tree-sitter-cpp = "0.23"
tree-sitter-css = "0.23"
tree-sitter-elixir = "0.3"
tree-sitter-embedded-template = "0.23.0"
tree-sitter-gitcommit = {git = "https://github.com/zed-industries/tree-sitter-git-commit", rev = "88309716a69dd13ab83443721ba6e0b491d37ee9"}
tree-sitter-go = "0.23"
tree-sitter-go-mod = { git = "https://github.com/camdencheek/tree-sitter-go-mod", rev = "6efb59652d30e0e9cd5f3b3a669afd6f1a926d3c", package = "tree-sitter-gomod" }
tree-sitter-gowork = { git = "https://github.com/zed-industries/tree-sitter-go-work", rev = "acb0617bf7f4fda02c6217676cc64acb89536dc7" }
tree-sitter-heex = { git = "https://github.com/zed-industries/tree-sitter-heex", rev = "1dd45142fbb05562e35b2040c6129c9bca346592" }
tree-sitter-diff = "0.1.0"
tree-sitter-html = "0.23"
tree-sitter-html = "0.20"
tree-sitter-jsdoc = "0.23"
tree-sitter-json = "0.24"
tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", rev = "9a23c1a96c0513d8fc6520972beedd419a973539" }
tree-sitter-python = "0.23"
tree-sitter-regex = "0.24"
tree-sitter-regex = "0.23"
tree-sitter-ruby = "0.23"
tree-sitter-rust = "0.23"
tree-sitter-typescript = "0.23"
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "baff0b51c64ef6a1fb1f8390f3ad6015b83ec13a" }
unicase = "2.6"
unindent = "0.2.0"
unindent = "0.1.7"
unicode-segmentation = "1.10"
unicode-script = "0.5.7"
url = "2.2"
uuid = { version = "1.1.2", features = ["v4", "v5", "v7", "serde"] }
wasmparser = "0.221"
wasm-encoder = "0.221"
wasmtime = { version = "29", default-features = false, features = [
wasmparser = "0.215"
wasm-encoder = "0.215"
wasmtime = { version = "24", default-features = false, features = [
"async",
"demangle",
"runtime",
"cranelift",
"component-model",
] }
wasmtime-wasi = "29"
wasmtime-wasi = "24"
which = "6.0.0"
wit-component = "0.221"
zed_llm_client = "0.4"
wit-component = "0.201"
zstd = "0.11"
metal = "0.31"
@@ -639,7 +607,6 @@ features = [
# TODO livekit https://github.com/RustAudio/cpal/pull/891
[patch.crates-io]
cpal = { git = "https://github.com/zed-industries/cpal", rev = "fd8bc2fd39f1f5fdee5a0690656caff9a26d9d50" }
real-async-tls = { git = "https://github.com/zed-industries/async-tls", rev = "1e759a4b5e370f87dc15e40756ac4f8815b61d9d", package = "async-tls"}
[profile.dev]
split-debuginfo = "unpacked"
@@ -693,6 +660,7 @@ telemetry_events = { codegen-units = 1 }
theme_selector = { codegen-units = 1 }
time_format = { codegen-units = 1 }
ui_input = { codegen-units = 1 }
vcs_menu = { codegen-units = 1 }
zed_actions = { codegen-units = 1 }
[profile.release]

View File

@@ -1,4 +1,4 @@
Copyright 2022 - 2025 Zed Industries, Inc.
Copyright 2022 - 2024 Zed Industries, Inc.

View File

@@ -1,4 +1,4 @@
Copyright 2022 - 2025 Zed Industries, Inc.
Copyright 2022 - 2024 Zed Industries, Inc.
Licensed under the Apache License, Version 2.0 (the "License");

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="283.6413 127.3453 56 55.9999" width="16px" height="16px">
<path d="M 808.592 158.131 C 807.489 158.131 806.592 157.234 806.592 156.131 C 806.592 155.028 807.489 154.131 808.592 154.131 C 809.695 154.131 810.592 155.028 810.592 156.131 C 810.592 157.234 809.695 158.131 808.592 158.131 Z M 776.705 185.039 L 773.457 183.145 L 780.122 178.979 L 779.062 177.283 L 771.505 182.006 L 765.592 178.557 L 765.592 169.666 L 771.147 165.963 L 770.037 164.299 L 764.551 167.956 L 758.592 164.551 L 758.592 159.711 L 765.088 155.999 L 764.096 154.263 L 758.592 157.408 L 758.592 153.711 L 764.592 150.283 L 770.592 153.711 L 770.592 157.565 L 766.077 160.274 L 767.107 161.988 L 771.592 159.297 L 776.077 161.988 L 777.107 160.274 L 772.592 157.565 L 772.592 153.666 L 778.147 149.963 C 778.425 149.777 778.592 149.465 778.592 149.131 L 778.592 142.131 L 776.592 142.131 L 776.592 148.596 L 771.551 151.956 L 765.592 148.551 L 765.592 139.705 L 770.592 136.789 L 770.592 145.131 L 772.592 145.131 L 772.592 135.622 L 776.705 133.223 L 784.592 135.852 L 784.592 164.565 L 770.077 173.274 L 771.107 174.988 L 784.592 166.897 L 784.592 182.41 L 776.705 185.039 Z M 806.592 169.131 C 806.592 170.234 805.695 171.131 804.592 171.131 C 803.489 171.131 802.592 170.234 802.592 169.131 C 802.592 168.028 803.489 167.131 804.592 167.131 C 805.695 167.131 806.592 168.028 806.592 169.131 Z M 796.592 179.131 C 796.592 180.234 795.695 181.131 794.592 181.131 C 793.489 181.131 792.592 180.234 792.592 179.131 C 792.592 178.028 793.489 177.131 794.592 177.131 C 795.695 177.131 796.592 178.028 796.592 179.131 Z M 795.592 139.131 C 795.592 138.028 796.489 137.131 797.592 137.131 C 798.695 137.131 799.592 138.028 799.592 139.131 C 799.592 140.234 798.695 141.131 797.592 141.131 C 796.489 141.131 795.592 140.234 795.592 139.131 Z M 808.592 152.131 C 806.733 152.131 805.181 153.411 804.734 155.131 L 786.592 155.131 L 786.592 150.131 L 797.592 150.131 C 798.145 150.131 798.592 149.683 798.592 149.131 L 798.592 142.989 C 800.312 142.542 801.592 140.989 801.592 139.131 C 801.592 136.925 799.798 135.131 797.592 135.131 C 795.386 135.131 793.592 136.925 793.592 139.131 C 793.592 140.989 794.872 142.542 796.592 142.989 L 796.592 148.131 L 786.592 148.131 L 786.592 135.131 C 786.592 134.7 786.317 134.319 785.908 134.182 L 776.908 131.182 C 776.634 131.092 776.336 131.122 776.088 131.267 L 764.088 138.267 C 763.78 138.446 763.592 138.776 763.592 139.131 L 763.592 148.551 L 757.096 152.263 C 756.784 152.441 756.592 152.772 756.592 153.131 L 756.592 165.131 C 756.592 165.49 756.784 165.821 757.096 165.999 L 763.592 169.711 L 763.592 179.131 C 763.592 179.486 763.78 179.816 764.088 179.995 L 776.088 186.995 C 776.242 187.085 776.417 187.131 776.592 187.131 C 776.698 187.131 776.805 187.114 776.908 187.08 L 785.908 184.08 C 786.317 183.943 786.592 183.562 786.592 183.131 L 786.592 171.131 L 793.592 171.131 L 793.592 175.273 C 791.872 175.72 790.592 177.273 790.592 179.131 C 790.592 181.337 792.386 183.131 794.592 183.131 C 796.798 183.131 798.592 181.337 798.592 179.131 C 798.592 177.273 797.312 175.72 795.592 175.273 L 795.592 170.131 C 795.592 169.579 795.145 169.131 794.592 169.131 L 786.592 169.131 L 786.592 164.131 L 799.092 164.131 L 801.23 166.981 C 800.831 167.603 800.592 168.338 800.592 169.131 C 800.592 171.337 802.386 173.131 804.592 173.131 C 806.798 173.131 808.592 171.337 808.592 169.131 C 808.592 166.925 806.798 165.131 804.592 165.131 C 803.908 165.131 803.274 165.319 802.711 165.623 L 800.392 162.531 C 800.203 162.279 799.906 162.131 799.592 162.131 L 786.592 162.131 L 786.592 157.131 L 804.734 157.131 C 805.181 158.851 806.733 160.131 808.592 160.131 C 810.798 160.131 812.592 158.337 812.592 156.131 C 812.592 153.925 810.798 152.131 808.592 152.131 Z" fill-rule="evenodd" fill-opacity="1" style="" id="object-0" transform="matrix(1, 0, 0, 1, -472.9506530761719, -3.7858259677886963)"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1 +0,0 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Mistral</title><g><path d="M15 6v4h-2V6h2zm4-4v4h-2V2h2zM3 2H1h2zM1 2h2v20H1V2zm8 12h2v4H9v-4zm8 0h2v8h-2v-8z"></path><path d="M19 2h4v4h-4V2zM3 2h4v4H3V2z" opacity=".4"></path><path d="M15 10V6h8v4h-8zM3 10V6h8v4H3z" opacity=".5"></path><path d="M3 14v-4h20v4z" opacity=".6"></path><path d="M11 14h4v4h-4v-4zm8 0h4v4h-4v-4zM3 14h4v4H3v-4z" opacity=".7"></path><path d="M19 18h4v4h-4v-4zM3 18h4v4H3v-4z" opacity=".8"></path></g></svg>

Before

Width:  |  Height:  |  Size: 598 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"><circle cx="7.25" cy="7.25" r="3" fill="currentColor"></circle></svg>

Before

Width:  |  Height:  |  Size: 165 B

View File

@@ -0,0 +1,214 @@
{
"stems": {
"Dockerfile": "docker",
"Podfile": "ruby",
"Procfile": "heroku"
},
"suffixes": {
"Emakefile": "erlang",
"aac": "audio",
"accdb": "storage",
"app.src": "erlang",
"astro": "astro",
"avi": "video",
"avif": "image",
"bak": "backup",
"bash": "terminal",
"bash_aliases": "terminal",
"bash_logout": "terminal",
"bash_profile": "terminal",
"bashrc": "terminal",
"bmp": "image",
"c": "c",
"c++": "cpp",
"cc": "cpp",
"cjs": "javascript",
"coffee": "coffeescript",
"conf": "settings",
"cpp": "cpp",
"css": "css",
"csv": "storage",
"cxx": "cpp",
"cts": "typescript",
"dart": "dart",
"dat": "storage",
"db": "storage",
"dbf": "storage",
"diff": "diff",
"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",
"TAG_EDITMSG": "vcs",
"MERGE_MSG": "vcs",
"COMMIT_EDITMSG": "vcs",
"NOTES_EDITMSG": "vcs",
"EDIT_DESCRIPTION": "vcs",
"gleam": "gleam",
"go": "go",
"gql": "graphql",
"graphql": "graphql",
"graphqls": "graphql",
"h": "c",
"handlebars": "code",
"hbs": "template",
"hcl": "hcl",
"heex": "elixir",
"heic": "image",
"heif": "image",
"hh": "cpp",
"hpp": "cpp",
"hrl": "erlang",
"hs": "haskell",
"htm": "template",
"html": "template",
"hxx": "cpp",
"ib": "storage",
"ico": "image",
"ini": "settings",
"inl": "cpp",
"j2k": "image",
"java": "java",
"jfif": "image",
"jl": "julia",
"jp2": "image",
"jpeg": "image",
"jpg": "image",
"js": "javascript",
"json": "storage",
"jsonc": "storage",
"jsx": "react",
"jxl": "image",
"kt": "kotlin",
"ldf": "storage",
"lock": "lock",
"lockb": "bun",
"log": "log",
"lua": "lua",
"m4a": "audio",
"m4v": "video",
"markdown": "document",
"md": "document",
"mdb": "storage",
"mdf": "storage",
"mdx": "document",
"metadata": "code",
"metal": "metal",
"mjs": "javascript",
"mka": "audio",
"mkv": "video",
"ml": "ocaml",
"mli": "ocaml",
"mod": "go",
"mov": "video",
"mp3": "audio",
"mp4": "video",
"mts": "typescript",
"myd": "storage",
"myi": "storage",
"nim": "nim",
"nix": "nix",
"nu": "terminal",
"odp": "document",
"ods": "document",
"odt": "document",
"ogg": "audio",
"opus": "audio",
"otf": "font",
"pcss": "css",
"pdb": "storage",
"pdf": "document",
"php": "php",
"plist": "template",
"png": "image",
"postcss": "css",
"ppt": "document",
"pptx": "document",
"prettierignore": "prettier",
"prettierrc": "prettier",
"prisma": "prisma",
"profile": "terminal",
"ps1": "terminal",
"psd": "image",
"py": "python",
"qoi": "image",
"r": "r",
"rb": "ruby",
"rebar.config": "erlang",
"rkt": "code",
"roc": "roc",
"rs": "rust",
"rtf": "document",
"sass": "sass",
"sav": "storage",
"sc": "scala",
"scala": "scala",
"scm": "code",
"scss": "sass",
"sdf": "storage",
"sh": "terminal",
"sql": "storage",
"sqlite": "storage",
"svelte": "template",
"svg": "image",
"swift": "swift",
"tcl": "tcl",
"tf": "terraform",
"tfvars": "terraform",
"tiff": "image",
"toml": "toml",
"ts": "typescript",
"tsv": "storage",
"tsx": "react",
"ttf": "font",
"txt": "document",
"v": "v",
"vsh": "v",
"vv": "v",
"vue": "vue",
"wav": "audio",
"webm": "video",
"webp": "image",
"wma": "audio",
"wmv": "video",
"woff": "font",
"woff2": "font",
"work": "go",
"wv": "audio",
"xls": "document",
"xlsx": "document",
"xml": "template",
"xrl": "erlang",
"yaml": "settings",
"yml": "settings",
"yrl": "erlang",
"zig": "zig",
"zlogin": "terminal",
"zsh": "terminal",
"zsh_aliases": "terminal",
"zsh_histfile": "terminal",
"zsh_profile": "terminal",
"zshenv": "terminal",
"zshrc": "terminal"
}
}

View File

@@ -1,6 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 5C5 3.89543 5.89543 3 7 3H9C10.1046 3 11 3.89543 11 5V6H5V5Z" stroke="black" stroke-width="1.5"/>
<path d="M8 9V11" stroke="black" stroke-width="1.5" stroke-linecap="round"/>
<circle cx="8" cy="9" r="1" fill="black"/>
<rect x="3.75" y="5.75" width="8.5" height="7.5" rx="1.25" stroke="black" stroke-width="1.5" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 452 B

View File

@@ -1,5 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 8.9V11C5.34478 11 4.65522 11 3 11V10.4L7 5.6V5H3V7.1" stroke="black" stroke-width="1.5"/>
<path d="M12 5L14 8L12 11" stroke="black" stroke-width="1.5"/>
<path d="M10 6.5L11 8L10 9.5" stroke="black" stroke-width="1.5"/>
<path d="M7.5 8.9V11C5.43097 11 4.56903 11 2.5 11V10.4L7.5 5.6V5H2.5V7.1" stroke="black" stroke-width="1.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 342 B

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -1,19 +0,0 @@
<svg width="550" height="128" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="tilePattern" width="23" height="23" patternUnits="userSpaceOnUse">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 5L14 8L12 11" stroke="black" stroke-width="1.5"/>
<path d="M10 6.5L11 8L10 9.5" stroke="black" stroke-width="1.5"/>
<path d="M7.5 8.9V11C5.43097 11 4.56903 11 2.5 11V10.4L7.5 5.6V5H2.5V7.1" stroke="black" stroke-width="1.5"/>
</svg>
</pattern>
<linearGradient id="fade" y2="1" x2="0">
<stop offset="0" stop-color="white" stop-opacity=".24"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<mask id="fadeMask" maskContentUnits="objectBoundingBox">
<rect width="1" height="1" fill="url(#fade)"/>
</mask>
</defs>
<rect width="100%" height="100%" fill="url(#tilePattern)" mask="url(#fadeMask)"/>
</svg>

Before

Width:  |  Height:  |  Size: 971 B

View File

@@ -1,6 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M6.75 9.31247L8.25 10.5576V11.75H1.75V10.0803L4.49751 7.44273L5.65909 8.40693L3.73923 10.25H6.75V9.31247ZM8.25 5.85739V4.25H6.31358L8.25 5.85739ZM1.75 5.16209V7.1H3.25V6.4072L1.75 5.16209Z" fill="black"/>
<path opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M10.9624 9.40853L11.9014 8L10.6241 6.08397L9.37598 6.91603L10.0986 8L9.80184 8.44518L10.9624 9.40853Z" fill="black"/>
<path opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M12.8936 11.0116L14.9014 8L12.6241 4.58397L11.376 5.41603L13.0986 8L11.7331 10.0483L12.8936 11.0116Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.1225 13.809C14.0341 13.9146 13.877 13.9289 13.7711 13.8409L1.19311 3.40021C1.08659 3.31178 1.07221 3.15362 1.16104 3.04743L1.87752 2.19101C1.96588 2.0854 2.123 2.07112 2.22895 2.15906L14.8069 12.5998C14.9134 12.6882 14.9278 12.8464 14.839 12.9526L14.1225 13.809Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,5 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 9.33333L14.5 9.66667L12.5 11L10.5 9.66667L10 9.33333" stroke="black" stroke-width="1.5"/>
<path d="M12.5 11V4.5" stroke="black" stroke-width="1.5"/>
<path d="M7.5 8.9V11C5.43097 11 4.56903 11 2.5 11V10.4L7.5 5.6V5H2.5V7.1" stroke="black" stroke-width="1.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 375 B

View File

@@ -1,5 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 6.66667L10.5 6.33333L12.5 5L14.5 6.33333L15 6.66667" stroke="black" stroke-width="1.5"/>
<path d="M12.5 11V5" stroke="black" stroke-width="1.5"/>
<path d="M7.5 8.9V11C5.43097 11 4.56903 11 2.5 11V10.4L7.5 5.6V5H2.5V7.1" stroke="black" stroke-width="1.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 372 B

View File

@@ -24,15 +24,15 @@
"shift-escape": "workspace::ToggleZoom",
"open": "workspace::Open",
"ctrl-o": "workspace::Open",
"ctrl-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
"ctrl-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
"ctrl--": ["zed::DecreaseBufferFontSize", { "persist": false }],
"ctrl-0": ["zed::ResetBufferFontSize", { "persist": false }],
"ctrl-=": "zed::IncreaseBufferFontSize",
"ctrl-+": "zed::IncreaseBufferFontSize",
"ctrl--": "zed::DecreaseBufferFontSize",
"ctrl-0": "zed::ResetBufferFontSize",
"ctrl-,": "zed::OpenSettings",
"ctrl-q": "zed::Quit",
"f11": "zed::ToggleFullScreen",
"ctrl-alt-z": "edit_prediction::RateCompletions",
"ctrl-shift-i": "edit_prediction::ToggleMenu"
"ctrl-alt-z": "zeta::RateCompletions",
"ctrl-shift-i": "inline_completion::ToggleMenu"
}
},
{
@@ -84,12 +84,12 @@
"pageup": "editor::MovePageUp",
"alt-pageup": "editor::PageUp",
"shift-pageup": "editor::SelectPageUp",
"home": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
"home": "editor::MoveToBeginningOfLine",
"down": "editor::MoveDown",
"pagedown": "editor::MovePageDown",
"alt-pagedown": "editor::PageDown",
"shift-pagedown": "editor::SelectPageDown",
"end": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
"end": "editor::MoveToEndOfLine",
"left": "editor::MoveLeft",
"right": "editor::MoveRight",
"ctrl-left": "editor::MoveToPreviousWordStart",
@@ -107,23 +107,23 @@
"ctrl-a": "editor::SelectAll",
"ctrl-l": "editor::SelectLine",
"ctrl-shift-i": "editor::Format",
// "cmd-shift-left": ["editor::SelectToBeginningOfLine", {"stop_at_soft_wraps": true, "stop_at_indent": true }],
// "ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
// "cmd-shift-left": ["editor::SelectToBeginningOfLine", {"stop_at_soft_wraps": true }],
// "ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
// "cmd-shift-right": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
// "ctrl-shift-e": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
// "alt-v": ["editor::MovePageUp", { "center_cursor": true }],
"ctrl-alt-space": "editor::ShowCharacterPalette",
"ctrl-;": "editor::ToggleLineNumbers",
"ctrl-k ctrl-r": "git::Restore",
"ctrl-k ctrl-r": "editor::RevertSelectedHunks",
"ctrl-'": "editor::ToggleSelectedDiffHunks",
"ctrl-\"": "editor::ExpandAllDiffHunks",
"ctrl-\"": "editor::ExpandAllHunkDiffs",
"ctrl-i": "editor::ShowSignatureHelp",
"alt-g b": "editor::ToggleGitBlame",
"menu": "editor::OpenContextMenu",
"shift-f10": "editor::OpenContextMenu",
"ctrl-shift-e": "editor::ToggleEditPrediction"
"alt-enter": "editor::OpenSelectionsInMultibuffer"
}
},
{
@@ -137,26 +137,25 @@
"ctrl-k z": "editor::ToggleSoftWrap",
"find": "buffer_search::Deploy",
"ctrl-f": "buffer_search::Deploy",
"ctrl-h": "buffer_search::DeployReplace",
"ctrl-h": ["buffer_search::Deploy", { "replace_enabled": true }],
// "cmd-e": ["buffer_search::Deploy", { "focus": false }],
"ctrl->": "assistant::QuoteSelection",
"ctrl-<": "assistant::InsertIntoEditor",
"ctrl-alt-e": "editor::SelectEnclosingSymbol",
"alt-enter": "editor::OpenSelectionsInMultibuffer"
"ctrl-alt-e": "editor::SelectEnclosingSymbol"
}
},
{
"context": "Editor && mode == full && edit_prediction",
"context": "Editor && mode == full && inline_completion",
"bindings": {
"alt-]": "editor::NextEditPrediction",
"alt-[": "editor::PreviousEditPrediction",
"alt-right": "editor::AcceptPartialEditPrediction"
"alt-]": "editor::NextInlineCompletion",
"alt-[": "editor::PreviousInlineCompletion",
"alt-right": "editor::AcceptPartialInlineCompletion"
}
},
{
"context": "Editor && !edit_prediction",
"context": "Editor && !inline_completion",
"bindings": {
"alt-\\": "editor::ShowEditPrediction"
"alt-\\": "editor::ShowInlineCompletion"
}
},
{
@@ -184,9 +183,8 @@
"ctrl-alt-/": "assistant::ToggleModelSelector",
"ctrl-k h": "assistant::DeployHistory",
"ctrl-k l": "assistant::DeployPromptLibrary",
"new": "assistant::NewChat",
"ctrl-t": "assistant::NewChat",
"ctrl-n": "assistant::NewChat"
"new": "assistant::NewContext",
"ctrl-n": "assistant::NewContext"
}
},
{
@@ -205,8 +203,8 @@
"enter": "search::SelectNextMatch",
"shift-enter": "search::SelectPrevMatch",
"alt-enter": "search::SelectAllMatches",
"find": "search::FocusSearch",
"ctrl-f": "search::FocusSearch",
"find": "search::FocusSearch",
"ctrl-h": "search::ToggleReplace",
"ctrl-l": "search::ToggleSelection"
}
@@ -276,8 +274,8 @@
"ctrl-pagedown": "pane::ActivateNextItem",
"ctrl-shift-pageup": "pane::SwapItemLeft",
"ctrl-shift-pagedown": "pane::SwapItemRight",
"ctrl-f4": ["pane::CloseActiveItem", { "close_pinned": false }],
"ctrl-w": ["pane::CloseActiveItem", { "close_pinned": false }],
"ctrl-f4": "pane::CloseActiveItem",
"ctrl-w": "pane::CloseActiveItem",
"alt-ctrl-t": ["pane::CloseInactiveItems", { "close_pinned": false }],
"alt-ctrl-shift-w": "workspace::CloseInactiveTabsAndPanes",
"ctrl-k e": ["pane::CloseItemsToTheLeft", { "close_pinned": false }],
@@ -292,15 +290,15 @@
"f3": "search::SelectNextMatch",
"ctrl-alt-shift-g": "search::SelectPrevMatch",
"shift-f3": "search::SelectPrevMatch",
"shift-find": "project_search::ToggleFocus",
"ctrl-shift-f": "project_search::ToggleFocus",
"shift-find": "project_search::ToggleFocus",
"ctrl-alt-shift-h": "search::ToggleReplace",
"ctrl-alt-shift-l": "search::ToggleSelection",
"alt-enter": "search::SelectAllMatches",
"alt-c": "search::ToggleCaseSensitive",
"alt-w": "search::ToggleWholeWord",
"alt-find": "project_search::ToggleFilters",
"alt-ctrl-f": "project_search::ToggleFilters",
"alt-find": "project_search::ToggleFilters",
"ctrl-alt-shift-r": "search::ToggleRegex",
"ctrl-alt-shift-x": "search::ToggleRegex",
"alt-r": "search::ToggleRegex",
@@ -344,21 +342,21 @@
"alt-ctrl-f12": "editor::GoToTypeDefinitionSplit",
"alt-shift-f12": "editor::FindAllReferences",
"ctrl-m": "editor::MoveToEnclosingBracket",
"ctrl-|": "editor::MoveToEnclosingBracket",
"ctrl-{": "editor::Fold",
"ctrl-}": "editor::UnfoldLines",
"ctrl-shift-\\": "editor::MoveToEnclosingBracket",
"ctrl-shift-[": "editor::Fold",
"ctrl-shift-]": "editor::UnfoldLines",
"ctrl-k ctrl-l": "editor::ToggleFold",
"ctrl-k ctrl-[": "editor::FoldRecursive",
"ctrl-k ctrl-]": "editor::UnfoldRecursive",
"ctrl-k ctrl-1": ["editor::FoldAtLevel", 1],
"ctrl-k ctrl-2": ["editor::FoldAtLevel", 2],
"ctrl-k ctrl-3": ["editor::FoldAtLevel", 3],
"ctrl-k ctrl-4": ["editor::FoldAtLevel", 4],
"ctrl-k ctrl-5": ["editor::FoldAtLevel", 5],
"ctrl-k ctrl-6": ["editor::FoldAtLevel", 6],
"ctrl-k ctrl-7": ["editor::FoldAtLevel", 7],
"ctrl-k ctrl-8": ["editor::FoldAtLevel", 8],
"ctrl-k ctrl-9": ["editor::FoldAtLevel", 9],
"ctrl-k ctrl-1": ["editor::FoldAtLevel", { "level": 1 }],
"ctrl-k ctrl-2": ["editor::FoldAtLevel", { "level": 2 }],
"ctrl-k ctrl-3": ["editor::FoldAtLevel", { "level": 3 }],
"ctrl-k ctrl-4": ["editor::FoldAtLevel", { "level": 4 }],
"ctrl-k ctrl-5": ["editor::FoldAtLevel", { "level": 5 }],
"ctrl-k ctrl-6": ["editor::FoldAtLevel", { "level": 6 }],
"ctrl-k ctrl-7": ["editor::FoldAtLevel", { "level": 7 }],
"ctrl-k ctrl-8": ["editor::FoldAtLevel", { "level": 8 }],
"ctrl-k ctrl-9": ["editor::FoldAtLevel", { "level": 9 }],
"ctrl-k ctrl-0": "editor::FoldAll",
"ctrl-k ctrl-j": "editor::UnfoldAll",
"ctrl-space": "editor::ShowCompletions",
@@ -368,12 +366,7 @@
"ctrl-\\": "pane::SplitRight",
"ctrl-k v": "markdown::OpenPreviewToTheSide",
"ctrl-shift-v": "markdown::OpenPreview",
"ctrl-alt-shift-c": "editor::DisplayCursorNames",
"ctrl-alt-y": "git::ToggleStaged",
"alt-y": "git::StageAndNext",
"alt-shift-y": "git::UnstageAndNext",
"alt-.": "editor::GoToHunk",
"alt-,": "editor::GoToPrevHunk"
"ctrl-alt-shift-c": "editor::DisplayCursorNames"
}
},
{
@@ -439,14 +432,14 @@
"ctrl-alt-s": "workspace::SaveAll",
"ctrl-k m": "language_selector::Toggle",
"escape": "workspace::Unfollow",
"ctrl-k ctrl-left": "workspace::ActivatePaneLeft",
"ctrl-k ctrl-right": "workspace::ActivatePaneRight",
"ctrl-k ctrl-up": "workspace::ActivatePaneUp",
"ctrl-k ctrl-down": "workspace::ActivatePaneDown",
"ctrl-k shift-left": "workspace::SwapPaneLeft",
"ctrl-k shift-right": "workspace::SwapPaneRight",
"ctrl-k shift-up": "workspace::SwapPaneUp",
"ctrl-k shift-down": "workspace::SwapPaneDown",
"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"],
"ctrl-shift-x": "zed::Extensions",
"ctrl-shift-r": "task::Rerun",
"ctrl-alt-r": "task::Rerun",
@@ -460,8 +453,8 @@
{
"context": "ApplicationMenu",
"bindings": {
"left": "app_menu::ActivateMenuLeft",
"right": "app_menu::ActivateMenuRight"
"left": ["app_menu::NavigateApplicationMenuInDirection", "Left"],
"right": ["app_menu::NavigateApplicationMenuInDirection", "Right"]
}
},
// Bindings from Sublime Text
@@ -503,28 +496,17 @@
},
{
"context": "Editor && showing_completions",
"use_key_equivalents": true,
"bindings": {
"enter": "editor::ConfirmCompletion",
"tab": "editor::ComposeCompletion"
}
},
// Bindings for accepting edit predictions
//
// alt-l is provided as an alternative to tab/alt-tab. and will be displayed in the UI. This is
// because alt-tab may not be available, as it is often used for window switching.
{
"context": "Editor && edit_prediction",
"context": "Editor && inline_completion && !showing_completions",
"use_key_equivalents": true,
"bindings": {
"alt-tab": "editor::AcceptEditPrediction",
"alt-l": "editor::AcceptEditPrediction",
"tab": "editor::AcceptEditPrediction"
}
},
{
"context": "Editor && edit_prediction_conflict",
"bindings": {
"alt-tab": "editor::AcceptEditPrediction",
"alt-l": "editor::AcceptEditPrediction"
"tab": "editor::AcceptInlineCompletion"
}
},
{
@@ -548,7 +530,8 @@
{
"bindings": {
"ctrl-alt-shift-f": "workspace::FollowNextCollaborator",
"ctrl-alt-i": "zed::DebugElements"
"ctrl-alt-i": "zed::DebugElements",
"ctrl-:": "editor::ToggleInlayHints"
}
},
{
@@ -566,8 +549,7 @@
"ctrl-shift-e": "pane::RevealInProjectPanel",
"ctrl-f8": "editor::GoToHunk",
"ctrl-shift-f8": "editor::GoToPrevHunk",
"ctrl-enter": "assistant::InlineAssist",
"ctrl-:": "editor::ToggleInlayHints"
"ctrl-enter": "assistant::InlineAssist"
}
},
{
@@ -593,7 +575,6 @@
"save": "workspace::Save",
"ctrl->": "assistant::QuoteSelection",
"ctrl-<": "assistant::InsertIntoEditor",
"ctrl-alt-/": "assistant::ToggleModelSelector",
"shift-enter": "assistant::Split",
"ctrl-r": "assistant::CycleMessageRole",
"enter": "assistant::ConfirmCommand",
@@ -614,12 +595,14 @@
},
{
"context": "MessageEditor > Editor",
"use_key_equivalents": true,
"bindings": {
"enter": "assistant2::Chat"
}
},
{
"context": "ContextStrip",
"use_key_equivalents": true,
"bindings": {
"up": "assistant2::FocusUp",
"right": "assistant2::FocusRight",
@@ -657,8 +640,8 @@
"right": "outline_panel::ExpandSelectedEntry",
"alt-copy": "outline_panel::CopyPath",
"ctrl-alt-c": "outline_panel::CopyPath",
"alt-shift-copy": "workspace::CopyRelativePath",
"alt-ctrl-shift-c": "workspace::CopyRelativePath",
"alt-shift-copy": "outline_panel::CopyRelativePath",
"alt-ctrl-shift-c": "outline_panel::CopyRelativePath",
"alt-ctrl-r": "outline_panel::RevealInFileManager",
"space": "outline_panel::Open",
"shift-down": "menu::SelectNext",
@@ -686,8 +669,8 @@
"ctrl-v": "project_panel::Paste",
"alt-copy": "project_panel::CopyPath",
"ctrl-alt-c": "project_panel::CopyPath",
"alt-shift-copy": "workspace::CopyRelativePath",
"alt-ctrl-shift-c": "workspace::CopyRelativePath",
"alt-shift-copy": "project_panel::CopyRelativePath",
"alt-ctrl-shift-c": "project_panel::CopyRelativePath",
"enter": "project_panel::Rename",
"f2": "project_panel::Rename",
"backspace": ["project_panel::Trash", { "skip_prompt": false }],
@@ -697,8 +680,8 @@
"ctrl-delete": ["project_panel::Delete", { "skip_prompt": false }],
"alt-ctrl-r": "project_panel::RevealInFileManager",
"ctrl-shift-enter": "project_panel::OpenWithSystem",
"shift-find": "project_panel::NewSearchInDirectory",
"ctrl-shift-f": "project_panel::NewSearchInDirectory",
"shift-find": "project_panel::NewSearchInDirectory",
"shift-down": "menu::SelectNext",
"shift-up": "menu::SelectPrev",
"escape": "menu::Cancel"
@@ -710,45 +693,32 @@
"space": "project_panel::Open"
}
},
{
"context": "GitPanel && !CommitEditor",
"use_key_equivalents": true,
"bindings": {
"escape": "git_panel::Close"
}
},
{
"context": "GitPanel && ChangesList",
"use_key_equivalents": true,
"bindings": {
"up": "menu::SelectPrev",
"down": "menu::SelectNext",
"enter": "menu::Confirm",
"space": "git::ToggleStaged",
"ctrl-space": "git::StageAll",
"ctrl-shift-space": "git::UnstageAll",
"tab": "git_panel::FocusEditor",
"shift-tab": "git_panel::FocusEditor",
"escape": "git_panel::ToggleFocus",
"ctrl-enter": "git::Commit",
"alt-enter": "menu::SecondaryConfirm"
"ctrl-shift-space": "git::UnstageAll"
}
},
{
"context": "GitCommit > Editor",
"bindings": {
"enter": "editor::Newline",
"ctrl-enter": "git::Commit"
}
},
{
"context": "GitPanel > Editor",
"bindings": {
"escape": "git_panel::FocusChanges",
"tab": "git_panel::FocusChanges",
"shift-tab": "git_panel::FocusChanges",
"ctrl-enter": "git::Commit",
"alt-up": "git_panel::FocusChanges"
}
},
{
"context": "GitCommit > Editor",
"context": "GitPanel && CommitEditor > Editor",
"use_key_equivalents": true,
"bindings": {
"enter": "editor::Newline",
"ctrl-enter": "git::Commit"
"escape": "git_panel::FocusChanges",
"ctrl-enter": "git::CommitChanges",
"ctrl-shift-enter": "git::CommitAllChanges"
}
},
{
@@ -784,7 +754,13 @@
}
},
{
"context": "FileFinder || (FileFinder > Picker > Editor) || (FileFinder > Picker > menu)",
"context": "FileFinder",
"bindings": {
"ctrl": "file_finder::ToggleMenu"
}
},
{
"context": "FileFinder && !menu_open",
"bindings": {
"ctrl-shift-p": "file_finder::SelectPrev",
"ctrl-j": "pane::SplitDown",
@@ -793,6 +769,15 @@
"ctrl-l": "pane::SplitRight"
}
},
{
"context": "FileFinder && menu_open",
"bindings": {
"j": "pane::SplitDown",
"k": "pane::SplitUp",
"h": "pane::SplitLeft",
"l": "pane::SplitRight"
}
},
{
"context": "TabSwitcher",
"bindings": {
@@ -813,8 +798,6 @@
"shift-insert": "terminal::Paste",
"ctrl-shift-v": "terminal::Paste",
"ctrl-enter": "assistant::InlineAssist",
"alt-b": ["terminal::SendText", "\u001bb"],
"alt-f": ["terminal::SendText", "\u001bf"],
// Overrides for conflicting keybindings
"ctrl-w": ["terminal::SendKeystroke", "ctrl-w"],
"ctrl-shift-a": "editor::SelectAll",
@@ -829,7 +812,6 @@
"pagedown": ["terminal::SendKeystroke", "pagedown"],
"escape": ["terminal::SendKeystroke", "escape"],
"enter": ["terminal::SendKeystroke", "enter"],
"ctrl-b": ["terminal::SendKeystroke", "ctrl-b"],
"ctrl-c": ["terminal::SendKeystroke", "ctrl-c"],
"shift-pageup": "terminal::ScrollPageUp",
"shift-pagedown": "terminal::ScrollPageDown",
@@ -839,11 +821,5 @@
"shift-end": "terminal::ScrollToBottom",
"ctrl-shift-space": "terminal::ToggleViMode"
}
},
{
"context": "ZedPredictModal",
"bindings": {
"escape": "menu::Cancel"
}
}
]

View File

@@ -28,10 +28,10 @@
"cmd-shift-w": "workspace::CloseWindow",
"shift-escape": "workspace::ToggleZoom",
"cmd-o": "workspace::Open",
"cmd-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
"cmd-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
"cmd--": ["zed::DecreaseBufferFontSize", { "persist": false }],
"cmd-0": ["zed::ResetBufferFontSize", { "persist": false }],
"cmd-=": "zed::IncreaseBufferFontSize",
"cmd-+": "zed::IncreaseBufferFontSize",
"cmd--": "zed::DecreaseBufferFontSize",
"cmd-0": "zed::ResetBufferFontSize",
"cmd-,": "zed::OpenSettings",
"cmd-q": "zed::Quit",
"cmd-h": "zed::Hide",
@@ -39,8 +39,8 @@
"cmd-m": "zed::Minimize",
"fn-f": "zed::ToggleFullScreen",
"ctrl-cmd-f": "zed::ToggleFullScreen",
"ctrl-cmd-z": "edit_prediction::RateCompletions",
"ctrl-cmd-i": "edit_prediction::ToggleMenu"
"ctrl-shift-z": "zeta::RateCompletions",
"ctrl-shift-i": "inline_completion::ToggleMenu"
}
},
{
@@ -91,16 +91,14 @@
"ctrl-l": "editor::ScrollCursorCenter",
"alt-left": "editor::MoveToPreviousWordStart",
"alt-right": "editor::MoveToNextWordEnd",
"cmd-left": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
"ctrl-a": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": false, "stop_at_indent": true }],
"home": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
"cmd-right": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
"ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }],
"end": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
"cmd-up": "editor::MoveToStartOfExcerpt",
"cmd-down": "editor::MoveToEndOfExcerpt",
"cmd-home": "editor::MoveToBeginning", // Typed via `cmd-fn-left`
"cmd-end": "editor::MoveToEnd", // Typed via `cmd-fn-right`
"cmd-left": "editor::MoveToBeginningOfLine",
"ctrl-a": "editor::MoveToBeginningOfLine",
"home": "editor::MoveToBeginningOfLine",
"cmd-right": "editor::MoveToEndOfLine",
"ctrl-e": "editor::MoveToEndOfLine",
"end": "editor::MoveToEndOfLine",
"cmd-up": "editor::MoveToBeginning",
"cmd-down": "editor::MoveToEnd",
"shift-up": "editor::SelectUp",
"ctrl-shift-p": "editor::SelectUp",
"shift-down": "editor::SelectDown",
@@ -113,14 +111,14 @@
"alt-shift-right": "editor::SelectToNextWordEnd", // cursorWordRightSelect
"ctrl-shift-up": "editor::SelectToStartOfParagraph",
"ctrl-shift-down": "editor::SelectToEndOfParagraph",
"cmd-shift-up": "editor::SelectToStartOfExcerpt",
"cmd-shift-down": "editor::SelectToEndOfExcerpt",
"cmd-shift-up": "editor::SelectToBeginning",
"cmd-shift-down": "editor::SelectToEnd",
"cmd-a": "editor::SelectAll",
"cmd-l": "editor::SelectLine",
"cmd-shift-i": "editor::Format",
"cmd-shift-left": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
"ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
"cmd-shift-left": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
"ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
"cmd-shift-right": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
"ctrl-shift-e": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
@@ -128,17 +126,14 @@
"ctrl-shift-v": ["editor::MovePageUp", { "center_cursor": true }],
"ctrl-cmd-space": "editor::ShowCharacterPalette",
"cmd-;": "editor::ToggleLineNumbers",
"cmd-alt-z": "git::Restore",
"cmd-alt-y": "git::ToggleStaged",
"cmd-y": "git::StageAndNext",
"cmd-shift-y": "git::UnstageAndNext",
"cmd-alt-z": "editor::RevertSelectedHunks",
"cmd-'": "editor::ToggleSelectedDiffHunks",
"cmd-\"": "editor::ExpandAllDiffHunks",
"cmd-\"": "editor::ExpandAllHunkDiffs",
"cmd-alt-g b": "editor::ToggleGitBlame",
"cmd-i": "editor::ShowSignatureHelp",
"ctrl-f12": "editor::GoToDeclaration",
"alt-ctrl-f12": "editor::GoToDeclarationSplit",
"ctrl-cmd-e": "editor::ToggleEditPrediction"
"alt-enter": "editor::OpenSelectionsInMultibuffer"
}
},
{
@@ -151,29 +146,28 @@
"cmd-shift-enter": "editor::NewlineAbove",
"cmd-k z": "editor::ToggleSoftWrap",
"cmd-f": "buffer_search::Deploy",
"cmd-alt-f": "buffer_search::DeployReplace",
"cmd-alt-f": ["buffer_search::Deploy", { "replace_enabled": true }],
"cmd-alt-l": ["buffer_search::Deploy", { "selection_search_enabled": true }],
"cmd-e": ["buffer_search::Deploy", { "focus": false }],
"cmd->": "assistant::QuoteSelection",
"cmd-<": "assistant::InsertIntoEditor",
"cmd-alt-e": "editor::SelectEnclosingSymbol",
"alt-enter": "editor::OpenSelectionsInMultibuffer"
"cmd-alt-e": "editor::SelectEnclosingSymbol"
}
},
{
"context": "Editor && mode == full && edit_prediction",
"context": "Editor && mode == full && inline_completion",
"use_key_equivalents": true,
"bindings": {
"alt-tab": "editor::NextEditPrediction",
"alt-shift-tab": "editor::PreviousEditPrediction",
"ctrl-cmd-right": "editor::AcceptPartialEditPrediction"
"alt-tab": "editor::NextInlineCompletion",
"alt-shift-tab": "editor::PreviousInlineCompletion",
"ctrl-cmd-right": "editor::AcceptPartialInlineCompletion"
}
},
{
"context": "Editor && !edit_prediction",
"context": "Editor && !inline_completion",
"use_key_equivalents": true,
"bindings": {
"alt-tab": "editor::ShowEditPrediction"
"alt-tab": "editor::ShowInlineCompletion"
}
},
{
@@ -211,8 +205,7 @@
"cmd-alt-/": "assistant::ToggleModelSelector",
"cmd-k h": "assistant::DeployHistory",
"cmd-k l": "assistant::DeployPromptLibrary",
"cmd-t": "assistant::NewChat",
"cmd-n": "assistant::NewChat"
"cmd-n": "assistant::NewContext"
}
},
{
@@ -224,7 +217,6 @@
"cmd-s": "workspace::Save",
"cmd->": "assistant::QuoteSelection",
"cmd-<": "assistant::InsertIntoEditor",
"cmd-alt-/": "assistant::ToggleModelSelector",
"shift-enter": "assistant::Split",
"ctrl-r": "assistant::CycleMessageRole",
"enter": "assistant::ConfirmCommand",
@@ -289,8 +281,7 @@
"alt-enter": "search::SelectAllMatches",
"cmd-f": "search::FocusSearch",
"cmd-alt-f": "search::ToggleReplace",
"cmd-alt-l": "search::ToggleSelection",
"cmd-shift-o": "outline::Toggle"
"cmd-alt-l": "search::ToggleSelection"
}
},
{
@@ -358,7 +349,7 @@
"cmd-}": "pane::ActivateNextItem",
"ctrl-shift-pageup": "pane::SwapItemLeft",
"ctrl-shift-pagedown": "pane::SwapItemRight",
"cmd-w": ["pane::CloseActiveItem", { "close_pinned": false }],
"cmd-w": "pane::CloseActiveItem",
"alt-cmd-t": ["pane::CloseInactiveItems", { "close_pinned": false }],
"ctrl-alt-cmd-w": "workspace::CloseInactiveTabsAndPanes",
"cmd-k e": ["pane::CloseItemsToTheLeft", { "close_pinned": false }],
@@ -422,15 +413,15 @@
"cmd-k cmd-l": "editor::ToggleFold",
"cmd-k cmd-[": "editor::FoldRecursive",
"cmd-k cmd-]": "editor::UnfoldRecursive",
"cmd-k cmd-1": ["editor::FoldAtLevel", 1],
"cmd-k cmd-2": ["editor::FoldAtLevel", 2],
"cmd-k cmd-3": ["editor::FoldAtLevel", 3],
"cmd-k cmd-4": ["editor::FoldAtLevel", 4],
"cmd-k cmd-5": ["editor::FoldAtLevel", 5],
"cmd-k cmd-6": ["editor::FoldAtLevel", 6],
"cmd-k cmd-7": ["editor::FoldAtLevel", 7],
"cmd-k cmd-8": ["editor::FoldAtLevel", 8],
"cmd-k cmd-9": ["editor::FoldAtLevel", 9],
"cmd-k cmd-1": ["editor::FoldAtLevel", { "level": 1 }],
"cmd-k cmd-2": ["editor::FoldAtLevel", { "level": 2 }],
"cmd-k cmd-3": ["editor::FoldAtLevel", { "level": 3 }],
"cmd-k cmd-4": ["editor::FoldAtLevel", { "level": 4 }],
"cmd-k cmd-5": ["editor::FoldAtLevel", { "level": 5 }],
"cmd-k cmd-6": ["editor::FoldAtLevel", { "level": 6 }],
"cmd-k cmd-7": ["editor::FoldAtLevel", { "level": 7 }],
"cmd-k cmd-8": ["editor::FoldAtLevel", { "level": 8 }],
"cmd-k cmd-9": ["editor::FoldAtLevel", { "level": 9 }],
"cmd-k cmd-0": "editor::FoldAll",
"cmd-k cmd-j": "editor::UnfoldAll",
// Using `ctrl-space` in Zed requires disabling the macOS global shortcut.
@@ -468,7 +459,7 @@
"ctrl-9": ["pane::ActivateItem", 8],
"ctrl-0": "pane::ActivateLastItem",
"ctrl--": "pane::GoBack",
"ctrl-_": "pane::GoForward",
"ctrl-shift--": "pane::GoForward",
"cmd-shift-f": "pane::DeploySearch"
}
},
@@ -518,14 +509,14 @@
"cmd-alt-s": "workspace::SaveAll",
"cmd-k m": "language_selector::Toggle",
"escape": "workspace::Unfollow",
"cmd-k cmd-left": "workspace::ActivatePaneLeft",
"cmd-k cmd-right": "workspace::ActivatePaneRight",
"cmd-k cmd-up": "workspace::ActivatePaneUp",
"cmd-k cmd-down": "workspace::ActivatePaneDown",
"cmd-k shift-left": "workspace::SwapPaneLeft",
"cmd-k shift-right": "workspace::SwapPaneRight",
"cmd-k shift-up": "workspace::SwapPaneUp",
"cmd-k shift-down": "workspace::SwapPaneDown",
"cmd-k cmd-left": ["workspace::ActivatePaneInDirection", "Left"],
"cmd-k cmd-right": ["workspace::ActivatePaneInDirection", "Right"],
"cmd-k cmd-up": ["workspace::ActivatePaneInDirection", "Up"],
"cmd-k cmd-down": ["workspace::ActivatePaneInDirection", "Down"],
"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"],
"cmd-shift-x": "zed::Extensions"
}
},
@@ -589,17 +580,10 @@
}
},
{
"context": "Editor && edit_prediction",
"bindings": {
"alt-tab": "editor::AcceptEditPrediction",
"tab": "editor::AcceptEditPrediction"
}
},
{
"context": "Editor && edit_prediction_conflict",
"context": "Editor && inline_completion && !showing_completions",
"use_key_equivalents": true,
"bindings": {
"alt-tab": "editor::AcceptEditPrediction"
"tab": "editor::AcceptInlineCompletion"
}
},
{
@@ -628,7 +612,8 @@
"ctrl-alt-cmd-f": "workspace::FollowNextCollaborator",
// TODO: Move this to a dock open action
"cmd-shift-c": "collab_panel::ToggleFocus",
"cmd-alt-i": "zed::DebugElements"
"cmd-alt-i": "zed::DebugElements",
"ctrl-:": "editor::ToggleInlayHints"
}
},
{
@@ -641,8 +626,7 @@
"cmd-shift-e": "pane::RevealInProjectPanel",
"cmd-f8": "editor::GoToHunk",
"cmd-shift-f8": "editor::GoToPrevHunk",
"ctrl-enter": "assistant::InlineAssist",
"ctrl-:": "editor::ToggleInlayHints"
"ctrl-enter": "assistant::InlineAssist"
}
},
{
@@ -678,8 +662,8 @@
"escape": "menu::Cancel",
"left": "outline_panel::CollapseSelectedEntry",
"right": "outline_panel::ExpandSelectedEntry",
"cmd-alt-c": "workspace::CopyPath",
"alt-cmd-shift-c": "workspace::CopyRelativePath",
"cmd-alt-c": "outline_panel::CopyPath",
"alt-cmd-shift-c": "outline_panel::CopyRelativePath",
"alt-cmd-r": "outline_panel::RevealInFileManager",
"space": "outline_panel::Open",
"shift-down": "menu::SelectNext",
@@ -700,8 +684,8 @@
"cmd-x": "project_panel::Cut",
"cmd-c": "project_panel::Copy",
"cmd-v": "project_panel::Paste",
"cmd-alt-c": "workspace::CopyPath",
"alt-cmd-shift-c": "workspace::CopyRelativePath",
"cmd-alt-c": "project_panel::CopyPath",
"alt-cmd-shift-c": "project_panel::CopyRelativePath",
"enter": "project_panel::Rename",
"f2": "project_panel::Rename",
"backspace": ["project_panel::Trash", { "skip_prompt": false }],
@@ -724,6 +708,13 @@
"space": "project_panel::Open"
}
},
{
"context": "GitPanel && !CommitEditor",
"use_key_equivalents": true,
"bindings": {
"escape": "git_panel::Close"
}
},
{
"context": "GitPanel && ChangesList",
"use_key_equivalents": true,
@@ -736,29 +727,17 @@
"space": "git::ToggleStaged",
"cmd-shift-space": "git::StageAll",
"ctrl-shift-space": "git::UnstageAll",
"alt-down": "git_panel::FocusEditor",
"tab": "git_panel::FocusEditor",
"shift-tab": "git_panel::FocusEditor",
"escape": "git_panel::ToggleFocus"
"alt-down": "git_panel::FocusEditor"
}
},
{
"context": "GitPanel > Editor",
"context": "GitPanel && CommitEditor > Editor",
"use_key_equivalents": true,
"bindings": {
"enter": "editor::Newline",
"cmd-enter": "git::Commit",
"tab": "git_panel::FocusChanges",
"shift-tab": "git_panel::FocusChanges",
"alt-up": "git_panel::FocusChanges"
}
},
{
"context": "GitCommit > Editor",
"use_key_equivalents": true,
"bindings": {
"enter": "editor::Newline",
"cmd-enter": "git::Commit"
"alt-up": "git_panel::FocusChanges",
"escape": "git_panel::FocusChanges",
"cmd-enter": "git::CommitChanges",
"cmd-alt-enter": "git::CommitAllChanges"
}
},
{
@@ -800,7 +779,14 @@
}
},
{
"context": "FileFinder || (FileFinder > Picker > Editor) || (FileFinder > Picker > menu)",
"context": "FileFinder",
"use_key_equivalents": true,
"bindings": {
"cmd": "file_finder::ToggleMenu"
}
},
{
"context": "FileFinder && !menu_open",
"use_key_equivalents": true,
"bindings": {
"cmd-shift-p": "file_finder::SelectPrev",
@@ -810,6 +796,16 @@
"cmd-l": "pane::SplitRight"
}
},
{
"context": "FileFinder && menu_open",
"use_key_equivalents": true,
"bindings": {
"j": "pane::SplitDown",
"k": "pane::SplitUp",
"h": "pane::SplitLeft",
"l": "pane::SplitRight"
}
},
{
"context": "TabSwitcher",
"use_key_equivalents": true,
@@ -831,7 +827,6 @@
"cmd-k": "terminal::Clear",
"cmd-n": "workspace::NewTerminal",
"ctrl-enter": "assistant::InlineAssist",
"ctrl-_": null, // emacs undo
// Some nice conveniences
"cmd-backspace": ["terminal::SendText", "\u0015"],
"cmd-right": ["terminal::SendText", "\u0005"],
@@ -839,8 +834,6 @@
// Terminal.app compatibility
"alt-left": ["terminal::SendText", "\u001bb"],
"alt-right": ["terminal::SendText", "\u001bf"],
"alt-b": ["terminal::SendText", "\u001bb"],
"alt-f": ["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"],
@@ -888,7 +881,7 @@
}
},
{
"context": "ZedPredictModal",
"context": "ZedPredictTos",
"use_key_equivalents": true,
"bindings": {
"escape": "menu::Cancel"

View File

@@ -28,7 +28,6 @@
"ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": false }], // move-beginning-of-line
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
"alt-m": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": false, "stop_at_indent": true }], // back-to-indentation
"alt-f": "editor::MoveToNextSubwordEnd", // forward-word
"alt-b": "editor::MoveToPreviousSubwordStart", // backward-word
"alt-u": "editor::ConvertToUpperCase", // upcase-word
@@ -49,8 +48,6 @@
"ctrl-_": "editor::Undo", // undo
"ctrl-/": "editor::Undo", // undo
"ctrl-x u": "editor::Undo", // undo
"alt-{": "editor::MoveToStartOfParagraph", // backward-paragraph
"alt-}": "editor::MoveToEndOfParagraph", // forward-paragraph
"ctrl-v": "editor::MovePageDown", // scroll-up
"alt-v": "editor::MovePageUp", // scroll-down
"ctrl-x [": "editor::MoveToBeginning", // beginning-of-buffer

View File

@@ -2,15 +2,15 @@
{
"bindings": {
"ctrl-alt-s": "zed::OpenSettings",
"ctrl-{": "pane::ActivatePrevItem",
"ctrl-}": "pane::ActivateNextItem"
"ctrl-shift-[": "pane::ActivatePrevItem",
"ctrl-shift-]": "pane::ActivateNextItem"
}
},
{
"context": "Editor",
"bindings": {
"ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
"ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
"ctrl->": "zed::IncreaseBufferFontSize",
"ctrl-<": "zed::DecreaseBufferFontSize",
"ctrl-shift-j": "editor::JoinLines",
"ctrl-d": "editor::DuplicateSelection",
"ctrl-y": "editor::DeleteLine",
@@ -44,7 +44,7 @@
"shift-f2": "editor::GoToPrevDiagnostic",
"ctrl-alt-shift-down": "editor::GoToHunk",
"ctrl-alt-shift-up": "editor::GoToPrevHunk",
"ctrl-alt-z": "git::Restore",
"ctrl-alt-z": "editor::RevertSelectedHunks",
"ctrl-home": "editor::MoveToBeginning",
"ctrl-end": "editor::MoveToEnd",
"ctrl-shift-home": "editor::SelectToBeginning",

View File

@@ -1,8 +1,8 @@
[
{
"bindings": {
"ctrl-{": "pane::ActivatePrevItem",
"ctrl-}": "pane::ActivateNextItem",
"ctrl-shift-[": "pane::ActivatePrevItem",
"ctrl-shift-]": "pane::ActivateNextItem",
"ctrl-pageup": "pane::ActivatePrevItem",
"ctrl-pagedown": "pane::ActivateNextItem",
"ctrl-1": ["workspace::ActivatePane", 0],
@@ -14,15 +14,15 @@
"ctrl-7": ["workspace::ActivatePane", 6],
"ctrl-8": ["workspace::ActivatePane", 7],
"ctrl-9": ["workspace::ActivatePane", 8],
"ctrl-!": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
"ctrl-@": ["workspace::MoveItemToPane", { "destination": 1 }],
"ctrl-#": ["workspace::MoveItemToPane", { "destination": 2 }],
"ctrl-$": ["workspace::MoveItemToPane", { "destination": 3 }],
"ctrl-%": ["workspace::MoveItemToPane", { "destination": 4 }],
"ctrl-^": ["workspace::MoveItemToPane", { "destination": 5 }],
"ctrl-&": ["workspace::MoveItemToPane", { "destination": 6 }],
"ctrl-*": ["workspace::MoveItemToPane", { "destination": 7 }],
"ctrl-(": ["workspace::MoveItemToPane", { "destination": 8 }]
"ctrl-shift-1": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
"ctrl-shift-2": ["workspace::MoveItemToPane", { "destination": 1 }],
"ctrl-shift-3": ["workspace::MoveItemToPane", { "destination": 2 }],
"ctrl-shift-4": ["workspace::MoveItemToPane", { "destination": 3 }],
"ctrl-shift-5": ["workspace::MoveItemToPane", { "destination": 4 }],
"ctrl-shift-6": ["workspace::MoveItemToPane", { "destination": 5 }],
"ctrl-shift-7": ["workspace::MoveItemToPane", { "destination": 6 }],
"ctrl-shift-8": ["workspace::MoveItemToPane", { "destination": 7 }],
"ctrl-shift-9": ["workspace::MoveItemToPane", { "destination": 8 }]
}
},
{

View File

@@ -28,7 +28,6 @@
"ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": false }], // move-beginning-of-line
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
"alt-m": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": false, "stop_at_indent": true }], // back-to-indentation
"alt-f": "editor::MoveToNextSubwordEnd", // forward-word
"alt-b": "editor::MoveToPreviousSubwordStart", // backward-word
"alt-u": "editor::ConvertToUpperCase", // upcase-word
@@ -49,8 +48,6 @@
"ctrl-_": "editor::Undo", // undo
"ctrl-/": "editor::Undo", // undo
"ctrl-x u": "editor::Undo", // undo
"alt-{": "editor::MoveToStartOfParagraph", // backward-paragraph
"alt-}": "editor::MoveToEndOfParagraph", // forward-paragraph
"ctrl-v": "editor::MovePageDown", // scroll-up
"alt-v": "editor::MovePageUp", // scroll-down
"ctrl-x [": "editor::MoveToBeginning", // beginning-of-buffer

View File

@@ -1,15 +1,15 @@
[
{
"bindings": {
"cmd-{": "pane::ActivatePrevItem",
"cmd-}": "pane::ActivateNextItem"
"cmd-shift-[": "pane::ActivatePrevItem",
"cmd-shift-]": "pane::ActivateNextItem"
}
},
{
"context": "Editor",
"bindings": {
"ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
"ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
"ctrl->": "zed::IncreaseBufferFontSize",
"ctrl-<": "zed::DecreaseBufferFontSize",
"ctrl-shift-j": "editor::JoinLines",
"cmd-d": "editor::DuplicateSelection",
"cmd-backspace": "editor::DeleteLine",

View File

@@ -1,8 +1,8 @@
[
{
"bindings": {
"cmd-{": "pane::ActivatePrevItem",
"cmd-}": "pane::ActivateNextItem",
"cmd-shift-[": "pane::ActivatePrevItem",
"cmd-shift-]": "pane::ActivateNextItem",
"ctrl-pageup": "pane::ActivatePrevItem",
"ctrl-pagedown": "pane::ActivateNextItem",
"ctrl-1": ["workspace::ActivatePane", 0],
@@ -14,15 +14,15 @@
"ctrl-7": ["workspace::ActivatePane", 6],
"ctrl-8": ["workspace::ActivatePane", 7],
"ctrl-9": ["workspace::ActivatePane", 8],
"ctrl-!": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
"ctrl-@": ["workspace::MoveItemToPane", { "destination": 1 }],
"ctrl-#": ["workspace::MoveItemToPane", { "destination": 2 }],
"ctrl-$": ["workspace::MoveItemToPane", { "destination": 3 }],
"ctrl-%": ["workspace::MoveItemToPane", { "destination": 4 }],
"ctrl-^": ["workspace::MoveItemToPane", { "destination": 5 }],
"ctrl-&": ["workspace::MoveItemToPane", { "destination": 6 }],
"ctrl-*": ["workspace::MoveItemToPane", { "destination": 7 }],
"ctrl-(": ["workspace::MoveItemToPane", { "destination": 8 }]
"ctrl-shift-1": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
"ctrl-shift-2": ["workspace::MoveItemToPane", { "destination": 1 }],
"ctrl-shift-3": ["workspace::MoveItemToPane", { "destination": 2 }],
"ctrl-shift-4": ["workspace::MoveItemToPane", { "destination": 3 }],
"ctrl-shift-5": ["workspace::MoveItemToPane", { "destination": 4 }],
"ctrl-shift-6": ["workspace::MoveItemToPane", { "destination": 5 }],
"ctrl-shift-7": ["workspace::MoveItemToPane", { "destination": 6 }],
"ctrl-shift-8": ["workspace::MoveItemToPane", { "destination": 7 }],
"ctrl-shift-9": ["workspace::MoveItemToPane", { "destination": 8 }]
}
},
{

View File

@@ -13,7 +13,7 @@
"cmd-b": "editor::GoToDefinition",
"cmd-j": "editor::ScrollCursorCenter",
"cmd-enter": "editor::NewlineBelow",
"cmd-alt-enter": "editor::NewlineAbove",
"cmd-alt-enter": "editor::NewLineAbove",
"cmd-shift-l": "editor::SelectLine",
"cmd-shift-t": "outline::Toggle",
"alt-backspace": "editor::DeleteToPreviousWordStart",
@@ -70,7 +70,7 @@
"bindings": {
"cmd-backspace": ["project_panel::Trash", { "skip_prompt": true }],
"cmd-d": "project_panel::Duplicate",
"cmd-n": "project_panel::NewDirectory",
"cmd-n": "project_panel::NewFolder",
"return": "project_panel::Rename",
"cmd-c": "project_panel::Copy",
"cmd-v": "project_panel::Paste",

View File

@@ -2,8 +2,8 @@
{
"context": "VimControl && !menu",
"bindings": {
"i": ["vim::PushObject", { "around": false }],
"a": ["vim::PushObject", { "around": true }],
"i": ["vim::PushOperator", { "Object": { "around": false } }],
"a": ["vim::PushOperator", { "Object": { "around": true } }],
"left": "vim::Left",
"h": "vim::Left",
"backspace": "vim::Backspace",
@@ -37,9 +37,9 @@
"[ [": "vim::PreviousSectionStart",
"[ ]": "vim::PreviousSectionEnd",
"] m": "vim::NextMethodStart",
"] shift-m": "vim::NextMethodEnd",
"] M": "vim::NextMethodEnd",
"[ m": "vim::PreviousMethodStart",
"[ shift-m": "vim::PreviousMethodEnd",
"[ M": "vim::PreviousMethodEnd",
"[ *": "vim::PreviousComment",
"[ /": "vim::PreviousComment",
"] *": "vim::NextComment",
@@ -54,10 +54,10 @@
// "b": "vim::PreviousSubwordStart",
// "e": "vim::NextSubwordEnd",
// "g e": "vim::PreviousSubwordEnd",
"shift-w": ["vim::NextWordStart", { "ignore_punctuation": true }],
"shift-e": ["vim::NextWordEnd", { "ignore_punctuation": true }],
"shift-b": ["vim::PreviousWordStart", { "ignore_punctuation": true }],
"g shift-e": ["vim::PreviousWordEnd", { "ignore_punctuation": true }],
"shift-w": ["vim::NextWordStart", { "ignorePunctuation": true }],
"shift-e": ["vim::NextWordEnd", { "ignorePunctuation": true }],
"shift-b": ["vim::PreviousWordStart", { "ignorePunctuation": true }],
"g shift-e": ["vim::PreviousWordEnd", { "ignorePunctuation": true }],
"/": "vim::Search",
"g /": "pane::DeploySearch",
"?": ["vim::Search", { "backwards": true }],
@@ -70,20 +70,20 @@
"[ {": ["vim::UnmatchedBackward", { "char": "{" }],
"] )": ["vim::UnmatchedForward", { "char": ")" }],
"[ (": ["vim::UnmatchedBackward", { "char": "(" }],
"f": ["vim::PushFindForward", { "before": false }],
"t": ["vim::PushFindForward", { "before": true }],
"shift-f": ["vim::PushFindBackward", { "after": false }],
"shift-t": ["vim::PushFindBackward", { "after": true }],
"m": "vim::PushMark",
"'": ["vim::PushJump", { "line": true }],
"`": ["vim::PushJump", { "line": false }],
"f": ["vim::PushOperator", { "FindForward": { "before": false } }],
"t": ["vim::PushOperator", { "FindForward": { "before": true } }],
"shift-f": ["vim::PushOperator", { "FindBackward": { "after": false } }],
"shift-t": ["vim::PushOperator", { "FindBackward": { "after": true } }],
"m": ["vim::PushOperator", "Mark"],
"'": ["vim::PushOperator", { "Jump": { "line": true } }],
"`": ["vim::PushOperator", { "Jump": { "line": false } }],
";": "vim::RepeatFind",
",": "vim::RepeatFindReversed",
"ctrl-o": "pane::GoBack",
"ctrl-i": "pane::GoForward",
"ctrl-]": "editor::GoToDefinition",
"escape": "vim::SwitchToNormalMode",
"ctrl-[": "vim::SwitchToNormalMode",
"escape": ["vim::SwitchMode", "Normal"],
"ctrl-[": ["vim::SwitchMode", "Normal"],
"v": "vim::ToggleVisual",
"shift-v": "vim::ToggleVisualLine",
"ctrl-g": "vim::ShowLocation",
@@ -102,7 +102,6 @@
"ctrl-e": "vim::LineDown",
"ctrl-y": "vim::LineUp",
// "g" commands
"g r": "vim::PushReplaceWithRegister",
"g g": "vim::StartOfDocument",
"g h": "editor::Hover",
"g t": "pane::ActivateNextItem",
@@ -125,17 +124,17 @@
"g .": "editor::ToggleCodeActions", // zed specific
"g shift-a": "editor::FindAllReferences", // zed specific
"g space": "editor::OpenExcerpts", // zed specific
"g *": ["vim::MoveToNext", { "partial_word": true }],
"g #": ["vim::MoveToPrev", { "partial_word": true }],
"g j": ["vim::Down", { "display_lines": true }],
"g down": ["vim::Down", { "display_lines": true }],
"g k": ["vim::Up", { "display_lines": true }],
"g up": ["vim::Up", { "display_lines": true }],
"g $": ["vim::EndOfLine", { "display_lines": true }],
"g end": ["vim::EndOfLine", { "display_lines": true }],
"g 0": ["vim::StartOfLine", { "display_lines": true }],
"g home": ["vim::StartOfLine", { "display_lines": true }],
"g ^": ["vim::FirstNonWhitespace", { "display_lines": true }],
"g *": ["vim::MoveToNext", { "partialWord": true }],
"g #": ["vim::MoveToPrev", { "partialWord": true }],
"g j": ["vim::Down", { "displayLines": true }],
"g down": ["vim::Down", { "displayLines": true }],
"g k": ["vim::Up", { "displayLines": true }],
"g up": ["vim::Up", { "displayLines": true }],
"g $": ["vim::EndOfLine", { "displayLines": true }],
"g end": ["vim::EndOfLine", { "displayLines": true }],
"g 0": ["vim::StartOfLine", { "displayLines": true }],
"g home": ["vim::StartOfLine", { "displayLines": true }],
"g ^": ["vim::FirstNonWhitespace", { "displayLines": true }],
"g v": "vim::RestoreVisualSelection",
"g ]": "editor::GoToDiagnostic",
"g [": "editor::GoToPrevDiagnostic",
@@ -147,7 +146,7 @@
"shift-l": "vim::WindowBottom",
"q": "vim::ToggleRecord",
"shift-q": "vim::ReplayLastRecording",
"@": "vim::PushReplayRegister",
"@": ["vim::PushOperator", "ReplayRegister"],
// z commands
"z enter": ["workspace::SendKeystrokes", "z t ^"],
"z -": ["workspace::SendKeystrokes", "z b ^"],
@@ -166,8 +165,8 @@
"z f": "editor::FoldSelectedRanges",
"z shift-m": "editor::FoldAll",
"z shift-r": "editor::UnfoldAll",
"shift-z shift-q": ["pane::CloseActiveItem", { "save_intent": "skip" }],
"shift-z shift-z": ["pane::CloseActiveItem", { "save_intent": "save_all" }],
"shift-z shift-q": ["pane::CloseActiveItem", { "saveIntent": "skip" }],
"shift-z shift-z": ["pane::CloseActiveItem", { "saveIntent": "saveAll" }],
// Count support
"1": ["vim::Number", 1],
"2": ["vim::Number", 2],
@@ -194,13 +193,13 @@
"escape": "editor::Cancel",
":": "command_palette::Toggle",
".": "vim::Repeat",
"c": "vim::PushChange",
"c": ["vim::PushOperator", "Change"],
"shift-c": "vim::ChangeToEndOfLine",
"d": "vim::PushDelete",
"d": ["vim::PushOperator", "Delete"],
"shift-d": "vim::DeleteToEndOfLine",
"shift-j": "vim::JoinLines",
"g shift-j": "vim::JoinLinesNoWhitespace",
"y": "vim::PushYank",
"y": ["vim::PushOperator", "Yank"],
"shift-y": "vim::YankLine",
"i": "vim::InsertBefore",
"shift-i": "vim::InsertFirstNonWhitespace",
@@ -217,19 +216,19 @@
"shift-p": ["vim::Paste", { "before": true }],
"u": "vim::Undo",
"ctrl-r": "vim::Redo",
"r": "vim::PushReplace",
"r": ["vim::PushOperator", "Replace"],
"s": "vim::Substitute",
"shift-s": "vim::SubstituteLine",
">": "vim::PushIndent",
"<": "vim::PushOutdent",
"=": "vim::PushAutoIndent",
"!": "vim::PushShellCommand",
"g u": "vim::PushLowercase",
"g shift-u": "vim::PushUppercase",
"g ~": "vim::PushOppositeCase",
"\"": "vim::PushRegister",
"g w": "vim::PushRewrap",
"g q": "vim::PushRewrap",
">": ["vim::PushOperator", "Indent"],
"<": ["vim::PushOperator", "Outdent"],
"=": ["vim::PushOperator", "AutoIndent"],
"!": ["vim::PushOperator", "ShellCommand"],
"g u": ["vim::PushOperator", "Lowercase"],
"g shift-u": ["vim::PushOperator", "Uppercase"],
"g ~": ["vim::PushOperator", "OppositeCase"],
"\"": ["vim::PushOperator", "Register"],
"g w": ["vim::PushOperator", "Rewrap"],
"g q": ["vim::PushOperator", "Rewrap"],
"ctrl-pagedown": "pane::ActivateNextItem",
"ctrl-pageup": "pane::ActivatePrevItem",
"insert": "vim::InsertBefore",
@@ -240,7 +239,7 @@
"[ d": "editor::GoToPrevDiagnostic",
"] c": "editor::GoToHunk",
"[ c": "editor::GoToPrevHunk",
"g c": "vim::PushToggleComments"
"g c": ["vim::PushOperator", "ToggleComments"]
}
},
{
@@ -265,14 +264,14 @@
"y": "vim::VisualYank",
"shift-y": "vim::VisualYankLine",
"p": "vim::Paste",
"shift-p": ["vim::Paste", { "preserve_clipboard": true }],
"shift-p": ["vim::Paste", { "preserveClipboard": true }],
"c": "vim::Substitute",
"s": "vim::Substitute",
"shift-r": "vim::SubstituteLine",
"shift-s": "vim::SubstituteLine",
"~": "vim::ChangeCase",
"*": ["vim::MoveToNext", { "partial_word": true }],
"#": ["vim::MoveToPrev", { "partial_word": true }],
"*": ["vim::MoveToNext", { "partialWord": true }],
"#": ["vim::MoveToPrev", { "partialWord": true }],
"ctrl-a": "vim::Increment",
"ctrl-x": "vim::Decrement",
"g ctrl-a": ["vim::Increment", { "step": true }],
@@ -283,20 +282,19 @@
"g shift-a": "vim::VisualInsertEndOfLine",
"shift-j": "vim::JoinLines",
"g shift-j": "vim::JoinLinesNoWhitespace",
"r": "vim::PushReplace",
"ctrl-c": "vim::SwitchToNormalMode",
"ctrl-[": "vim::SwitchToNormalMode",
"escape": "vim::SwitchToNormalMode",
"r": ["vim::PushOperator", "Replace"],
"ctrl-c": ["vim::SwitchMode", "Normal"],
"ctrl-[": ["vim::SwitchMode", "Normal"],
"escape": ["vim::SwitchMode", "Normal"],
">": "vim::Indent",
"<": "vim::Outdent",
"=": "vim::AutoIndent",
"!": "vim::ShellCommand",
"i": ["vim::PushObject", { "around": false }],
"a": ["vim::PushObject", { "around": true }],
"g r": ["vim::Paste", { "preserve_clipboard": true }],
"i": ["vim::PushOperator", { "Object": { "around": false } }],
"a": ["vim::PushOperator", { "Object": { "around": true } }],
"g c": "vim::ToggleComments",
"g q": "vim::Rewrap",
"\"": "vim::PushRegister",
"\"": ["vim::PushOperator", "Register"],
// tree-sitter related commands
"[ x": "editor::SelectLargerSyntaxNode",
"] x": "editor::SelectSmallerSyntaxNode"
@@ -311,19 +309,19 @@
"ctrl-x": null,
"ctrl-x ctrl-o": "editor::ShowCompletions",
"ctrl-x ctrl-a": "assistant::InlineAssist", // zed specific
"ctrl-x ctrl-c": "editor::ShowEditPrediction", // zed specific
"ctrl-x ctrl-c": "editor::ShowInlineCompletion", // 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-k": ["vim::PushDigraph", {}],
"ctrl-v": ["vim::PushLiteral", {}],
"ctrl-k": ["vim::PushOperator", { "Digraph": {} }],
"ctrl-v": ["vim::PushOperator", { "Literal": {} }],
"ctrl-shift-v": "editor::Paste", // note: this is *very* similar to ctrl-v in vim, but ctrl-shift-v on linux is the typical shortcut for paste when ctrl-v is already in use.
"ctrl-q": ["vim::PushLiteral", {}],
"ctrl-shift-q": ["vim::PushLiteral", {}],
"ctrl-r": "vim::PushRegister",
"ctrl-q": ["vim::PushOperator", { "Literal": {} }],
"ctrl-shift-q": ["vim::PushOperator", { "Literal": {} }],
"ctrl-r": ["vim::PushOperator", "Register"],
"insert": "vim::ToggleReplace",
"ctrl-o": "vim::TemporaryNormal"
}
@@ -358,11 +356,11 @@
"ctrl-c": "vim::NormalBefore",
"ctrl-[": "vim::NormalBefore",
"escape": "vim::NormalBefore",
"ctrl-k": ["vim::PushDigraph", {}],
"ctrl-v": ["vim::PushLiteral", {}],
"ctrl-k": ["vim::PushOperator", { "Digraph": {} }],
"ctrl-v": ["vim::PushOperator", { "Literal": {} }],
"ctrl-shift-v": "editor::Paste", // note: this is *very* similar to ctrl-v in vim, but ctrl-shift-v on linux is the typical shortcut for paste when ctrl-v is already in use.
"ctrl-q": ["vim::PushLiteral", {}],
"ctrl-shift-q": ["vim::PushLiteral", {}],
"ctrl-q": ["vim::PushOperator", { "Literal": {} }],
"ctrl-shift-q": ["vim::PushOperator", { "Literal": {} }],
"backspace": "vim::UndoReplace",
"tab": "vim::Tab",
"enter": "vim::Enter",
@@ -377,15 +375,9 @@
"ctrl-c": "vim::ClearOperators",
"ctrl-[": "vim::ClearOperators",
"escape": "vim::ClearOperators",
"ctrl-k": ["vim::PushDigraph", {}],
"ctrl-v": ["vim::PushLiteral", {}],
"ctrl-q": ["vim::PushLiteral", {}]
}
},
{
"context": "Editor && vim_mode == waiting && (vim_operator == ys || vim_operator == cs)",
"bindings": {
"escape": "vim::SwitchToNormalMode"
"ctrl-k": ["vim::PushOperator", { "Digraph": {} }],
"ctrl-v": ["vim::PushOperator", { "Literal": {} }],
"ctrl-q": ["vim::PushOperator", { "Literal": {} }]
}
},
{
@@ -401,10 +393,10 @@
"context": "vim_operator == a || vim_operator == i || vim_operator == cs",
"bindings": {
"w": "vim::Word",
"shift-w": ["vim::Word", { "ignore_punctuation": true }],
"shift-w": ["vim::Word", { "ignorePunctuation": true }],
// Subword TextObject
// "w": "vim::Subword",
// "shift-w": ["vim::Subword", { "ignore_punctuation": true }],
// "shift-w": ["vim::Subword", { "ignorePunctuation": true }],
"t": "vim::Tag",
"s": "vim::Sentence",
"p": "vim::Paragraph",
@@ -427,28 +419,26 @@
">": "vim::AngleBrackets",
"a": "vim::Argument",
"i": "vim::IndentObj",
"shift-i": ["vim::IndentObj", { "include_below": true }],
"shift-i": ["vim::IndentObj", { "includeBelow": true }],
"f": "vim::Method",
"c": "vim::Class",
"e": "vim::EntireFile"
"c": "vim::Class"
}
},
{
"context": "vim_operator == c",
"bindings": {
"c": "vim::CurrentLine",
"x": "vim::Exchange",
"d": "editor::Rename", // zed specific
"s": ["vim::PushChangeSurrounds", {}]
"s": ["vim::PushOperator", { "ChangeSurrounds": {} }]
}
},
{
"context": "vim_operator == d",
"bindings": {
"d": "vim::CurrentLine",
"s": "vim::PushDeleteSurrounds",
"s": ["vim::PushOperator", "DeleteSurrounds"],
"o": "editor::ToggleSelectedDiffHunks", // "d o"
"p": "git::Restore" // "d p"
"p": "editor::RevertSelectedHunks" // "d p"
}
},
{
@@ -485,7 +475,7 @@
"context": "vim_operator == y",
"bindings": {
"y": "vim::CurrentLine",
"s": ["vim::PushAddSurrounds", {}]
"s": ["vim::PushOperator", { "AddSurrounds": {} }]
}
},
{
@@ -524,19 +514,6 @@
"c": "vim::CurrentLine"
}
},
{
"context": "vim_operator == gr",
"bindings": {
"r": "vim::CurrentLine"
}
},
{
"context": "vim_operator == cx",
"bindings": {
"x": "vim::CurrentLine",
"c": "vim::ClearExchange"
}
},
{
"context": "vim_mode == literal",
"bindings": {
@@ -588,34 +565,34 @@
}
},
{
"context": "GitPanel || ProjectPanel || CollabPanel || OutlinePanel || ChatPanel || VimControl || EmptyPane || SharedScreen || MarkdownPreview || KeyContextView",
"context": "ProjectPanel || CollabPanel || OutlinePanel || ChatPanel || VimControl || EmptyPane || SharedScreen || MarkdownPreview || KeyContextView",
"bindings": {
// window related commands (ctrl-w X)
"ctrl-w": null,
"ctrl-w left": "workspace::ActivatePaneLeft",
"ctrl-w right": "workspace::ActivatePaneRight",
"ctrl-w up": "workspace::ActivatePaneUp",
"ctrl-w down": "workspace::ActivatePaneDown",
"ctrl-w ctrl-h": "workspace::ActivatePaneLeft",
"ctrl-w ctrl-l": "workspace::ActivatePaneRight",
"ctrl-w ctrl-k": "workspace::ActivatePaneUp",
"ctrl-w ctrl-j": "workspace::ActivatePaneDown",
"ctrl-w h": "workspace::ActivatePaneLeft",
"ctrl-w l": "workspace::ActivatePaneRight",
"ctrl-w k": "workspace::ActivatePaneUp",
"ctrl-w j": "workspace::ActivatePaneDown",
"ctrl-w shift-left": "workspace::SwapPaneLeft",
"ctrl-w shift-right": "workspace::SwapPaneRight",
"ctrl-w shift-up": "workspace::SwapPaneUp",
"ctrl-w shift-down": "workspace::SwapPaneDown",
"ctrl-w shift-h": "workspace::SwapPaneLeft",
"ctrl-w shift-l": "workspace::SwapPaneRight",
"ctrl-w shift-k": "workspace::SwapPaneUp",
"ctrl-w shift-j": "workspace::SwapPaneDown",
"ctrl-w >": "vim::ResizePaneRight",
"ctrl-w <": "vim::ResizePaneLeft",
"ctrl-w -": "vim::ResizePaneDown",
"ctrl-w +": "vim::ResizePaneUp",
"ctrl-w left": ["workspace::ActivatePaneInDirection", "Left"],
"ctrl-w right": ["workspace::ActivatePaneInDirection", "Right"],
"ctrl-w up": ["workspace::ActivatePaneInDirection", "Up"],
"ctrl-w down": ["workspace::ActivatePaneInDirection", "Down"],
"ctrl-w ctrl-h": ["workspace::ActivatePaneInDirection", "Left"],
"ctrl-w ctrl-l": ["workspace::ActivatePaneInDirection", "Right"],
"ctrl-w ctrl-k": ["workspace::ActivatePaneInDirection", "Up"],
"ctrl-w ctrl-j": ["workspace::ActivatePaneInDirection", "Down"],
"ctrl-w h": ["workspace::ActivatePaneInDirection", "Left"],
"ctrl-w l": ["workspace::ActivatePaneInDirection", "Right"],
"ctrl-w k": ["workspace::ActivatePaneInDirection", "Up"],
"ctrl-w j": ["workspace::ActivatePaneInDirection", "Down"],
"ctrl-w shift-left": ["workspace::SwapPaneInDirection", "Left"],
"ctrl-w shift-right": ["workspace::SwapPaneInDirection", "Right"],
"ctrl-w shift-up": ["workspace::SwapPaneInDirection", "Up"],
"ctrl-w shift-down": ["workspace::SwapPaneInDirection", "Down"],
"ctrl-w shift-h": ["workspace::SwapPaneInDirection", "Left"],
"ctrl-w shift-l": ["workspace::SwapPaneInDirection", "Right"],
"ctrl-w shift-k": ["workspace::SwapPaneInDirection", "Up"],
"ctrl-w shift-j": ["workspace::SwapPaneInDirection", "Down"],
"ctrl-w >": ["vim::ResizePane", "Widen"],
"ctrl-w <": ["vim::ResizePane", "Narrow"],
"ctrl-w -": ["vim::ResizePane", "Shorten"],
"ctrl-w +": ["vim::ResizePane", "Lengthen"],
"ctrl-w _": "vim::MaximizePane",
"ctrl-w =": "vim::ResetPaneSizes",
"ctrl-w g t": "pane::ActivateNextItem",
@@ -633,12 +610,10 @@
"ctrl-w shift-s": "pane::SplitHorizontal",
"ctrl-w ctrl-s": "pane::SplitHorizontal",
"ctrl-w s": "pane::SplitHorizontal",
"ctrl-w ctrl-c": "pane::CloseActiveItem",
"ctrl-w c": "pane::CloseActiveItem",
"ctrl-w ctrl-q": "pane::CloseActiveItem",
"ctrl-w q": "pane::CloseActiveItem",
"ctrl-w ctrl-a": "pane::CloseAllItems",
"ctrl-w a": "pane::CloseAllItems",
"ctrl-w ctrl-c": "pane::CloseAllItems",
"ctrl-w c": "pane::CloseAllItems",
"ctrl-w ctrl-q": "pane::CloseAllItems",
"ctrl-w q": "pane::CloseAllItems",
"ctrl-w ctrl-o": "workspace::CloseInactiveTabsAndPanes",
"ctrl-w o": "workspace::CloseInactiveTabsAndPanes",
"ctrl-w ctrl-n": "workspace::NewFileSplitHorizontal",
@@ -646,7 +621,7 @@
}
},
{
"context": "ChangesList || EmptyPane || SharedScreen || MarkdownPreview || KeyContextView || Welcome",
"context": "EmptyPane || SharedScreen || MarkdownPreview || KeyContextView || Welcome",
"bindings": {
":": "command_palette::Toggle",
"g /": "pane::DeploySearch"
@@ -709,22 +684,5 @@
"shift-x": "git::StageAll",
"shift-u": "git::UnstageAll"
}
},
{
"context": "Editor && edit_prediction",
"bindings": {
// This is identical to the binding in the base keymap, but the vim bindings above to
// "vim::Tab" shadow it, so it needs to be bound again.
"tab": "editor::AcceptEditPrediction"
}
},
{
"context": "os != macos && Editor && edit_prediction_conflict",
"bindings": {
// alt-l is provided as an alternative to tab/alt-tab. and will be displayed in the UI. This
// is because alt-tab may not be available, as it is often used for window switching on Linux
// and Windows.
"alt-l": "editor::AcceptEditPrediction"
}
}
]

View File

@@ -10,9 +10,8 @@
"light": "One Light",
"dark": "One Dark"
},
"icon_theme": "Zed (Default)",
// The name of a base set of key bindings to use.
// This setting can take six values, each named after another
// This setting can take four values, each named after another
// text editor:
//
// 1. "VSCode"
@@ -24,8 +23,8 @@
"base_keymap": "VSCode",
// Features that can be globally enabled or disabled
"features": {
// Which edit prediction provider to use.
"edit_prediction_provider": "copilot"
// Which inline completion provider to use.
"inline_completion_provider": "copilot"
},
// The name of a font to use for rendering text in the editor
"buffer_font_family": "Zed Plex Mono",
@@ -93,13 +92,6 @@
// workspace when the centered layout is used.
"right_padding": 0.2
},
// All settings related to the image viewer.
"image_viewer": {
// The unit for image file sizes.
// By default we're setting it to binary.
// The second option is decimal.
"unit": "binary"
},
// The key to use for adding multiple cursors
// Currently "alt" or "cmd_or_ctrl" (also aliased as
// "cmd" and "ctrl") are supported.
@@ -126,13 +118,6 @@
// 3. Never close the window
// "when_closing_with_no_tabs": "keep_window_open",
"when_closing_with_no_tabs": "platform_default",
// What to do when the last window is closed.
// May take 2 values:
// 1. Use the current platform's convention
// "on_last_window_closed": "platform_default"
// 2. Always quit the application
// "on_last_window_closed": "quit_app",
"on_last_window_closed": "platform_default",
// Whether to use the system provided dialogs for Open and Save As.
// When set to false, Zed will use the built-in keyboard-first pickers.
"use_system_path_prompts": true,
@@ -161,10 +146,6 @@
// 4. Highlight the full line (default):
// "all"
"current_line_highlight": "all",
// Whether to highlight all occurrences of the selected text in an editor.
"selection_highlight": true,
// The debounce delay before querying highlights based on the selected text.
"selection_highlight_debounce": 50,
// The debounce delay before querying highlights from the language
// server based on the current cursor location.
"lsp_highlight_debounce": 75,
@@ -179,6 +160,9 @@
/// Whether to show the signature help after completion or a bracket pair inserted.
/// If `auto_signature_help` is enabled, this setting will be treated as enabled also.
"show_signature_help_after_edits": false,
/// Whether to show the inline completions next to the completions provided by a language server.
/// Only has an effect if inline completion provider supports it.
"show_inline_completions_in_menu": true,
// Whether to show wrap guides (vertical rulers) in the editor.
// Setting this to true will show a guide at the 'preferred_line_length' value
// if 'soft_wrap' is set to 'preferred_line_length', and will show any
@@ -211,31 +195,14 @@
// Otherwise(when `true`), the closing characters are always skipped over and auto-removed
// no matter how they were inserted.
"always_treat_brackets_as_autoclosed": false,
// Controls where the `editor::Rewrap` action is allowed in the current language scope.
//
// This setting can take three values:
//
// 1. Only allow rewrapping in comments:
// "in_comments"
// 2. Only allow rewrapping in the current selection(s):
// "in_selections"
// 3. Allow rewrapping anywhere:
// "anywhere"
//
// When using values other than `in_comments`, it is possible for the rewrapping to produce code
// that is syntactically invalid. Keep this in mind when selecting which behavior you would like
// to use.
//
// Note: This setting has no effect in Vim mode, as rewrap is already allowed everywhere.
"allow_rewrap": "in_comments",
// Controls whether edit predictions are shown immediately (true)
// or manually by triggering `editor::ShowEditPrediction` (false).
"show_edit_predictions": true,
// Controls whether edit predictions are shown in a given language scope.
// Controls whether inline completions are shown immediately (true)
// or manually by triggering `editor::ShowInlineCompletion` (false).
"show_inline_completions": true,
// Controls whether inline completions are shown in a given language scope.
// Example: ["string", "comment"]
"edit_predictions_disabled_in": [],
"inline_completions_disabled_in": [],
// Whether to show tabs and spaces in the editor.
// This setting can take four values:
// This setting can take three values:
//
// 1. Draw tabs and spaces only for the selected text (default):
// "selection"
@@ -287,8 +254,6 @@
"git_diff": true,
// Whether to show buffer search results in the scrollbar.
"search_results": true,
// Whether to show selected text occurrences in the scrollbar.
"selected_text": true,
// Whether to show selected symbol occurrences in the scrollbar.
"selected_symbol": true,
// Which diagnostic indicators to show in the scrollbar:
@@ -427,7 +392,7 @@
/// Scrollbar-related settings
"scrollbar": {
/// When to show the scrollbar in the project panel.
/// This setting can take five values:
/// This setting can take four values:
///
/// 1. null (default): Inherit editor settings
/// 2. Show the scrollbar if there's important information or
@@ -499,7 +464,7 @@
/// Scrollbar-related settings
"scrollbar": {
/// When to show the scrollbar in the project panel.
/// This setting can take five values:
/// This setting can take four values:
///
/// 1. null (default): Inherit editor settings
/// 2. Show the scrollbar if there's important information or
@@ -581,7 +546,7 @@
// The provider to use.
"provider": "zed.dev",
// The model to use.
"model": "claude-3-5-sonnet-latest"
"model": "claude-3-5-sonnet"
}
},
// The settings for slash commands.
@@ -682,15 +647,15 @@
// There are 5 possible width values:
//
// 1. Small: This value is essentially a fixed width.
// "modal_max_width": "small"
// "modal_width": "small"
// 2. Medium:
// "modal_max_width": "medium"
// "modal_width": "medium"
// 3. Large:
// "modal_max_width": "large"
// "modal_width": "large"
// 4. Extra Large:
// "modal_max_width": "xlarge"
// "modal_width": "xlarge"
// 5. Fullscreen: This value removes any horizontal padding, as it consumes the whole viewport width.
// "modal_max_width": "full"
// "modal_width": "full"
//
// Default: small
"modal_max_width": "small"
@@ -758,28 +723,11 @@
// Diagnostics configuration.
"diagnostics": {
// Whether to show warnings or not by default.
"include_warnings": true,
// Settings for inline diagnostics
"inline": {
// Whether to show diagnostics inline or not
"enabled": false,
// The delay in milliseconds to show inline diagnostics after the
// last diagnostic update.
"update_debounce_ms": 150,
// The amount of padding between the end of the source line and the start
// of the inline diagnostic in units of em widths.
"padding": 4,
// The minimum column to display inline diagnostics. This setting can be
// used to horizontally align inline diagnostics at some column. Lines
// longer than this value will still push diagnostics further to the right.
"min_column": 0,
// The minimum severity of the diagnostics to show inline.
// Shows all diagnostics when not specified.
"max_severity": null
}
"include_warnings": true
},
// Files or globs of files that will be excluded by Zed entirely. They will be skipped during file
// scans, file searches, and not be displayed in the project file tree. Takes precedence over `file_scan_inclusions`.
// Add files or globs of files that will be excluded by Zed entirely:
// they will be skipped during FS scan(s), file tree and file search
// will lack the corresponding file entries. Overrides `file_scan_inclusions`.
"file_scan_exclusions": [
"**/.git",
"**/.svn",
@@ -791,10 +739,10 @@
"**/.classpath",
"**/.settings"
],
// Files or globs of files that will be included by Zed, even when ignored by git. This is useful
// for files that are not tracked by git, but are still important to your project. Note that globs
// that are overly broad can slow down Zed's file scanning. `file_scan_exclusions` takes
// precedence over these inclusions.
// Add files or globs of files that will be included by Zed, even when
// ignored by git. This is useful for files that are not tracked by git,
// but are still important to your project. Note that globs that are
// overly broad can slow down Zed's file scanning. Overridden by `file_scan_exclusions`.
"file_scan_inclusions": [".env*"],
// Git gutter behavior configuration.
"git": {
@@ -825,26 +773,9 @@
// 2. Load direnv configuration through the shell hook, works for POSIX shells and fish.
// "load_direnv": "shell_hook"
"load_direnv": "direct",
"edit_predictions": {
// A list of globs representing files that edit predictions should be disabled for.
// There's a sensible default list of globs already included.
// Any addition to this list will be merged with the default list.
"disabled_globs": [
"**/.env*",
"**/*.pem",
"**/*.key",
"**/*.cert",
"**/*.crt",
"**/.dev.vars",
"**/secrets.yml"
],
// When to show edit predictions previews in buffer.
// This setting takes two possible values:
// 1. Display inline when there are no language server completions available.
// "mode": "eager_preview"
// 2. Display inline when holding modifier key (alt by default).
// "mode": "auto"
"mode": "eager_preview"
"inline_completions": {
// A list of globs representing files that inline completions should be disabled for.
"disabled_globs": [".env"]
},
// Settings specific to journaling
"journal": {
@@ -983,7 +914,7 @@
/// Scrollbar-related settings
"scrollbar": {
/// When to show the scrollbar in the terminal.
/// This setting can take five values:
/// This setting can take four values:
///
/// 1. null (default): Inherit editor settings
/// 2. Show the scrollbar if there's important information or
@@ -1093,7 +1024,6 @@
"tab_size": 2
},
"Diff": {
"show_edit_predictions": false,
"remove_trailing_whitespace_on_save": false,
"ensure_final_newline_on_save": false
},
@@ -1103,9 +1033,6 @@
"Erlang": {
"language_servers": ["erlang-ls", "!elp", "..."]
},
"Git Commit": {
"allow_rewrap": "anywhere"
},
"Go": {
"code_actions_on_format": {
"source.organizeImports": true
@@ -1149,7 +1076,6 @@
"Markdown": {
"format_on_save": "off",
"use_on_type_format": false,
"allow_rewrap": "anywhere",
"prettier": {
"allowed": true
}
@@ -1162,9 +1088,6 @@
"parser": "php"
}
},
"Plain Text": {
"allow_rewrap": "anywhere"
},
"Ruby": {
"language_servers": ["solargraph", "!ruby-lsp", "!rubocop", "..."]
},
@@ -1248,9 +1171,6 @@
},
"deepseek": {
"api_url": "https://api.deepseek.com"
},
"mistral": {
"api_url": "https://api.mistral.ai/v1"
}
},
// Zed's Prettier integration settings.

View File

@@ -1,3 +1,549 @@
## [Andromeda](https://github.com/EliverLara/Andromeda)
The MIT License (MIT)
Copyright (c) 2017 <eliverlara@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Cave Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Cave Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Dune Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Dune Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Estuary Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Estuary Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Forest Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Forest Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Heath Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Heath Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Lakeside Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Lakeside Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Plateau Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Plateau Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Savanna Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Savanna Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Seaside Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Seaside Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Sulphurpool Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Atelier Sulphurpool Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Ayu Dark](https://github.com/dempfi/ayu)
The MIT License (MIT)
@@ -281,3 +827,187 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Rosé Pine](https://github.com/edunfelt/base16-rose-pine-scheme)
The MIT License (MIT)
Copyright (c) 2021 Emilia Dunfelt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Rosé Pine Dawn](https://github.com/edunfelt/base16-rose-pine-scheme)
The MIT License (MIT)
Copyright (c) 2021 Emilia Dunfelt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Rosé Pine Moon](https://github.com/edunfelt/base16-rose-pine-scheme)
The MIT License (MIT)
Copyright (c) 2021 Emilia Dunfelt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Sandcastle](https://github.com/gessig/base16-sandcastle-scheme)
The MIT License (MIT)
Copyright (c) 2019 George Essig
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Solarized Dark](https://github.com/altercation/solarized)
The MIT License (MIT)
Copyright (c) 2011 Ethan Schoonover
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Solarized Light](https://github.com/altercation/solarized)
The MIT License (MIT)
Copyright (c) 2011 Ethan Schoonover
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************
## [Summercamp](https://github.com/zoefiri/base16-sc)
The MIT License (MIT)
Copyright (c) 2019 Zoe FiriH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
********************************************************************************

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 <eliverlara@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,378 @@
{
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
"name": "Andromeda",
"author": "Zed Industries",
"themes": [
{
"name": "Andromeda",
"appearance": "dark",
"style": {
"border": "#2b2f38ff",
"border.variant": "#252931ff",
"border.focused": "#183934ff",
"border.selected": "#183934ff",
"border.transparent": "#00000000",
"border.disabled": "#292d37ff",
"elevated_surface.background": "#21242bff",
"surface.background": "#21242bff",
"background": "#262933ff",
"element.background": "#21242bff",
"element.hover": "#252931ff",
"element.active": "#2a2f39ff",
"element.selected": "#2a2f39ff",
"element.disabled": "#21242bff",
"drop_target.background": "#aca8ae80",
"ghost_element.background": "#00000000",
"ghost_element.hover": "#252931ff",
"ghost_element.active": "#2a2f39ff",
"ghost_element.selected": "#2a2f39ff",
"ghost_element.disabled": "#21242bff",
"text": "#f7f7f8ff",
"text.muted": "#aca8aeff",
"text.placeholder": "#6b6b73ff",
"text.disabled": "#6b6b73ff",
"text.accent": "#10a793ff",
"icon": "#f7f7f8ff",
"icon.muted": "#aca8aeff",
"icon.disabled": "#6b6b73ff",
"icon.placeholder": "#aca8aeff",
"icon.accent": "#10a793ff",
"status_bar.background": "#262933ff",
"title_bar.background": "#262933ff",
"title_bar.inactive_background": "#21242bff",
"toolbar.background": "#1e2025ff",
"tab_bar.background": "#21242bff",
"tab.inactive_background": "#21242bff",
"tab.active_background": "#1e2025ff",
"search.match_background": "#11a79366",
"panel.background": "#21242bff",
"panel.focused_border": "#10a793ff",
"pane.focused_border": null,
"scrollbar.thumb.background": "#f7f7f84c",
"scrollbar.thumb.hover_background": "#252931ff",
"scrollbar.thumb.border": "#252931ff",
"scrollbar.track.background": "#00000000",
"scrollbar.track.border": "#21232aff",
"editor.foreground": "#f7f7f8ff",
"editor.background": "#1e2025ff",
"editor.gutter.background": "#1e2025ff",
"editor.subheader.background": "#21242bff",
"editor.active_line.background": "#21242bbf",
"editor.highlighted_line.background": "#21242bff",
"editor.line_number": "#565960",
"editor.active_line_number": "#f8f8f9",
"editor.hover_line_number": "#cbcdd0",
"editor.invisible": "#64646dff",
"editor.wrap_guide": "#f7f7f80d",
"editor.active_wrap_guide": "#f7f7f81a",
"editor.document_highlight.read_background": "#10a7931a",
"editor.document_highlight.write_background": "#64646d66",
"terminal.background": "#1e2025ff",
"terminal.foreground": "#f7f7f8ff",
"terminal.bright_foreground": "#f7f7f8ff",
"terminal.dim_foreground": "#1e2025ff",
"terminal.ansi.black": "#1e2025ff",
"terminal.ansi.bright_black": "#40434cff",
"terminal.ansi.dim_black": "#f7f7f8ff",
"terminal.ansi.red": "#f82871ff",
"terminal.ansi.bright_red": "#8e0f3aff",
"terminal.ansi.dim_red": "#ffa3b5ff",
"terminal.ansi.green": "#96df71ff",
"terminal.ansi.bright_green": "#457c38ff",
"terminal.ansi.dim_green": "#cef0b9ff",
"terminal.ansi.yellow": "#fee56cff",
"terminal.ansi.bright_yellow": "#958334ff",
"terminal.ansi.dim_yellow": "#fef1b7ff",
"terminal.ansi.blue": "#10a793ff",
"terminal.ansi.bright_blue": "#1a5148ff",
"terminal.ansi.dim_blue": "#9cd4c7ff",
"terminal.ansi.magenta": "#c74cecff",
"terminal.ansi.bright_magenta": "#682681ff",
"terminal.ansi.dim_magenta": "#e7abf7ff",
"terminal.ansi.cyan": "#08e7c5ff",
"terminal.ansi.bright_cyan": "#008169ff",
"terminal.ansi.dim_cyan": "#a9f4e1ff",
"terminal.ansi.white": "#f7f7f8ff",
"terminal.ansi.bright_white": "#f7f7f8ff",
"terminal.ansi.dim_white": "#87858cff",
"link_text.hover": "#10a793ff",
"conflict": "#fee56cff",
"conflict.background": "#5c5014ff",
"conflict.border": "#796b26ff",
"created": "#96df71ff",
"created.background": "#184618ff",
"created.border": "#306129ff",
"deleted": "#f82871ff",
"deleted.background": "#54051bff",
"deleted.border": "#72092aff",
"error": "#f82871ff",
"error.background": "#54051bff",
"error.border": "#72092aff",
"hidden": "#6b6b73ff",
"hidden.background": "#262933ff",
"hidden.border": "#292d37ff",
"hint": "#618399ff",
"hint.background": "#12231fff",
"hint.border": "#183934ff",
"ignored": "#6b6b73ff",
"ignored.background": "#262933ff",
"ignored.border": "#2b2f38ff",
"info": "#10a793ff",
"info.background": "#12231fff",
"info.border": "#183934ff",
"modified": "#fee56cff",
"modified.background": "#5c5014ff",
"modified.border": "#796b26ff",
"predictive": "#315f70ff",
"predictive.background": "#184618ff",
"predictive.border": "#306129ff",
"renamed": "#10a793ff",
"renamed.background": "#12231fff",
"renamed.border": "#183934ff",
"success": "#96df71ff",
"success.background": "#184618ff",
"success.border": "#306129ff",
"unreachable": "#aca8aeff",
"unreachable.background": "#262933ff",
"unreachable.border": "#2b2f38ff",
"warning": "#fee56cff",
"warning.background": "#5c5014ff",
"warning.border": "#796b26ff",
"players": [
{
"cursor": "#10a793ff",
"background": "#10a793ff",
"selection": "#10a7933d"
},
{
"cursor": "#c74cecff",
"background": "#c74cecff",
"selection": "#c74cec3d"
},
{
"cursor": "#f29c14ff",
"background": "#f29c14ff",
"selection": "#f29c143d"
},
{
"cursor": "#893ea6ff",
"background": "#893ea6ff",
"selection": "#893ea63d"
},
{
"cursor": "#08e7c5ff",
"background": "#08e7c5ff",
"selection": "#08e7c53d"
},
{
"cursor": "#f82871ff",
"background": "#f82871ff",
"selection": "#f828713d"
},
{
"cursor": "#fee56cff",
"background": "#fee56cff",
"selection": "#fee56c3d"
},
{
"cursor": "#96df71ff",
"background": "#96df71ff",
"selection": "#96df713d"
}
],
"syntax": {
"attribute": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
},
"boolean": {
"color": "#96df71ff",
"font_style": null,
"font_weight": null
},
"comment": {
"color": "#afabb1ff",
"font_style": null,
"font_weight": null
},
"comment.doc": {
"color": "#afabb1ff",
"font_style": null,
"font_weight": null
},
"constant": {
"color": "#96df71ff",
"font_style": null,
"font_weight": null
},
"constructor": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
},
"embedded": {
"color": "#f7f7f8ff",
"font_style": null,
"font_weight": null
},
"emphasis": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
},
"emphasis.strong": {
"color": "#10a793ff",
"font_style": null,
"font_weight": 700
},
"enum": {
"color": "#f29c14ff",
"font_style": null,
"font_weight": null
},
"function": {
"color": "#fee56cff",
"font_style": null,
"font_weight": null
},
"hint": {
"color": "#618399ff",
"font_style": null,
"font_weight": 700
},
"keyword": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
},
"label": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
},
"link_text": {
"color": "#f29c14ff",
"font_style": "italic",
"font_weight": null
},
"link_uri": {
"color": "#96df71ff",
"font_style": null,
"font_weight": null
},
"number": {
"color": "#96df71ff",
"font_style": null,
"font_weight": null
},
"operator": {
"color": "#f29c14ff",
"font_style": null,
"font_weight": null
},
"predictive": {
"color": "#315f70ff",
"font_style": "italic",
"font_weight": null
},
"preproc": {
"color": "#f7f7f8ff",
"font_style": null,
"font_weight": null
},
"primary": {
"color": "#f7f7f8ff",
"font_style": null,
"font_weight": null
},
"property": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
},
"punctuation": {
"color": "#d8d5dbff",
"font_style": null,
"font_weight": null
},
"punctuation.bracket": {
"color": "#d8d5dbff",
"font_style": null,
"font_weight": null
},
"punctuation.delimiter": {
"color": "#d8d5dbff",
"font_style": null,
"font_weight": null
},
"punctuation.list_marker": {
"color": "#d8d5dbff",
"font_style": null,
"font_weight": null
},
"punctuation.special": {
"color": "#d8d5dbff",
"font_style": null,
"font_weight": null
},
"string": {
"color": "#f29c14ff",
"font_style": null,
"font_weight": null
},
"string.escape": {
"color": "#afabb1ff",
"font_style": null,
"font_weight": null
},
"string.regex": {
"color": "#f29c14ff",
"font_style": null,
"font_weight": null
},
"string.special": {
"color": "#f29c14ff",
"font_style": null,
"font_weight": null
},
"string.special.symbol": {
"color": "#f29c14ff",
"font_style": null,
"font_weight": null
},
"tag": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
},
"text.literal": {
"color": "#f29c14ff",
"font_style": null,
"font_weight": null
},
"title": {
"color": "#f7f7f8ff",
"font_style": null,
"font_weight": 700
},
"type": {
"color": "#08e7c5ff",
"font_style": null,
"font_weight": null
},
"variable": {
"color": "#f7f7f8ff",
"font_style": null,
"font_weight": null
},
"variant": {
"color": "#10a793ff",
"font_style": null,
"font_weight": null
}
}
}
}
]
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -105,9 +105,6 @@
"terminal.ansi.bright_white": "#fbf1c7ff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#83a598ff",
"version_control_added": "#b7bb26ff",
"version_control_modified": "#f9bd2fff",
"version_control_deleted": "#fb4a35ff",
"conflict": "#f9bd2fff",
"conflict.background": "#572e10ff",
"conflict.border": "#754916ff",
@@ -379,7 +376,7 @@
"font_weight": null
},
"variable": {
"color": "#ebdbb2ff",
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
@@ -493,9 +490,6 @@
"terminal.ansi.bright_white": "#fbf1c7ff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#83a598ff",
"version_control_added": "#b7bb26ff",
"version_control_modified": "#f9bd2fff",
"version_control_deleted": "#fb4a35ff",
"conflict": "#f9bd2fff",
"conflict.background": "#572e10ff",
"conflict.border": "#754916ff",
@@ -767,7 +761,7 @@
"font_weight": null
},
"variable": {
"color": "#ebdbb2ff",
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
@@ -881,9 +875,6 @@
"terminal.ansi.bright_white": "#fbf1c7ff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#83a598ff",
"version_control_added": "#b7bb26ff",
"version_control_modified": "#f9bd2fff",
"version_control_deleted": "#fb4a35ff",
"conflict": "#f9bd2fff",
"conflict.background": "#572e10ff",
"conflict.border": "#754916ff",
@@ -1155,7 +1146,7 @@
"font_weight": null
},
"variable": {
"color": "#ebdbb2ff",
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
@@ -1269,9 +1260,6 @@
"terminal.ansi.bright_white": "#282828ff",
"terminal.ansi.dim_white": "#73675eff",
"link_text.hover": "#0b6678ff",
"version_control_added": "#797410ff",
"version_control_modified": "#b57615ff",
"version_control_deleted": "#9d0308ff",
"conflict": "#b57615ff",
"conflict.background": "#f5e2d0ff",
"conflict.border": "#ebccabff",
@@ -1543,7 +1531,7 @@
"font_weight": null
},
"variable": {
"color": "#282828ff",
"color": "#066578ff",
"font_style": null,
"font_weight": null
},
@@ -1657,9 +1645,6 @@
"terminal.ansi.bright_white": "#282828ff",
"terminal.ansi.dim_white": "#73675eff",
"link_text.hover": "#0b6678ff",
"version_control_added": "#797410ff",
"version_control_modified": "#b57615ff",
"version_control_deleted": "#9d0308ff",
"conflict": "#b57615ff",
"conflict.background": "#f5e2d0ff",
"conflict.border": "#ebccabff",
@@ -1931,7 +1916,7 @@
"font_weight": null
},
"variable": {
"color": "#282828ff",
"color": "#066578ff",
"font_style": null,
"font_weight": null
},
@@ -2045,9 +2030,6 @@
"terminal.ansi.bright_white": "#282828ff",
"terminal.ansi.dim_white": "#73675eff",
"link_text.hover": "#0b6678ff",
"version_control_added": "#797410ff",
"version_control_modified": "#b57615ff",
"version_control_deleted": "#9d0308ff",
"conflict": "#b57615ff",
"conflict.background": "#f5e2d0ff",
"conflict.border": "#ebccabff",
@@ -2319,7 +2301,7 @@
"font_weight": null
},
"variable": {
"color": "#282828ff",
"color": "#066578ff",
"font_style": null,
"font_weight": null
},

View File

@@ -81,7 +81,7 @@
"terminal.ansi.bright_green": "#4d6140ff",
"terminal.ansi.dim_green": "#d1e0bfff",
"terminal.ansi.yellow": "#dec184ff",
"terminal.ansi.bright_yellow": "#e5c07bff",
"terminal.ansi.bright_yellow": "#786441ff",
"terminal.ansi.dim_yellow": "#f1dfc1ff",
"terminal.ansi.blue": "#74ade8ff",
"terminal.ansi.bright_blue": "#385378ff",
@@ -96,9 +96,6 @@
"terminal.ansi.bright_white": "#dce0e5ff",
"terminal.ansi.dim_white": "#575d65ff",
"link_text.hover": "#74ade8ff",
"version_control_added": "#a7c088ff",
"version_control_modified": "#dec184ff",
"version_control_deleted": "#d07277ff",
"conflict": "#dec184ff",
"conflict.background": "#dec1841a",
"conflict.border": "#5d4c2fff",
@@ -365,7 +362,7 @@
"font_weight": null
},
"variable": {
"color": "#acb2beff",
"color": "#dce0e5ff",
"font_style": null,
"font_weight": null
},
@@ -444,7 +441,7 @@
"editor.invisible": "#a3a3a4ff",
"editor.wrap_guide": "#383a410d",
"editor.active_wrap_guide": "#383a411a",
"editor.document_highlight.read_background": "#5c78e225",
"editor.document_highlight.read_background": "#5c78e21a",
"editor.document_highlight.write_background": "#a3a3a466",
"terminal.background": "#fafafaff",
"terminal.foreground": "#242529ff",
@@ -460,7 +457,7 @@
"terminal.ansi.bright_green": "#b2cfa9ff",
"terminal.ansi.dim_green": "#354d2eff",
"terminal.ansi.yellow": "#dec184ff",
"terminal.ansi.bright_yellow": "#826221ff",
"terminal.ansi.bright_yellow": "#f1dfc1ff",
"terminal.ansi.dim_yellow": "#786441ff",
"terminal.ansi.blue": "#5c78e2ff",
"terminal.ansi.bright_blue": "#b5baf2ff",
@@ -475,9 +472,6 @@
"terminal.ansi.bright_white": "#242529ff",
"terminal.ansi.dim_white": "#97979aff",
"link_text.hover": "#5c78e2ff",
"version_control_added": "#669f59ff",
"version_control_modified": "#a48819ff",
"version_control_deleted": "#d36151ff",
"conflict": "#a48819ff",
"conflict.background": "#faf2e6ff",
"conflict.border": "#f4e7d1ff",

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2021 Emilia Dunfelt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 George Essig
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,378 @@
{
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
"name": "Sandcastle",
"author": "Zed Industries",
"themes": [
{
"name": "Sandcastle",
"appearance": "dark",
"style": {
"border": "#3d4350ff",
"border.variant": "#313741ff",
"border.focused": "#223131ff",
"border.selected": "#223131ff",
"border.transparent": "#00000000",
"border.disabled": "#393f4aff",
"elevated_surface.background": "#2b3038ff",
"surface.background": "#2b3038ff",
"background": "#333944ff",
"element.background": "#2b3038ff",
"element.hover": "#313741ff",
"element.active": "#3d4350ff",
"element.selected": "#3d4350ff",
"element.disabled": "#2b3038ff",
"drop_target.background": "#a6978280",
"ghost_element.background": "#00000000",
"ghost_element.hover": "#313741ff",
"ghost_element.active": "#3d4350ff",
"ghost_element.selected": "#3d4350ff",
"ghost_element.disabled": "#2b3038ff",
"text": "#fdf4c1ff",
"text.muted": "#a69782ff",
"text.placeholder": "#827568ff",
"text.disabled": "#827568ff",
"text.accent": "#518b8bff",
"icon": "#fdf4c1ff",
"icon.muted": "#a69782ff",
"icon.disabled": "#827568ff",
"icon.placeholder": "#a69782ff",
"icon.accent": "#518b8bff",
"status_bar.background": "#333944ff",
"title_bar.background": "#333944ff",
"title_bar.inactive_background": "#2b3038ff",
"toolbar.background": "#282c33ff",
"tab_bar.background": "#2b3038ff",
"tab.inactive_background": "#2b3038ff",
"tab.active_background": "#282c33ff",
"search.match_background": "#528b8b66",
"panel.background": "#2b3038ff",
"panel.focused_border": "#518b8bff",
"pane.focused_border": null,
"scrollbar.thumb.background": "#fdf4c14c",
"scrollbar.thumb.hover_background": "#313741ff",
"scrollbar.thumb.border": "#313741ff",
"scrollbar.track.background": "#00000000",
"scrollbar.track.border": "#2a2f38ff",
"editor.foreground": "#fdf4c1ff",
"editor.background": "#282c33ff",
"editor.gutter.background": "#282c33ff",
"editor.subheader.background": "#2b3038ff",
"editor.active_line.background": "#2b3038bf",
"editor.highlighted_line.background": "#2b3038ff",
"editor.line_number": "#6b6b61",
"editor.active_line_number": "#dbdbd7",
"editor.hover_line_number": "#b6b6af",
"editor.invisible": "#7c6f64ff",
"editor.wrap_guide": "#fdf4c10d",
"editor.active_wrap_guide": "#fdf4c11a",
"editor.document_highlight.read_background": "#518b8b1a",
"editor.document_highlight.write_background": "#7c6f6466",
"terminal.background": "#282c33ff",
"terminal.foreground": "#fdf4c1ff",
"terminal.bright_foreground": "#fdf4c1ff",
"terminal.dim_foreground": "#282c33ff",
"terminal.ansi.black": "#282c33ff",
"terminal.ansi.bright_black": "#5e5753ff",
"terminal.ansi.dim_black": "#fdf4c1ff",
"terminal.ansi.red": "#b3627aff",
"terminal.ansi.bright_red": "#57333dff",
"terminal.ansi.dim_red": "#dcb0bbff",
"terminal.ansi.green": "#83a598ff",
"terminal.ansi.bright_green": "#414f4aff",
"terminal.ansi.dim_green": "#c0d2cbff",
"terminal.ansi.yellow": "#a07d3aff",
"terminal.ansi.bright_yellow": "#4e3f22ff",
"terminal.ansi.dim_yellow": "#d3bd9aff",
"terminal.ansi.blue": "#518b8bff",
"terminal.ansi.bright_blue": "#2c4444ff",
"terminal.ansi.dim_blue": "#a8c4c4ff",
"terminal.ansi.magenta": "#a87222ff",
"terminal.ansi.bright_magenta": "#523918ff",
"terminal.ansi.dim_magenta": "#dab78eff",
"terminal.ansi.cyan": "#83a598ff",
"terminal.ansi.bright_cyan": "#414f4aff",
"terminal.ansi.dim_cyan": "#c0d2cbff",
"terminal.ansi.white": "#fdf4c1ff",
"terminal.ansi.bright_white": "#fdf4c1ff",
"terminal.ansi.dim_white": "#958776ff",
"link_text.hover": "#518b8bff",
"conflict": "#a07d3aff",
"conflict.background": "#231d12ff",
"conflict.border": "#392e19ff",
"created": "#83a598ff",
"created.background": "#1e2321ff",
"created.border": "#303a36ff",
"deleted": "#b3627aff",
"deleted.background": "#26191cff",
"deleted.border": "#3e272dff",
"error": "#b3627aff",
"error.background": "#26191cff",
"error.border": "#3e272dff",
"hidden": "#827568ff",
"hidden.background": "#333944ff",
"hidden.border": "#393f4aff",
"hint": "#727d68ff",
"hint.background": "#171e1eff",
"hint.border": "#223131ff",
"ignored": "#827568ff",
"ignored.background": "#333944ff",
"ignored.border": "#3d4350ff",
"info": "#518b8bff",
"info.background": "#171e1eff",
"info.border": "#223131ff",
"modified": "#a07d3aff",
"modified.background": "#231d12ff",
"modified.border": "#392e19ff",
"predictive": "#5c6152ff",
"predictive.background": "#1e2321ff",
"predictive.border": "#303a36ff",
"renamed": "#518b8bff",
"renamed.background": "#171e1eff",
"renamed.border": "#223131ff",
"success": "#83a598ff",
"success.background": "#1e2321ff",
"success.border": "#303a36ff",
"unreachable": "#a69782ff",
"unreachable.background": "#333944ff",
"unreachable.border": "#3d4350ff",
"warning": "#a07d3aff",
"warning.background": "#231d12ff",
"warning.border": "#392e19ff",
"players": [
{
"cursor": "#518b8bff",
"background": "#518b8bff",
"selection": "#518b8b3d"
},
{
"cursor": "#a87222ff",
"background": "#a87222ff",
"selection": "#a872223d"
},
{
"cursor": "#a07d3aff",
"background": "#a07d3aff",
"selection": "#a07d3a3d"
},
{
"cursor": "#d75f5fff",
"background": "#d75f5fff",
"selection": "#d75f5f3d"
},
{
"cursor": "#83a598ff",
"background": "#83a598ff",
"selection": "#83a5983d"
},
{
"cursor": "#b3627aff",
"background": "#b3627aff",
"selection": "#b3627a3d"
},
{
"cursor": "#a07d3aff",
"background": "#a07d3aff",
"selection": "#a07d3a3d"
},
{
"cursor": "#83a598ff",
"background": "#83a598ff",
"selection": "#83a5983d"
}
],
"syntax": {
"attribute": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
},
"boolean": {
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
"comment": {
"color": "#a89984ff",
"font_style": null,
"font_weight": null
},
"comment.doc": {
"color": "#a89984ff",
"font_style": null,
"font_weight": null
},
"constant": {
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
"constructor": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
},
"embedded": {
"color": "#fdf4c1ff",
"font_style": null,
"font_weight": null
},
"emphasis": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
},
"emphasis.strong": {
"color": "#518b8bff",
"font_style": null,
"font_weight": 700
},
"enum": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"function": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"hint": {
"color": "#727d68ff",
"font_style": null,
"font_weight": 700
},
"keyword": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
},
"label": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
},
"link_text": {
"color": "#a07d3aff",
"font_style": "italic",
"font_weight": null
},
"link_uri": {
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
"number": {
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
"operator": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"predictive": {
"color": "#5c6152ff",
"font_style": "italic",
"font_weight": null
},
"preproc": {
"color": "#fdf4c1ff",
"font_style": null,
"font_weight": null
},
"primary": {
"color": "#fdf4c1ff",
"font_style": null,
"font_weight": null
},
"property": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
},
"punctuation": {
"color": "#d5c5a1ff",
"font_style": null,
"font_weight": null
},
"punctuation.bracket": {
"color": "#d5c5a1ff",
"font_style": null,
"font_weight": null
},
"punctuation.delimiter": {
"color": "#d5c5a1ff",
"font_style": null,
"font_weight": null
},
"punctuation.list_marker": {
"color": "#d5c5a1ff",
"font_style": null,
"font_weight": null
},
"punctuation.special": {
"color": "#d5c5a1ff",
"font_style": null,
"font_weight": null
},
"string": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"string.escape": {
"color": "#a89984ff",
"font_style": null,
"font_weight": null
},
"string.regex": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"string.special": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"string.special.symbol": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"tag": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
},
"text.literal": {
"color": "#a07d3aff",
"font_style": null,
"font_weight": null
},
"title": {
"color": "#fdf4c1ff",
"font_style": null,
"font_weight": 700
},
"type": {
"color": "#83a598ff",
"font_style": null,
"font_weight": null
},
"variable": {
"color": "#fdf4c1ff",
"font_style": null,
"font_weight": null
},
"variant": {
"color": "#518b8bff",
"font_style": null,
"font_weight": null
}
}
}
}
]
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2011 Ethan Schoonover
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,749 @@
{
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
"name": "Solarized",
"author": "Zed Industries",
"themes": [
{
"name": "Solarized Dark",
"appearance": "dark",
"style": {
"border": "#2b4e58ff",
"border.variant": "#053541ff",
"border.focused": "#1b3149ff",
"border.selected": "#1b3149ff",
"border.transparent": "#00000000",
"border.disabled": "#19424dff",
"elevated_surface.background": "#04313bff",
"surface.background": "#04313bff",
"background": "#073743ff",
"element.background": "#04313bff",
"element.hover": "#053541ff",
"element.active": "#294d58ff",
"element.selected": "#294d58ff",
"element.disabled": "#04313bff",
"drop_target.background": "#93a1a180",
"ghost_element.background": "#00000000",
"ghost_element.hover": "#053541ff",
"ghost_element.active": "#294d58ff",
"ghost_element.selected": "#294d58ff",
"ghost_element.disabled": "#04313bff",
"text": "#fdf6e3ff",
"text.muted": "#93a1a1ff",
"text.placeholder": "#6f8389ff",
"text.disabled": "#6f8389ff",
"text.accent": "#278ad1ff",
"icon": "#fdf6e3ff",
"icon.muted": "#93a1a1ff",
"icon.disabled": "#6f8389ff",
"icon.placeholder": "#93a1a1ff",
"icon.accent": "#278ad1ff",
"status_bar.background": "#073743ff",
"title_bar.background": "#073743ff",
"title_bar.inactive_background": "#04313bff",
"toolbar.background": "#002a35ff",
"tab_bar.background": "#04313bff",
"tab.inactive_background": "#04313bff",
"tab.active_background": "#002a35ff",
"search.match_background": "#288bd166",
"panel.background": "#04313bff",
"panel.focused_border": "#278ad1ff",
"pane.focused_border": null,
"scrollbar.thumb.background": "#fdf6e34c",
"scrollbar.thumb.hover_background": "#053541ff",
"scrollbar.thumb.border": "#053541ff",
"scrollbar.track.background": "#00000000",
"scrollbar.track.border": "#022f3bff",
"editor.foreground": "#fdf6e3ff",
"editor.background": "#002a35ff",
"editor.gutter.background": "#002a35ff",
"editor.subheader.background": "#04313bff",
"editor.active_line.background": "#04313bbf",
"editor.highlighted_line.background": "#04313bff",
"editor.line_number": "#5a6d6f",
"editor.active_line_number": "#e3e8e8",
"editor.hover_line_number": "#abb9ba",
"editor.invisible": "#6c8287ff",
"editor.wrap_guide": "#fdf6e30d",
"editor.active_wrap_guide": "#fdf6e31a",
"editor.document_highlight.read_background": "#278ad11a",
"editor.document_highlight.write_background": "#6c828766",
"terminal.background": "#002a35ff",
"terminal.foreground": "#fdf6e3ff",
"terminal.bright_foreground": "#fdf6e3ff",
"terminal.dim_foreground": "#002a35ff",
"terminal.ansi.black": "#002a35ff",
"terminal.ansi.bright_black": "#5c7279ff",
"terminal.ansi.dim_black": "#fdf6e3ff",
"terminal.ansi.red": "#dc3330ff",
"terminal.ansi.bright_red": "#7d181cff",
"terminal.ansi.dim_red": "#faa091ff",
"terminal.ansi.green": "#849903ff",
"terminal.ansi.bright_green": "#434a10ff",
"terminal.ansi.dim_green": "#c6cb8bff",
"terminal.ansi.yellow": "#b58902ff",
"terminal.ansi.bright_yellow": "#5d430fff",
"terminal.ansi.dim_yellow": "#e0c189ff",
"terminal.ansi.blue": "#278ad1ff",
"terminal.ansi.bright_blue": "#214365ff",
"terminal.ansi.dim_blue": "#a5c3e9ff",
"terminal.ansi.magenta": "#d33781ff",
"terminal.ansi.bright_magenta": "#6f1f3fff",
"terminal.ansi.dim_magenta": "#f0a2beff",
"terminal.ansi.cyan": "#2ba198ff",
"terminal.ansi.bright_cyan": "#204e4aff",
"terminal.ansi.dim_cyan": "#9fd0cbff",
"terminal.ansi.white": "#fdf6e3ff",
"terminal.ansi.bright_white": "#fdf6e3ff",
"terminal.ansi.dim_white": "#7b8e91ff",
"link_text.hover": "#278ad1ff",
"conflict": "#b58902ff",
"conflict.background": "#2e1d0cff",
"conflict.border": "#47300fff",
"created": "#849903ff",
"created.background": "#1e210cff",
"created.border": "#313510ff",
"deleted": "#dc3330ff",
"deleted.background": "#4a080eff",
"deleted.border": "#641015ff",
"error": "#dc3330ff",
"error.background": "#4a080eff",
"error.border": "#641015ff",
"hidden": "#6f8389ff",
"hidden.background": "#073743ff",
"hidden.border": "#19424dff",
"hint": "#4f8297ff",
"hint.background": "#141f2cff",
"hint.border": "#1b3149ff",
"ignored": "#6f8389ff",
"ignored.background": "#073743ff",
"ignored.border": "#2b4e58ff",
"info": "#278ad1ff",
"info.background": "#141f2cff",
"info.border": "#1b3149ff",
"modified": "#b58902ff",
"modified.background": "#2e1d0cff",
"modified.border": "#47300fff",
"predictive": "#3f718bff",
"predictive.background": "#1e210cff",
"predictive.border": "#313510ff",
"renamed": "#278ad1ff",
"renamed.background": "#141f2cff",
"renamed.border": "#1b3149ff",
"success": "#849903ff",
"success.background": "#1e210cff",
"success.border": "#313510ff",
"unreachable": "#93a1a1ff",
"unreachable.background": "#073743ff",
"unreachable.border": "#2b4e58ff",
"warning": "#b58902ff",
"warning.background": "#2e1d0cff",
"warning.border": "#47300fff",
"players": [
{
"cursor": "#278ad1ff",
"background": "#278ad1ff",
"selection": "#278ad13d"
},
{
"cursor": "#d33781ff",
"background": "#d33781ff",
"selection": "#d337813d"
},
{
"cursor": "#cb4b16ff",
"background": "#cb4b16ff",
"selection": "#cb4b163d"
},
{
"cursor": "#6c71c4ff",
"background": "#6c71c4ff",
"selection": "#6c71c43d"
},
{
"cursor": "#2ba198ff",
"background": "#2ba198ff",
"selection": "#2ba1983d"
},
{
"cursor": "#dc3330ff",
"background": "#dc3330ff",
"selection": "#dc33303d"
},
{
"cursor": "#b58902ff",
"background": "#b58902ff",
"selection": "#b589023d"
},
{
"cursor": "#849903ff",
"background": "#849903ff",
"selection": "#8499033d"
}
],
"syntax": {
"attribute": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
},
"boolean": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"comment": {
"color": "#99a5a4ff",
"font_style": null,
"font_weight": null
},
"comment.doc": {
"color": "#99a5a4ff",
"font_style": null,
"font_weight": null
},
"constant": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"constructor": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
},
"embedded": {
"color": "#fdf6e3ff",
"font_style": null,
"font_weight": null
},
"emphasis": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
},
"emphasis.strong": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": 700
},
"enum": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"function": {
"color": "#b58902ff",
"font_style": null,
"font_weight": null
},
"hint": {
"color": "#4f8297ff",
"font_style": null,
"font_weight": 700
},
"keyword": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
},
"label": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
},
"link_text": {
"color": "#cb4b16ff",
"font_style": "italic",
"font_weight": null
},
"link_uri": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"number": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"operator": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"predictive": {
"color": "#3f718bff",
"font_style": "italic",
"font_weight": null
},
"preproc": {
"color": "#fdf6e3ff",
"font_style": null,
"font_weight": null
},
"primary": {
"color": "#fdf6e3ff",
"font_style": null,
"font_weight": null
},
"property": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
},
"punctuation": {
"color": "#efe9d6ff",
"font_style": null,
"font_weight": null
},
"punctuation.bracket": {
"color": "#efe9d6ff",
"font_style": null,
"font_weight": null
},
"punctuation.delimiter": {
"color": "#efe9d6ff",
"font_style": null,
"font_weight": null
},
"punctuation.list_marker": {
"color": "#efe9d6ff",
"font_style": null,
"font_weight": null
},
"punctuation.special": {
"color": "#efe9d6ff",
"font_style": null,
"font_weight": null
},
"string": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"string.escape": {
"color": "#99a5a4ff",
"font_style": null,
"font_weight": null
},
"string.regex": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"string.special": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"string.special.symbol": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"tag": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
},
"text.literal": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"title": {
"color": "#fdf6e3ff",
"font_style": null,
"font_weight": 700
},
"type": {
"color": "#2ba198ff",
"font_style": null,
"font_weight": null
},
"variable": {
"color": "#fdf6e3ff",
"font_style": null,
"font_weight": null
},
"variant": {
"color": "#278ad1ff",
"font_style": null,
"font_weight": null
}
}
}
},
{
"name": "Solarized Light",
"appearance": "light",
"style": {
"border": "#9faaa8ff",
"border.variant": "#dcdacbff",
"border.focused": "#bfd3efff",
"border.selected": "#bfd3efff",
"border.transparent": "#00000000",
"border.disabled": "#b6bcb5ff",
"elevated_surface.background": "#f3eddaff",
"surface.background": "#f3eddaff",
"background": "#cfd0c4ff",
"element.background": "#f3eddaff",
"element.hover": "#dcdacbff",
"element.active": "#a2aca9ff",
"element.selected": "#a2aca9ff",
"element.disabled": "#f3eddaff",
"drop_target.background": "#34555e80",
"ghost_element.background": "#00000000",
"ghost_element.hover": "#dcdacbff",
"ghost_element.active": "#a2aca9ff",
"ghost_element.selected": "#a2aca9ff",
"ghost_element.disabled": "#f3eddaff",
"text": "#002a35ff",
"text.muted": "#34555eff",
"text.placeholder": "#6a7f86ff",
"text.disabled": "#6a7f86ff",
"text.accent": "#288bd1ff",
"icon": "#002a35ff",
"icon.muted": "#34555eff",
"icon.disabled": "#6a7f86ff",
"icon.placeholder": "#34555eff",
"icon.accent": "#288bd1ff",
"status_bar.background": "#cfd0c4ff",
"title_bar.background": "#cfd0c4ff",
"title_bar.inactive_background": "#f3eddaff",
"toolbar.background": "#fdf6e3ff",
"tab_bar.background": "#f3eddaff",
"tab.inactive_background": "#f3eddaff",
"tab.active_background": "#fdf6e3ff",
"search.match_background": "#298bd166",
"panel.background": "#f3eddaff",
"panel.focused_border": "#288bd1ff",
"pane.focused_border": null,
"scrollbar.thumb.background": "#002a354c",
"scrollbar.thumb.hover_background": "#dcdacbff",
"scrollbar.thumb.border": "#dcdacbff",
"scrollbar.track.background": "#00000000",
"scrollbar.track.border": "#f5eedbff",
"editor.foreground": "#002a35ff",
"editor.background": "#fdf6e3ff",
"editor.gutter.background": "#fdf6e3ff",
"editor.subheader.background": "#f3eddaff",
"editor.active_line.background": "#f3eddabf",
"editor.highlighted_line.background": "#f3eddaff",
"editor.line_number": "#a8ad9f",
"editor.active_line_number": "#272923",
"editor.hover_line_number": "#42453b",
"editor.invisible": "#6c8287ff",
"editor.wrap_guide": "#002a350d",
"editor.active_wrap_guide": "#002a351a",
"editor.document_highlight.read_background": "#288bd11a",
"editor.document_highlight.write_background": "#6c828766",
"terminal.background": "#fdf6e3ff",
"terminal.foreground": "#002a35ff",
"terminal.bright_foreground": "#002a35ff",
"terminal.dim_foreground": "#fdf6e3ff",
"terminal.ansi.black": "#fdf6e3ff",
"terminal.ansi.bright_black": "#7b8e91ff",
"terminal.ansi.dim_black": "#002a35ff",
"terminal.ansi.red": "#dc3330ff",
"terminal.ansi.bright_red": "#faa091ff",
"terminal.ansi.dim_red": "#7d181cff",
"terminal.ansi.green": "#849903ff",
"terminal.ansi.bright_green": "#c6cb8bff",
"terminal.ansi.dim_green": "#434a10ff",
"terminal.ansi.yellow": "#b58903ff",
"terminal.ansi.bright_yellow": "#e0c189ff",
"terminal.ansi.dim_yellow": "#5d430fff",
"terminal.ansi.blue": "#288bd1ff",
"terminal.ansi.bright_blue": "#a5c3e9ff",
"terminal.ansi.dim_blue": "#214365ff",
"terminal.ansi.magenta": "#d33781ff",
"terminal.ansi.bright_magenta": "#f0a2beff",
"terminal.ansi.dim_magenta": "#6f1f3fff",
"terminal.ansi.cyan": "#2ba198ff",
"terminal.ansi.bright_cyan": "#9fd0cbff",
"terminal.ansi.dim_cyan": "#204e4aff",
"terminal.ansi.white": "#002a35ff",
"terminal.ansi.bright_white": "#002a35ff",
"terminal.ansi.dim_white": "#5c7279ff",
"link_text.hover": "#288bd1ff",
"conflict": "#b58903ff",
"conflict.background": "#f5e6d0ff",
"conflict.border": "#ebd3aaff",
"created": "#849903ff",
"created.background": "#e9ead0ff",
"created.border": "#d6d9abff",
"deleted": "#dc3330ff",
"deleted.background": "#ffd9d2ff",
"deleted.border": "#ffbbafff",
"error": "#dc3330ff",
"error.background": "#ffd9d2ff",
"error.border": "#ffbbafff",
"hidden": "#6a7f86ff",
"hidden.background": "#cfd0c4ff",
"hidden.border": "#b6bcb5ff",
"hint": "#5789a3ff",
"hint.background": "#dbe6f6ff",
"hint.border": "#bfd3efff",
"ignored": "#6a7f86ff",
"ignored.background": "#cfd0c4ff",
"ignored.border": "#9faaa8ff",
"info": "#288bd1ff",
"info.background": "#dbe6f6ff",
"info.border": "#bfd3efff",
"modified": "#b58903ff",
"modified.background": "#f5e6d0ff",
"modified.border": "#ebd3aaff",
"predictive": "#679aafff",
"predictive.background": "#e9ead0ff",
"predictive.border": "#d6d9abff",
"renamed": "#288bd1ff",
"renamed.background": "#dbe6f6ff",
"renamed.border": "#bfd3efff",
"success": "#849903ff",
"success.background": "#e9ead0ff",
"success.border": "#d6d9abff",
"unreachable": "#34555eff",
"unreachable.background": "#cfd0c4ff",
"unreachable.border": "#9faaa8ff",
"warning": "#b58903ff",
"warning.background": "#f5e6d0ff",
"warning.border": "#ebd3aaff",
"players": [
{
"cursor": "#288bd1ff",
"background": "#288bd1ff",
"selection": "#288bd13d"
},
{
"cursor": "#d33781ff",
"background": "#d33781ff",
"selection": "#d337813d"
},
{
"cursor": "#cb4b16ff",
"background": "#cb4b16ff",
"selection": "#cb4b173d"
},
{
"cursor": "#6c71c3ff",
"background": "#6c71c3ff",
"selection": "#6c71c33d"
},
{
"cursor": "#2ba198ff",
"background": "#2ba198ff",
"selection": "#2ba1983d"
},
{
"cursor": "#dc3330ff",
"background": "#dc3330ff",
"selection": "#dc33303d"
},
{
"cursor": "#b58903ff",
"background": "#b58903ff",
"selection": "#b589033d"
},
{
"cursor": "#849903ff",
"background": "#849903ff",
"selection": "#8499033d"
}
],
"syntax": {
"attribute": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
},
"boolean": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"comment": {
"color": "#30525bff",
"font_style": null,
"font_weight": null
},
"comment.doc": {
"color": "#30525bff",
"font_style": null,
"font_weight": null
},
"constant": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"constructor": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
},
"embedded": {
"color": "#002a35ff",
"font_style": null,
"font_weight": null
},
"emphasis": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
},
"emphasis.strong": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": 700
},
"enum": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"function": {
"color": "#b58903ff",
"font_style": null,
"font_weight": null
},
"hint": {
"color": "#5789a3ff",
"font_style": null,
"font_weight": 700
},
"keyword": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
},
"label": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
},
"link_text": {
"color": "#cb4b16ff",
"font_style": "italic",
"font_weight": null
},
"link_uri": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"number": {
"color": "#849903ff",
"font_style": null,
"font_weight": null
},
"operator": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"predictive": {
"color": "#679aafff",
"font_style": "italic",
"font_weight": null
},
"preproc": {
"color": "#002a35ff",
"font_style": null,
"font_weight": null
},
"primary": {
"color": "#002a35ff",
"font_style": null,
"font_weight": null
},
"property": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
},
"punctuation": {
"color": "#04333eff",
"font_style": null,
"font_weight": null
},
"punctuation.bracket": {
"color": "#04333eff",
"font_style": null,
"font_weight": null
},
"punctuation.delimiter": {
"color": "#04333eff",
"font_style": null,
"font_weight": null
},
"punctuation.list_marker": {
"color": "#04333eff",
"font_style": null,
"font_weight": null
},
"punctuation.special": {
"color": "#04333eff",
"font_style": null,
"font_weight": null
},
"string": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"string.escape": {
"color": "#30525bff",
"font_style": null,
"font_weight": null
},
"string.regex": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"string.special": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"string.special.symbol": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"tag": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
},
"text.literal": {
"color": "#cb4b16ff",
"font_style": null,
"font_weight": null
},
"title": {
"color": "#002a35ff",
"font_style": null,
"font_weight": 700
},
"type": {
"color": "#2ba198ff",
"font_style": null,
"font_weight": null
},
"variable": {
"color": "#002a35ff",
"font_style": null,
"font_weight": null
},
"variant": {
"color": "#288bd1ff",
"font_style": null,
"font_weight": null
}
}
}
}
]
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 Zoe FiriH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,378 @@
{
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
"name": "Summercamp",
"author": "Zed Industries",
"themes": [
{
"name": "Summercamp",
"appearance": "dark",
"style": {
"border": "#302c21ff",
"border.variant": "#29251bff",
"border.focused": "#193760ff",
"border.selected": "#193760ff",
"border.transparent": "#00000000",
"border.disabled": "#2e2a1fff",
"elevated_surface.background": "#231f16ff",
"surface.background": "#231f16ff",
"background": "#2a261cff",
"element.background": "#231f16ff",
"element.hover": "#29251bff",
"element.active": "#2f2b20ff",
"element.selected": "#2f2b20ff",
"element.disabled": "#231f16ff",
"drop_target.background": "#736e5580",
"ghost_element.background": "#00000000",
"ghost_element.hover": "#29251bff",
"ghost_element.active": "#2f2b20ff",
"ghost_element.selected": "#2f2b20ff",
"ghost_element.disabled": "#231f16ff",
"text": "#f8f5deff",
"text.muted": "#736e55ff",
"text.placeholder": "#4c4735ff",
"text.disabled": "#4c4735ff",
"text.accent": "#499befff",
"icon": "#f8f5deff",
"icon.muted": "#736e55ff",
"icon.disabled": "#4c4735ff",
"icon.placeholder": "#736e55ff",
"icon.accent": "#499befff",
"status_bar.background": "#2a261cff",
"title_bar.background": "#2a261cff",
"title_bar.inactive_background": "#231f16ff",
"toolbar.background": "#1b1810ff",
"tab_bar.background": "#231f16ff",
"tab.inactive_background": "#231f16ff",
"tab.active_background": "#1b1810ff",
"search.match_background": "#499bef66",
"panel.background": "#231f16ff",
"panel.focused_border": "#499befff",
"pane.focused_border": null,
"scrollbar.thumb.background": "#f8f5de4c",
"scrollbar.thumb.hover_background": "#29251bff",
"scrollbar.thumb.border": "#29251bff",
"scrollbar.track.background": "#00000000",
"scrollbar.track.border": "#221e15ff",
"editor.foreground": "#f8f5deff",
"editor.background": "#1b1810ff",
"editor.gutter.background": "#1b1810ff",
"editor.subheader.background": "#231f16ff",
"editor.active_line.background": "#231f16bf",
"editor.highlighted_line.background": "#231f16ff",
"editor.line_number": "#676559",
"editor.active_line_number": "#e3e2de",
"editor.hover_line_number": "#b8b6ad",
"editor.invisible": "#494433ff",
"editor.wrap_guide": "#f8f5de0d",
"editor.active_wrap_guide": "#f8f5de1a",
"editor.document_highlight.read_background": "#499bef1a",
"editor.document_highlight.write_background": "#49443366",
"terminal.background": "#1b1810ff",
"terminal.foreground": "#f8f5deff",
"terminal.bright_foreground": "#f8f5deff",
"terminal.dim_foreground": "#1b1810ff",
"terminal.ansi.black": "#1b1810ff",
"terminal.ansi.bright_black": "#3a3527ff",
"terminal.ansi.dim_black": "#f8f5deff",
"terminal.ansi.red": "#e35041ff",
"terminal.ansi.bright_red": "#7f2724ff",
"terminal.ansi.dim_red": "#faaa9bff",
"terminal.ansi.green": "#5dea5aff",
"terminal.ansi.bright_green": "#28842cff",
"terminal.ansi.dim_green": "#b9f7aeff",
"terminal.ansi.yellow": "#f1fe28ff",
"terminal.ansi.bright_yellow": "#8c9a0fff",
"terminal.ansi.dim_yellow": "#ffffa2ff",
"terminal.ansi.blue": "#499befff",
"terminal.ansi.bright_blue": "#234b7fff",
"terminal.ansi.dim_blue": "#b1ccf8ff",
"terminal.ansi.magenta": "#f59be6ff",
"terminal.ansi.bright_magenta": "#88487eff",
"terminal.ansi.dim_magenta": "#fccef3ff",
"terminal.ansi.cyan": "#5aeabbff",
"terminal.ansi.bright_cyan": "#288461ff",
"terminal.ansi.dim_cyan": "#b7f6ddff",
"terminal.ansi.white": "#f8f5deff",
"terminal.ansi.bright_white": "#f8f5deff",
"terminal.ansi.dim_white": "#57533fff",
"link_text.hover": "#499befff",
"conflict": "#f1fe28ff",
"conflict.background": "#546205ff",
"conflict.border": "#717f0aff",
"created": "#5dea5aff",
"created.background": "#094d12ff",
"created.border": "#1a6a20ff",
"deleted": "#e35041ff",
"deleted.background": "#490f12ff",
"deleted.border": "#651c1cff",
"error": "#e35041ff",
"error.background": "#490f12ff",
"error.border": "#651c1cff",
"hidden": "#4c4735ff",
"hidden.background": "#2a261cff",
"hidden.border": "#2e2a1fff",
"hint": "#246e61ff",
"hint.background": "#0e2242ff",
"hint.border": "#193760ff",
"ignored": "#4c4735ff",
"ignored.background": "#2a261cff",
"ignored.border": "#302c21ff",
"info": "#499befff",
"info.background": "#0e2242ff",
"info.border": "#193760ff",
"modified": "#f1fe28ff",
"modified.background": "#546205ff",
"modified.border": "#717f0aff",
"predictive": "#78434aff",
"predictive.background": "#094d12ff",
"predictive.border": "#1a6a20ff",
"renamed": "#499befff",
"renamed.background": "#0e2242ff",
"renamed.border": "#193760ff",
"success": "#5dea5aff",
"success.background": "#094d12ff",
"success.border": "#1a6a20ff",
"unreachable": "#736e55ff",
"unreachable.background": "#2a261cff",
"unreachable.border": "#302c21ff",
"warning": "#f1fe28ff",
"warning.background": "#546205ff",
"warning.border": "#717f0aff",
"players": [
{
"cursor": "#499befff",
"background": "#499befff",
"selection": "#499bef3d"
},
{
"cursor": "#f59be6ff",
"background": "#f59be6ff",
"selection": "#f59be63d"
},
{
"cursor": "#faa11cff",
"background": "#faa11cff",
"selection": "#faa11c3d"
},
{
"cursor": "#fe8080ff",
"background": "#fe8080ff",
"selection": "#fe80803d"
},
{
"cursor": "#5aeabbff",
"background": "#5aeabbff",
"selection": "#5aeabb3d"
},
{
"cursor": "#e35041ff",
"background": "#e35041ff",
"selection": "#e350413d"
},
{
"cursor": "#f1fe28ff",
"background": "#f1fe28ff",
"selection": "#f1fe283d"
},
{
"cursor": "#5dea5aff",
"background": "#5dea5aff",
"selection": "#5dea5a3d"
}
],
"syntax": {
"attribute": {
"color": "#499befff",
"font_style": null,
"font_weight": null
},
"boolean": {
"color": "#5dea5aff",
"font_style": null,
"font_weight": null
},
"comment": {
"color": "#777159ff",
"font_style": null,
"font_weight": null
},
"comment.doc": {
"color": "#777159ff",
"font_style": null,
"font_weight": null
},
"constant": {
"color": "#5dea5aff",
"font_style": null,
"font_weight": null
},
"constructor": {
"color": "#499befff",
"font_style": null,
"font_weight": null
},
"embedded": {
"color": "#f8f5deff",
"font_style": null,
"font_weight": null
},
"emphasis": {
"color": "#499befff",
"font_style": null,
"font_weight": null
},
"emphasis.strong": {
"color": "#499befff",
"font_style": null,
"font_weight": 700
},
"enum": {
"color": "#faa11cff",
"font_style": null,
"font_weight": null
},
"function": {
"color": "#f1fe28ff",
"font_style": null,
"font_weight": null
},
"hint": {
"color": "#246e61ff",
"font_style": null,
"font_weight": 700
},
"keyword": {
"color": "#499befff",
"font_style": null,
"font_weight": null
},
"label": {
"color": "#499befff",
"font_style": null,
"font_weight": null
},
"link_text": {
"color": "#faa11cff",
"font_style": "italic",
"font_weight": null
},
"link_uri": {
"color": "#5dea5aff",
"font_style": null,
"font_weight": null
},
"number": {
"color": "#5dea5aff",
"font_style": null,
"font_weight": null
},
"operator": {
"color": "#faa11cff",
"font_style": null,
"font_weight": null
},
"predictive": {
"color": "#78434aff",
"font_style": "italic",
"font_weight": null
},
"preproc": {
"color": "#f8f5deff",
"font_style": null,
"font_weight": null
},
"primary": {
"color": "#f8f5deff",
"font_style": null,
"font_weight": null
},
"property": {
"color": "#499befff",
"font_style": null,
"font_weight": null
},
"punctuation": {
"color": "#bfbb9bff",
"font_style": null,
"font_weight": null
},
"punctuation.bracket": {
"color": "#bfbb9bff",
"font_style": null,
"font_weight": null
},
"punctuation.delimiter": {
"color": "#bfbb9bff",
"font_style": null,
"font_weight": null
},
"punctuation.list_marker": {
"color": "#bfbb9bff",
"font_style": null,
"font_weight": null
},
"punctuation.special": {
"color": "#bfbb9bff",
"font_style": null,
"font_weight": null
},
"string": {
"color": "#faa11cff",
"font_style": null,
"font_weight": null
},
"string.escape": {
"color": "#777159ff",
"font_style": null,
"font_weight": null
},
"string.regex": {
"color": "#faa11cff",
"font_style": null,
"font_weight": null
},
"string.special": {
"color": "#faa11cff",
"font_style": null,
"font_weight": null
},
"string.special.symbol": {
"color": "#faa11cff",
"font_style": null,
"font_weight": null
},
"tag": {
"color": "#499befff",
"font_style": null,
"font_weight": null
},
"text.literal": {
"color": "#faa11cff",
"font_style": null,
"font_weight": null
},
"title": {
"color": "#f8f5deff",
"font_style": null,
"font_weight": 700
},
"type": {
"color": "#5aeabbff",
"font_style": null,
"font_weight": null
},
"variable": {
"color": "#f8f5deff",
"font_style": null,
"font_weight": null
},
"variant": {
"color": "#499befff",
"font_style": null,
"font_weight": null
}
}
}
}
]
}

View File

@@ -3,7 +3,7 @@ name = "anthropic"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
license = "GPL-3.0-or-later"
license = "AGPL-3.0-or-later"
[features]
default = []

View File

@@ -0,0 +1 @@
../../LICENSE-AGPL

View File

@@ -30,8 +30,6 @@ pub enum Model {
#[default]
#[serde(rename = "claude-3-5-sonnet", alias = "claude-3-5-sonnet-latest")]
Claude3_5Sonnet,
#[serde(rename = "claude-3-7-sonnet", alias = "claude-3-7-sonnet-latest")]
Claude3_7Sonnet,
#[serde(rename = "claude-3-5-haiku", alias = "claude-3-5-haiku-latest")]
Claude3_5Haiku,
#[serde(rename = "claude-3-opus", alias = "claude-3-opus-latest")]
@@ -61,8 +59,6 @@ impl Model {
pub fn from_id(id: &str) -> Result<Self> {
if id.starts_with("claude-3-5-sonnet") {
Ok(Self::Claude3_5Sonnet)
} else if id.starts_with("claude-3-7-sonnet") {
Ok(Self::Claude3_7Sonnet)
} else if id.starts_with("claude-3-5-haiku") {
Ok(Self::Claude3_5Haiku)
} else if id.starts_with("claude-3-opus") {
@@ -79,7 +75,6 @@ impl Model {
pub fn id(&self) -> &str {
match self {
Model::Claude3_5Sonnet => "claude-3-5-sonnet-latest",
Model::Claude3_7Sonnet => "claude-3-7-sonnet-latest",
Model::Claude3_5Haiku => "claude-3-5-haiku-latest",
Model::Claude3Opus => "claude-3-opus-latest",
Model::Claude3Sonnet => "claude-3-sonnet-20240229",
@@ -90,7 +85,6 @@ impl Model {
pub fn display_name(&self) -> &str {
match self {
Self::Claude3_7Sonnet => "Claude 3.7 Sonnet",
Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
Self::Claude3_5Haiku => "Claude 3.5 Haiku",
Self::Claude3Opus => "Claude 3 Opus",
@@ -104,14 +98,13 @@ impl Model {
pub fn cache_configuration(&self) -> Option<AnthropicModelCacheConfiguration> {
match self {
Self::Claude3_5Sonnet
| Self::Claude3_5Haiku
| Self::Claude3_7Sonnet
| Self::Claude3Haiku => Some(AnthropicModelCacheConfiguration {
min_total_token: 2_048,
should_speculate: true,
max_cache_anchors: 4,
}),
Self::Claude3_5Sonnet | Self::Claude3_5Haiku | Self::Claude3Haiku => {
Some(AnthropicModelCacheConfiguration {
min_total_token: 2_048,
should_speculate: true,
max_cache_anchors: 4,
})
}
Self::Custom {
cache_configuration,
..
@@ -124,7 +117,6 @@ impl Model {
match self {
Self::Claude3_5Sonnet
| Self::Claude3_5Haiku
| Self::Claude3_7Sonnet
| Self::Claude3Opus
| Self::Claude3Sonnet
| Self::Claude3Haiku => 200_000,
@@ -135,7 +127,7 @@ impl Model {
pub fn max_output_tokens(&self) -> u32 {
match self {
Self::Claude3Opus | Self::Claude3Sonnet | Self::Claude3Haiku => 4_096,
Self::Claude3_5Sonnet | Self::Claude3_7Sonnet | Self::Claude3_5Haiku => 8_192,
Self::Claude3_5Sonnet | Self::Claude3_5Haiku => 8_192,
Self::Custom {
max_output_tokens, ..
} => max_output_tokens.unwrap_or(4_096),
@@ -145,7 +137,6 @@ impl Model {
pub fn default_temperature(&self) -> f32 {
match self {
Self::Claude3_5Sonnet
| Self::Claude3_7Sonnet
| Self::Claude3_5Haiku
| Self::Claude3Opus
| Self::Claude3Sonnet
@@ -259,7 +250,7 @@ pub async fn stream_completion(
.map(|output| output.0)
}
/// <https://docs.anthropic.com/en/api/rate-limits#response-headers>
/// https://docs.anthropic.com/en/api/rate-limits#response-headers
#[derive(Debug)]
pub struct RateLimitInfo {
pub requests_limit: usize,
@@ -635,7 +626,7 @@ pub struct ApiError {
}
/// An Anthropic API error code.
/// <https://docs.anthropic.com/en/api/errors#http-errors>
/// https://docs.anthropic.com/en/api/errors#http-errors
#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumString)]
#[strum(serialize_all = "snake_case")]
pub enum ApiErrorCode {

View File

@@ -3,7 +3,7 @@ use std::sync::LazyLock;
/// Returns whether the given country code is supported by Anthropic.
///
/// <https://www.anthropic.com/supported-countries>
/// https://www.anthropic.com/supported-countries
pub fn is_supported_country(country_code: &str) -> bool {
SUPPORTED_COUNTRIES.contains(&country_code)
}

View File

@@ -43,6 +43,7 @@ indoc.workspace = true
language.workspace = true
language_model.workspace = true
language_model_selector.workspace = true
language_models.workspace = true
log.workspace = true
lsp.workspace = true
menu.workspace = true
@@ -58,6 +59,7 @@ search.workspace = true
semantic_index.workspace = true
serde.workspace = true
settings.workspace = true
similar.workspace = true
smol.workspace = true
streaming_diff.workspace = true
telemetry.workspace = true

View File

@@ -33,7 +33,7 @@ actions!(
[
InsertActivePrompt,
DeployHistory,
NewChat,
NewContext,
CycleNextInlineAssist,
CyclePreviousInlineAssist
]

View File

@@ -1,16 +1,17 @@
use crate::assistant_configuration::{ConfigurationView, ConfigurationViewEvent};
use crate::{
terminal_inline_assistant::TerminalInlineAssistant, DeployHistory, InlineAssistant, NewChat,
terminal_inline_assistant::TerminalInlineAssistant, DeployHistory, InlineAssistant, NewContext,
};
use anyhow::{anyhow, Result};
use assistant_context_editor::{
make_lsp_adapter_delegate, AssistantContext, AssistantPanelDelegate, ContextEditor,
ContextEditorToolbarItem, ContextEditorToolbarItemEvent, ContextHistory, ContextId,
ContextStore, ContextStoreEvent, InsertDraggedFiles, SlashCommandCompletionProvider,
DEFAULT_TAB_TITLE,
ToggleModelSelector, DEFAULT_TAB_TITLE,
};
use assistant_settings::{AssistantDockPosition, AssistantSettings};
use assistant_slash_command::SlashCommandWorkingSet;
use assistant_tool::ToolWorkingSet;
use client::{proto, Client, Status};
use editor::{Editor, EditorEvent};
use fs::Fs;
@@ -20,9 +21,8 @@ use gpui::{
Subscription, Task, UpdateGlobal, WeakEntity,
};
use language::LanguageRegistry;
use language_model::{
AuthenticateError, LanguageModelProviderId, LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID,
};
use language_model::{LanguageModelProviderId, LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID};
use language_model_selector::LanguageModelSelector;
use project::Project;
use prompt_library::{open_prompt_library, PromptBuilder, PromptLibrary};
use search::{buffer_search::DivRegistrar, BufferSearchBar};
@@ -30,7 +30,7 @@ use settings::{update_settings_file, Settings};
use smol::stream::StreamExt;
use std::{ops::ControlFlow, path::PathBuf, sync::Arc};
use terminal_view::{terminal_panel::TerminalPanel, TerminalView};
use ui::{prelude::*, ContextMenu, PopoverMenu, Tooltip};
use ui::{prelude::*, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip};
use util::{maybe, ResultExt};
use workspace::DraggedTab;
use workspace::{
@@ -78,6 +78,7 @@ pub struct AssistantPanel {
languages: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>,
subscriptions: Vec<Subscription>,
model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
model_summary_editor: Entity<Editor>,
authenticate_provider_task: Option<(LanguageModelProviderId, Task<()>)>,
configuration_subscription: Option<Subscription>,
@@ -99,10 +100,11 @@ impl AssistantPanel {
) -> Task<Result<Entity<Self>>> {
cx.spawn(|mut cx| async move {
let slash_commands = Arc::new(SlashCommandWorkingSet::default());
let tools = Arc::new(ToolWorkingSet::default());
let context_store = workspace
.update(&mut cx, |workspace, cx| {
let project = workspace.project().clone();
ContextStore::new(project, prompt_builder.clone(), slash_commands, cx)
ContextStore::new(project, prompt_builder.clone(), slash_commands, tools, cx)
})?
.await?;
@@ -119,9 +121,17 @@ impl AssistantPanel {
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let model_selector_menu_handle = PopoverMenuHandle::default();
let model_summary_editor = cx.new(|cx| Editor::single_line(window, cx));
let context_editor_toolbar =
cx.new(|_| ContextEditorToolbarItem::new(model_summary_editor.clone()));
let context_editor_toolbar = cx.new(|cx| {
ContextEditorToolbarItem::new(
workspace,
model_selector_menu_handle.clone(),
model_summary_editor.clone(),
window,
cx,
)
});
let pane = cx.new(|cx| {
let mut pane = Pane::new(
@@ -129,7 +139,7 @@ impl AssistantPanel {
workspace.project().clone(),
Default::default(),
None,
NewChat.boxed_clone(),
NewContext.boxed_clone(),
window,
cx,
);
@@ -228,12 +238,12 @@ impl AssistantPanel {
IconButton::new("new-chat", IconName::Plus)
.icon_size(IconSize::Small)
.on_click(cx.listener(|_, _, window, cx| {
window.dispatch_action(NewChat.boxed_clone(), cx)
window.dispatch_action(NewContext.boxed_clone(), cx)
}))
.tooltip(move |window, cx| {
Tooltip::for_action_in(
"New Chat",
&NewChat,
&NewContext,
&focus_handle,
window,
cx,
@@ -242,10 +252,10 @@ impl AssistantPanel {
)
.child(
PopoverMenu::new("assistant-panel-popover-menu")
.trigger_with_tooltip(
.trigger(
IconButton::new("menu", IconName::EllipsisVertical)
.icon_size(IconSize::Small),
Tooltip::text("Toggle Assistant Menu"),
.icon_size(IconSize::Small)
.tooltip(Tooltip::text("Toggle Assistant Menu")),
)
.menu(move |window, cx| {
let zoom_label = if _pane.read(cx).is_zoomed() {
@@ -256,7 +266,7 @@ impl AssistantPanel {
let focus_handle = _pane.focus_handle(cx);
Some(ContextMenu::build(window, cx, move |menu, _, _| {
menu.context(focus_handle.clone())
.action("New Chat", Box::new(NewChat))
.action("New Chat", Box::new(NewContext))
.action("History", Box::new(DeployHistory))
.action("Prompt Library", Box::new(DeployPromptLibrary))
.action("Configure", Box::new(ShowConfiguration))
@@ -271,17 +281,7 @@ impl AssistantPanel {
});
pane.toolbar().update(cx, |toolbar, cx| {
toolbar.add_item(context_editor_toolbar.clone(), window, cx);
toolbar.add_item(
cx.new(|cx| {
BufferSearchBar::new(
Some(workspace.project().read(cx).languages().clone()),
window,
cx,
)
}),
window,
cx,
)
toolbar.add_item(cx.new(|cx| BufferSearchBar::new(window, cx)), window, cx)
});
pane
});
@@ -323,6 +323,7 @@ impl AssistantPanel {
languages: workspace.app_state().languages.clone(),
fs: workspace.app_state().fs.clone(),
subscriptions,
model_selector_menu_handle,
model_summary_editor,
authenticate_provider_task: None,
configuration_subscription: None,
@@ -760,7 +761,7 @@ impl AssistantPanel {
pub fn create_new_context(
workspace: &mut Workspace,
_: &NewChat,
_: &NewContext,
window: &mut Window,
cx: &mut Context<Workspace>,
) {
@@ -978,7 +979,7 @@ impl AssistantPanel {
.active_provider()
.map_or(true, |p| p.id() != provider.id())
{
if let Some(model) = provider.default_model(cx) {
if let Some(model) = provider.provided_models(cx).first().cloned() {
update_settings_file::<AssistantSettings>(
this.fs.clone(),
cx,
@@ -1045,6 +1046,15 @@ impl AssistantPanel {
.detach_and_log_err(cx);
}
fn toggle_model_selector(
&mut self,
_: &ToggleModelSelector,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.model_selector_menu_handle.toggle(window, cx);
}
pub(crate) fn active_context_editor(&self, cx: &App) -> Option<Entity<ContextEditor>> {
self.pane
.read(cx)
@@ -1158,10 +1168,7 @@ impl AssistantPanel {
.map_or(false, |provider| provider.is_authenticated(cx))
}
fn authenticate(
&mut self,
cx: &mut Context<Self>,
) -> Option<Task<Result<(), AuthenticateError>>> {
fn authenticate(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
LanguageModelRegistry::read_global(cx)
.active_provider()
.map_or(None, |provider| Some(provider.authenticate(cx)))
@@ -1206,7 +1213,7 @@ impl Render for AssistantPanel {
v_flex()
.key_context("AssistantPanel")
.size_full()
.on_action(cx.listener(|this, _: &NewChat, window, cx| {
.on_action(cx.listener(|this, _: &NewContext, window, cx| {
this.new_context(window, cx);
}))
.on_action(cx.listener(|this, _: &ShowConfiguration, window, cx| {
@@ -1214,6 +1221,7 @@ impl Render for AssistantPanel {
}))
.on_action(cx.listener(AssistantPanel::deploy_history))
.on_action(cx.listener(AssistantPanel::deploy_prompt_library))
.on_action(cx.listener(AssistantPanel::toggle_model_selector))
.child(registrar.size_full().child(self.pane.clone()))
.into_any_element()
}

View File

@@ -30,12 +30,13 @@ use gpui::{
EventEmitter, FocusHandle, Focusable, FontWeight, Global, HighlightStyle, Subscription, Task,
TextStyle, UpdateGlobal, WeakEntity, Window,
};
use language::{line_diff, Buffer, IndentKind, Point, Selection, TransactionId};
use language::{Buffer, IndentKind, Point, Selection, TransactionId};
use language_model::{
report_assistant_event, LanguageModel, LanguageModelRegistry, LanguageModelRequest,
LanguageModelRequestMessage, LanguageModelTextStream, Role,
LanguageModel, LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage,
LanguageModelTextStream, Role,
};
use language_model_selector::{LanguageModelSelector, LanguageModelSelectorPopoverMenu};
use language_models::report_assistant_event;
use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use project::{CodeAction, ProjectTransaction};
@@ -1254,7 +1255,7 @@ impl InlineAssistant {
editor.scroll_manager.set_forbid_vertical_scroll(true);
editor.set_show_scrollbars(false, cx);
editor.set_read_only(true);
editor.set_show_edit_predictions(Some(false), window, cx);
editor.set_show_inline_completions(Some(false), window, cx);
editor.highlight_rows::<DeletedLines>(
Anchor::min()..Anchor::max(),
cx.theme().status().deleted_background,
@@ -1594,23 +1595,22 @@ impl Render for PromptEditor {
IconButton::new("context", IconName::SettingsAlt)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.icon_color(Color::Muted),
move |window, cx| {
Tooltip::with_meta(
format!(
"Using {}",
LanguageModelRegistry::read_global(cx)
.active_model()
.map(|model| model.name().0)
.unwrap_or_else(|| "No model selected".into()),
),
None,
"Change Model",
window,
cx,
)
},
gpui::Corner::TopRight,
.icon_color(Color::Muted)
.tooltip(move |window, cx| {
Tooltip::with_meta(
format!(
"Using {}",
LanguageModelRegistry::read_global(cx)
.active_model()
.map(|model| model.name().0)
.unwrap_or_else(|| "No model selected".into()),
),
None,
"Change Model",
window,
cx,
)
}),
))
.map(|el| {
let CodegenStatus::Error(error) = self.codegen.read(cx).status(cx) else {
@@ -1704,7 +1704,7 @@ impl PromptEditor {
// always show the cursor (even when it isn't focused) because
// typing in one will make what you typed appear in all of them.
editor.set_show_cursor_when_unfocused(true, cx);
editor.set_placeholder_text(Self::placeholder_text(codegen.read(cx), window, cx), cx);
editor.set_placeholder_text(Self::placeholder_text(codegen.read(cx), window), cx);
editor
});
@@ -1783,10 +1783,7 @@ impl PromptEditor {
self.editor = cx.new(|cx| {
let mut editor = Editor::auto_height(Self::MAX_LINES as usize, window, cx);
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
editor.set_placeholder_text(
Self::placeholder_text(self.codegen.read(cx), window, cx),
cx,
);
editor.set_placeholder_text(Self::placeholder_text(self.codegen.read(cx), window), cx);
editor.set_placeholder_text("Add a prompt…", cx);
editor.set_text(prompt, window, cx);
if focus {
@@ -1797,8 +1794,8 @@ impl PromptEditor {
self.subscribe_to_editor(window, cx);
}
fn placeholder_text(codegen: &Codegen, window: &Window, cx: &App) -> String {
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window, cx)
fn placeholder_text(codegen: &Codegen, window: &Window) -> String {
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window)
.map(|keybinding| format!("{keybinding} for context"))
.unwrap_or_default();
@@ -2087,13 +2084,12 @@ impl PromptEditor {
.tooltip({
let focus_handle = self.editor.focus_handle(cx);
move |window, cx| {
cx.new(|cx| {
cx.new(|_| {
let mut tooltip = Tooltip::new("Previous Alternative").key_binding(
KeyBinding::for_action_in(
&CyclePreviousInlineAssist,
&focus_handle,
window,
cx,
),
);
if !disabled && current_index != 0 {
@@ -2130,13 +2126,12 @@ impl PromptEditor {
.tooltip({
let focus_handle = self.editor.focus_handle(cx);
move |window, cx| {
cx.new(|cx| {
cx.new(|_| {
let mut tooltip = Tooltip::new("Next Alternative").key_binding(
KeyBinding::for_action_in(
&CycleNextInlineAssist,
&focus_handle,
window,
cx,
),
);
if !disabled && current_index != total_models - 1 {
@@ -2226,7 +2221,7 @@ impl PromptEditor {
},
font_family: settings.buffer_font.family.clone(),
font_fallbacks: settings.buffer_font.fallbacks.clone(),
font_size: settings.buffer_font_size(cx).into(),
font_size: settings.buffer_font_size.into(),
font_weight: settings.buffer_font.weight,
line_height: relative(settings.buffer_line_height.value()),
..Default::default()
@@ -3015,7 +3010,7 @@ impl CodegenAlternative {
let executor = cx.background_executor().clone();
let message_id = message_id.clone();
let line_based_stream_diff: Task<anyhow::Result<()>> =
cx.background_spawn(async move {
cx.background_executor().spawn(async move {
let mut response_latency = None;
let request_start = Instant::now();
let diff = async {
@@ -3329,7 +3324,8 @@ impl CodegenAlternative {
cx.spawn(|codegen, mut cx| async move {
let (deleted_row_ranges, inserted_row_ranges) = cx
.background_spawn(async move {
.background_executor()
.spawn(async move {
let old_text = old_snapshot
.text_for_range(
Point::new(old_range.start.row, 0)
@@ -3349,29 +3345,52 @@ impl CodegenAlternative {
)
.collect::<String>();
let old_start_row = old_range.start.row;
let new_start_row = new_range.start.row;
let mut old_row = old_range.start.row;
let mut new_row = new_range.start.row;
let batch_diff =
similar::TextDiff::from_lines(old_text.as_str(), new_text.as_str());
let mut deleted_row_ranges: Vec<(Anchor, RangeInclusive<u32>)> = Vec::new();
let mut inserted_row_ranges = Vec::new();
for (old_rows, new_rows) in line_diff(&old_text, &new_text) {
let old_rows = old_start_row + old_rows.start..old_start_row + old_rows.end;
let new_rows = new_start_row + new_rows.start..new_start_row + new_rows.end;
if !old_rows.is_empty() {
deleted_row_ranges.push((
new_snapshot.anchor_before(Point::new(new_rows.start, 0)),
old_rows.start..=old_rows.end - 1,
));
}
if !new_rows.is_empty() {
let start = new_snapshot.anchor_before(Point::new(new_rows.start, 0));
let new_end_row = new_rows.end - 1;
let end = new_snapshot.anchor_before(Point::new(
new_end_row,
new_snapshot.line_len(MultiBufferRow(new_end_row)),
));
inserted_row_ranges.push(start..end);
for change in batch_diff.iter_all_changes() {
let line_count = change.value().lines().count() as u32;
match change.tag() {
similar::ChangeTag::Equal => {
old_row += line_count;
new_row += line_count;
}
similar::ChangeTag::Delete => {
let old_end_row = old_row + line_count - 1;
let new_row = new_snapshot.anchor_before(Point::new(new_row, 0));
if let Some((_, last_deleted_row_range)) =
deleted_row_ranges.last_mut()
{
if *last_deleted_row_range.end() + 1 == old_row {
*last_deleted_row_range =
*last_deleted_row_range.start()..=old_end_row;
} else {
deleted_row_ranges.push((new_row, old_row..=old_end_row));
}
} else {
deleted_row_ranges.push((new_row, old_row..=old_end_row));
}
old_row += line_count;
}
similar::ChangeTag::Insert => {
let new_end_row = new_row + line_count - 1;
let start = new_snapshot.anchor_before(Point::new(new_row, 0));
let end = new_snapshot.anchor_before(Point::new(
new_end_row,
new_snapshot.line_len(MultiBufferRow(new_end_row)),
));
inserted_row_ranges.push(start..end);
new_row += line_count;
}
}
}
(deleted_row_ranges, inserted_row_ranges)
})
.await;

View File

@@ -16,10 +16,10 @@ use gpui::{
};
use language::Buffer;
use language_model::{
report_assistant_event, LanguageModelRegistry, LanguageModelRequest,
LanguageModelRequestMessage, Role,
LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage, Role,
};
use language_model_selector::{LanguageModelSelector, LanguageModelSelectorPopoverMenu};
use language_models::report_assistant_event;
use prompt_library::PromptBuilder;
use settings::{update_settings_file, Settings};
use std::{
@@ -646,23 +646,22 @@ impl Render for PromptEditor {
IconButton::new("context", IconName::SettingsAlt)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.icon_color(Color::Muted),
move |window, cx| {
Tooltip::with_meta(
format!(
"Using {}",
LanguageModelRegistry::read_global(cx)
.active_model()
.map(|model| model.name().0)
.unwrap_or_else(|| "No model selected".into()),
),
None,
"Change Model",
window,
cx,
)
},
gpui::Corner::TopRight,
.icon_color(Color::Muted)
.tooltip(move |window, cx| {
Tooltip::with_meta(
format!(
"Using {}",
LanguageModelRegistry::read_global(cx)
.active_model()
.map(|model| model.name().0)
.unwrap_or_else(|| "No model selected".into()),
),
None,
"Change Model",
window,
cx,
)
}),
))
.children(
if let CodegenStatus::Error(error) = &self.codegen.read(cx).status {
@@ -726,7 +725,7 @@ impl PromptEditor {
cx,
);
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
editor.set_placeholder_text(Self::placeholder_text(window, cx), cx);
editor.set_placeholder_text(Self::placeholder_text(window), cx);
editor
});
@@ -775,8 +774,8 @@ impl PromptEditor {
this
}
fn placeholder_text(window: &Window, cx: &App) -> String {
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window, cx)
fn placeholder_text(window: &Window) -> String {
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window)
.map(|keybinding| format!("{keybinding} for context"))
.unwrap_or_default();
@@ -1049,7 +1048,7 @@ impl PromptEditor {
},
font_family: settings.buffer_font.family.clone(),
font_fallbacks: settings.buffer_font.fallbacks.clone(),
font_size: settings.buffer_font_size(cx).into(),
font_size: settings.buffer_font_size.into(),
font_weight: settings.buffer_font.weight,
line_height: relative(settings.buffer_line_height.value()),
..Default::default()
@@ -1151,7 +1150,7 @@ impl Codegen {
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
let task = cx.background_spawn({
let task = cx.background_executor().spawn({
let message_id = message_id.clone();
let executor = cx.background_executor().clone();
async move {

View File

@@ -46,6 +46,7 @@ itertools.workspace = true
language.workspace = true
language_model.workspace = true
language_model_selector.workspace = true
language_models.workspace = true
log.workspace = true
lsp.workspace = true
markdown.workspace = true
@@ -61,6 +62,7 @@ rope.workspace = true
serde.workspace = true
serde_json.workspace = true
settings.workspace = true
similar.workspace = true
smol.workspace = true
streaming_diff.workspace = true
telemetry_events.workspace = true
@@ -77,10 +79,5 @@ workspace.workspace = true
zed_actions.workspace = true
[dev-dependencies]
editor = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, "features" = ["test-support"] }
language = { workspace = true, "features" = ["test-support"] }
language_model = { workspace = true, "features" = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
rand.workspace = true
indoc.workspace = true

View File

@@ -179,10 +179,11 @@ impl ActiveThread {
let markdown = cx.new(|cx| {
Markdown::new(
text.into(),
text,
markdown_style,
Some(self.language_registry.clone()),
None,
window,
cx,
)
});
@@ -214,7 +215,7 @@ impl ActiveThread {
ThreadEvent::StreamedAssistantText(message_id, text) => {
if let Some(markdown) = self.rendered_messages_by_id.get_mut(&message_id) {
markdown.update(cx, |markdown, cx| {
markdown.append(text, cx);
markdown.append(text, window, cx);
});
}
}

View File

@@ -7,7 +7,6 @@ mod context;
mod context_picker;
mod context_store;
mod context_strip;
mod history_store;
mod inline_assistant;
mod inline_prompt_editor;
mod message_editor;
@@ -41,6 +40,7 @@ actions!(
ToggleModelSelector,
RemoveAllContext,
OpenHistory,
OpenPromptEditorHistory,
OpenConfiguration,
RemoveSelectedThread,
Chat,
@@ -66,7 +66,6 @@ pub fn init(
cx: &mut App,
) {
AssistantSettings::register(cx);
thread_store::init(cx);
assistant_panel::init(cx);
inline_assistant::init(

View File

@@ -3,7 +3,7 @@ use std::sync::Arc;
use collections::HashMap;
use gpui::{AnyView, App, EventEmitter, FocusHandle, Focusable, Subscription};
use language_model::{LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry};
use ui::{prelude::*, Divider, DividerColor, ElevationIndex};
use ui::{prelude::*, ElevationIndex};
use zed_actions::assistant::DeployPromptLibrary;
pub struct AssistantConfiguration {
@@ -91,47 +91,38 @@ impl AssistantConfiguration {
.cloned();
v_flex()
.gap_1p5()
.gap_2()
.child(
h_flex()
.justify_between()
.child(
h_flex()
.gap_2()
.child(
Icon::new(provider.icon())
.size(IconSize::Small)
.color(Color::Muted),
)
.child(Label::new(provider_name.clone())),
)
.child(Headline::new(provider_name.clone()).size(HeadlineSize::Small))
.when(provider.is_authenticated(cx), |parent| {
parent.child(
Button::new(
SharedString::from(format!("new-thread-{provider_id}")),
"Start New Thread",
)
.icon_position(IconPosition::Start)
.icon(IconName::Plus)
.icon_size(IconSize::Small)
.style(ButtonStyle::Filled)
.layer(ElevationIndex::ModalSurface)
.label_size(LabelSize::Small)
.on_click(cx.listener({
let provider = provider.clone();
move |_this, _event, _window, cx| {
cx.emit(AssistantConfigurationEvent::NewThread(
provider.clone(),
))
}
})),
h_flex().justify_end().child(
Button::new(
SharedString::from(format!("new-thread-{provider_id}")),
"Open New Thread",
)
.icon_position(IconPosition::Start)
.icon(IconName::Plus)
.style(ButtonStyle::Filled)
.layer(ElevationIndex::ModalSurface)
.on_click(cx.listener({
let provider = provider.clone();
move |_this, _event, _window, cx| {
cx.emit(AssistantConfigurationEvent::NewThread(
provider.clone(),
))
}
})),
),
)
}),
)
.child(
div()
.p(DynamicSpacing::Base08.rems(cx))
.bg(cx.theme().colors().editor_background)
.bg(cx.theme().colors().surface_background)
.border_1()
.border_color(cx.theme().colors().border_variant)
.rounded_md()
@@ -152,43 +143,26 @@ impl Render for AssistantConfiguration {
v_flex()
.id("assistant-configuration")
.track_focus(&self.focus_handle(cx))
.bg(cx.theme().colors().panel_background)
.bg(cx.theme().colors().editor_background)
.size_full()
.overflow_y_scroll()
.child(
v_flex()
.p(DynamicSpacing::Base16.rems(cx))
.gap_1()
.child(Headline::new("Prompt Library").size(HeadlineSize::Small))
.child(
Button::new("open-prompt-library", "Open Prompt Library")
.style(ButtonStyle::Filled)
.layer(ElevationIndex::ModalSurface)
.full_width()
.icon(IconName::Book)
.icon_size(IconSize::Small)
.icon_position(IconPosition::Start)
.on_click(|_event, _window, cx| {
cx.dispatch_action(&DeployPromptLibrary)
}),
),
h_flex().p(DynamicSpacing::Base16.rems(cx)).child(
Button::new("open-prompt-library", "Open Prompt Library")
.style(ButtonStyle::Filled)
.full_width()
.icon(IconName::Book)
.icon_size(IconSize::Small)
.icon_position(IconPosition::Start)
.on_click(|_event, _window, cx| cx.dispatch_action(&DeployPromptLibrary)),
),
)
.child(Divider::horizontal().color(DividerColor::Border))
.child(
v_flex()
.p(DynamicSpacing::Base16.rems(cx))
.mt_1()
.gap_6()
.flex_1()
.child(
v_flex()
.gap_0p5()
.child(Headline::new("LLM Providers").size(HeadlineSize::Small))
.child(
Label::new("Add at least one provider to use AI-powered features.")
.color(Color::Muted),
),
)
.children(
providers
.into_iter()

View File

@@ -61,26 +61,29 @@ impl Render for AssistantModelSelector {
h_flex()
.gap_0p5()
.child(
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted),
div().max_w_32().child(
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted)
.text_ellipsis()
.into_any_element(),
),
)
.child(
Icon::new(IconName::ChevronDown)
.color(Color::Muted)
.size(IconSize::XSmall),
),
),
move |window, cx| {
Tooltip::for_action_in(
"Change Model",
&ToggleModelSelector,
&focus_handle,
window,
cx,
)
},
gpui::Corner::BottomRight,
.tooltip(move |window, cx| {
Tooltip::for_action_in(
"Change Model",
&ToggleModelSelector,
&focus_handle,
window,
cx,
)
}),
)
.with_handle(self.menu_handle.clone())
}

View File

@@ -3,8 +3,8 @@ use std::sync::Arc;
use anyhow::{anyhow, Result};
use assistant_context_editor::{
make_lsp_adapter_delegate, render_remaining_tokens, AssistantPanelDelegate, ConfigurationError,
ContextEditor, SlashCommandCompletionProvider,
make_lsp_adapter_delegate, AssistantPanelDelegate, ConfigurationError, ContextEditor,
ContextHistory, SlashCommandCompletionProvider,
};
use assistant_settings::{AssistantDockPosition, AssistantSettings};
use assistant_slash_command::SlashCommandWorkingSet;
@@ -31,12 +31,14 @@ use zed_actions::assistant::{DeployPromptLibrary, ToggleFocus};
use crate::active_thread::ActiveThread;
use crate::assistant_configuration::{AssistantConfiguration, AssistantConfigurationEvent};
use crate::history_store::{HistoryEntry, HistoryStore};
use crate::message_editor::MessageEditor;
use crate::thread::{Thread, ThreadError, ThreadId};
use crate::thread_history::{PastContext, PastThread, ThreadHistory};
use crate::thread_history::{PastThread, ThreadHistory};
use crate::thread_store::ThreadStore;
use crate::{InlineAssistant, NewPromptEditor, NewThread, OpenConfiguration, OpenHistory};
use crate::{
InlineAssistant, NewPromptEditor, NewThread, OpenConfiguration, OpenHistory,
OpenPromptEditorHistory,
};
pub fn init(cx: &mut App) {
cx.observe_new(
@@ -60,6 +62,12 @@ pub fn init(cx: &mut App) {
panel.update(cx, |panel, cx| panel.new_prompt_editor(window, cx));
}
})
.register_action(|workspace, _: &OpenPromptEditorHistory, window, cx| {
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
workspace.focus_panel::<AssistantPanel>(window, cx);
panel.update(cx, |panel, cx| panel.open_prompt_editor_history(window, cx));
}
})
.register_action(|workspace, _: &OpenConfiguration, window, cx| {
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
workspace.focus_panel::<AssistantPanel>(window, cx);
@@ -75,6 +83,7 @@ enum ActiveView {
Thread,
PromptEditor,
History,
PromptEditorHistory,
Configuration,
}
@@ -88,14 +97,15 @@ pub struct AssistantPanel {
message_editor: Entity<MessageEditor>,
context_store: Entity<assistant_context_editor::ContextStore>,
context_editor: Option<Entity<ContextEditor>>,
context_history: Option<Entity<ContextHistory>>,
configuration: Option<Entity<AssistantConfiguration>>,
configuration_subscription: Option<Subscription>,
tools: Arc<ToolWorkingSet>,
local_timezone: UtcOffset,
active_view: ActiveView,
history_store: Entity<HistoryStore>,
history: Entity<ThreadHistory>,
new_item_context_menu_handle: PopoverMenuHandle<ContextMenu>,
open_history_context_menu_handle: PopoverMenuHandle<ContextMenu>,
width: Option<Pixels>,
height: Option<Pixels>,
}
@@ -124,6 +134,7 @@ impl AssistantPanel {
project,
prompt_builder.clone(),
slash_commands,
tools.clone(),
cx,
)
})?
@@ -163,9 +174,6 @@ impl AssistantPanel {
)
});
let history_store =
cx.new(|cx| HistoryStore::new(thread_store.clone(), context_store.clone(), cx));
Self {
active_view: ActiveView::Thread,
workspace: workspace.clone(),
@@ -187,6 +195,7 @@ impl AssistantPanel {
message_editor,
context_store,
context_editor: None,
context_history: None,
configuration: None,
configuration_subscription: None,
tools,
@@ -194,9 +203,9 @@ impl AssistantPanel {
chrono::Local::now().offset().local_minus_utc(),
)
.unwrap(),
history_store: history_store.clone(),
history: cx.new(|cx| ThreadHistory::new(weak_self, history_store, cx)),
history: cx.new(|cx| ThreadHistory::new(weak_self, thread_store, cx)),
new_item_context_menu_handle: PopoverMenuHandle::default(),
open_history_context_menu_handle: PopoverMenuHandle::default(),
width: None,
height: None,
}
@@ -315,15 +324,31 @@ impl AssistantPanel {
}
fn open_history(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.thread_store
.update(cx, |thread_store, cx| thread_store.reload(cx))
.detach_and_log_err(cx);
self.active_view = ActiveView::History;
self.history.focus_handle(cx).focus(window);
cx.notify();
}
pub(crate) fn open_saved_prompt_editor(
fn open_prompt_editor_history(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.active_view = ActiveView::PromptEditorHistory;
self.context_history = Some(cx.new(|cx| {
ContextHistory::new(
self.project.clone(),
self.context_store.clone(),
self.workspace.clone(),
window,
cx,
)
}));
if let Some(context_history) = self.context_history.as_ref() {
context_history.focus_handle(cx).focus(window);
}
cx.notify();
}
fn open_saved_prompt_editor(
&mut self,
path: PathBuf,
window: &mut Window,
@@ -418,7 +443,7 @@ impl AssistantPanel {
fn handle_assistant_configuration_event(
&mut self,
_entity: &Entity<AssistantConfiguration>,
_model: &Entity<AssistantConfiguration>,
event: &AssistantConfigurationEvent,
window: &mut Window,
cx: &mut Context<Self>,
@@ -431,7 +456,7 @@ impl AssistantPanel {
active_provider.id() != provider.id()
})
{
if let Some(model) = provider.default_model(cx) {
if let Some(model) = provider.provided_models(cx).first().cloned() {
update_settings_file::<AssistantSettings>(
self.fs.clone(),
cx,
@@ -454,10 +479,6 @@ impl AssistantPanel {
.update(cx, |this, cx| this.delete_thread(thread_id, cx))
.detach_and_log_err(cx);
}
pub(crate) fn active_context_editor(&self) -> Option<Entity<ContextEditor>> {
self.context_editor.clone()
}
}
impl Focusable for AssistantPanel {
@@ -472,6 +493,13 @@ impl Focusable for AssistantPanel {
cx.focus_handle()
}
}
ActiveView::PromptEditorHistory => {
if let Some(context_history) = self.context_history.as_ref() {
context_history.focus_handle(cx)
} else {
cx.focus_handle()
}
}
ActiveView::Configuration => {
if let Some(configuration) = self.configuration.as_ref() {
configuration.focus_handle(cx)
@@ -584,8 +612,16 @@ impl AssistantPanel {
SharedString::from(context_editor.read(cx).title(cx).to_string())
})
.unwrap_or_else(|| SharedString::from("Loading Summary…")),
ActiveView::History => "History".into(),
ActiveView::Configuration => "Assistant Settings".into(),
ActiveView::History | ActiveView::PromptEditorHistory => "History".into(),
ActiveView::Configuration => "Configuration".into(),
};
let sub_title = match self.active_view {
ActiveView::Thread => None,
ActiveView::PromptEditor => None,
ActiveView::History => Some("Thread"),
ActiveView::PromptEditorHistory => Some("Prompt Editor"),
ActiveView::Configuration => None,
};
h_flex()
@@ -600,16 +636,20 @@ impl AssistantPanel {
.border_color(cx.theme().colors().border)
.child(
h_flex()
.w_full()
.gap_1()
.justify_between()
.child(Label::new(title))
.children(if matches!(self.active_view, ActiveView::PromptEditor) {
self.context_editor
.as_ref()
.and_then(|editor| render_remaining_tokens(editor, cx))
} else {
None
.when(sub_title.is_some(), |this| {
this.child(
h_flex()
.pl_1p5()
.gap_1p5()
.child(
Label::new("/")
.size(LabelSize::Small)
.color(Color::Disabled)
.alpha(0.5),
)
.child(Label::new(sub_title.unwrap())),
)
}),
)
.child(
@@ -621,11 +661,11 @@ impl AssistantPanel {
.gap(DynamicSpacing::Base02.rems(cx))
.child(
PopoverMenu::new("assistant-toolbar-new-popover-menu")
.trigger_with_tooltip(
.trigger(
IconButton::new("new", IconName::Plus)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle),
Tooltip::text("New…"),
.style(ButtonStyle::Subtle)
.tooltip(Tooltip::text("New…")),
)
.anchor(Corner::TopRight)
.with_handle(self.new_item_context_menu_handle.clone())
@@ -637,30 +677,30 @@ impl AssistantPanel {
}),
)
.child(
IconButton::new("open-history", IconName::HistoryRerun)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle)
.tooltip({
let focus_handle = self.focus_handle(cx);
move |window, cx| {
Tooltip::for_action_in(
"History",
&OpenHistory,
&focus_handle,
window,
cx,
)
}
})
.on_click(move |_event, window, cx| {
window.dispatch_action(OpenHistory.boxed_clone(), cx);
PopoverMenu::new("assistant-toolbar-history-popover-menu")
.trigger(
IconButton::new("open-history", IconName::HistoryRerun)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle)
.tooltip(Tooltip::text("History…")),
)
.anchor(Corner::TopRight)
.with_handle(self.open_history_context_menu_handle.clone())
.menu(move |window, cx| {
Some(ContextMenu::build(window, cx, |menu, _window, _cx| {
menu.action("Thread History", OpenHistory.boxed_clone())
.action(
"Prompt Editor History",
OpenPromptEditorHistory.boxed_clone(),
)
}))
}),
)
.child(
IconButton::new("configure-assistant", IconName::Settings)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle)
.tooltip(Tooltip::text("Assistant Settings"))
.tooltip(Tooltip::text("Configure Assistant"))
.on_click(move |_event, window, cx| {
window.dispatch_action(OpenConfiguration.boxed_clone(), cx);
}),
@@ -703,9 +743,9 @@ impl AssistantPanel {
window: &mut Window,
cx: &mut Context<Self>,
) -> impl IntoElement {
let recent_history = self
.history_store
.update(cx, |this, cx| this.recent_entries(3, cx));
let recent_threads = self
.thread_store
.update(cx, |this, _cx| this.recent_threads(3));
let create_welcome_heading = || {
h_flex()
@@ -732,8 +772,7 @@ impl AssistantPanel {
)
.map(|parent| {
match configuration_error {
Some(ConfigurationError::ProviderNotAuthenticated)
| Some(ConfigurationError::NoProvider) => {
Some(ConfigurationError::ProviderNotAuthenticated) | Some(ConfigurationError::NoProvider) => {
parent.child(
v_flex()
.gap_0p5()
@@ -760,24 +799,34 @@ impl AssistantPanel {
),
)
}
Some(ConfigurationError::ProviderPendingTermsAcceptance(provider)) => parent
.child(v_flex().gap_0p5().child(create_welcome_heading()).children(
provider.render_accept_terms(
LanguageModelProviderTosView::ThreadEmptyState,
cx,
),
)),
Some(ConfigurationError::ProviderPendingTermsAcceptance(provider)) => {
parent.child(
v_flex()
.gap_0p5()
.child(create_welcome_heading())
.children(provider.render_accept_terms(
LanguageModelProviderTosView::ThreadEmptyState,
cx,
)),
)
}
None => parent,
}
})
.when(recent_history.is_empty() && no_error, |parent| {
parent.child(v_flex().gap_0p5().child(create_welcome_heading()).child(
h_flex().w_full().justify_center().child(
Label::new("Start typing to chat with your codebase").color(Color::Muted),
),
))
})
.when(!recent_history.is_empty(), |parent| {
.when(
recent_threads.is_empty() && no_error,
|parent| {
parent.child(
v_flex().gap_0p5().child(create_welcome_heading()).child(
h_flex().w_full().justify_center().child(
Label::new("Start typing to chat with your codebase")
.color(Color::Muted),
),
),
)
},
)
.when(!recent_threads.is_empty(), |parent| {
parent
.child(
h_flex().w_full().justify_center().child(
@@ -787,18 +836,9 @@ impl AssistantPanel {
),
)
.child(v_flex().mx_auto().w_4_5().gap_2().children(
recent_history.into_iter().map(|entry| {
// TODO: Add keyboard navigation.
match entry {
HistoryEntry::Thread(thread) => {
PastThread::new(thread, cx.entity().downgrade(), false)
.into_any_element()
}
HistoryEntry::Context(context) => {
PastContext::new(context, cx.entity().downgrade(), false)
.into_any_element()
}
}
recent_threads.into_iter().map(|thread| {
// TODO: keyboard navigation
PastThread::new(thread, cx.entity().downgrade(), false)
}),
))
.child(
@@ -810,7 +850,6 @@ impl AssistantPanel {
&OpenHistory,
&self.focus_handle(cx),
window,
cx,
))
.on_click(move |_event, window, cx| {
window.dispatch_action(OpenHistory.boxed_clone(), cx);
@@ -1009,6 +1048,7 @@ impl Render for AssistantPanel {
.children(self.render_last_error(cx)),
ActiveView::History => parent.child(self.history.clone()),
ActiveView::PromptEditor => parent.children(self.context_editor.clone()),
ActiveView::PromptEditorHistory => parent.children(self.context_history.clone()),
ActiveView::Configuration => parent.children(self.configuration.clone()),
})
}

View File

@@ -7,11 +7,12 @@ use collections::HashSet;
use editor::{Anchor, AnchorRangeExt, MultiBuffer, MultiBufferSnapshot, ToOffset as _, ToPoint};
use futures::{channel::mpsc, future::LocalBoxFuture, join, SinkExt, Stream, StreamExt};
use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Subscription, Task};
use language::{line_diff, Buffer, IndentKind, Point, TransactionId};
use language::{Buffer, IndentKind, Point, TransactionId};
use language_model::{
report_assistant_event, LanguageModel, LanguageModelRegistry, LanguageModelRequest,
LanguageModelRequestMessage, LanguageModelTextStream, Role,
LanguageModel, LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage,
LanguageModelTextStream, Role,
};
use language_models::report_assistant_event;
use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use prompt_library::PromptBuilder;
@@ -492,7 +493,7 @@ impl CodegenAlternative {
let executor = cx.background_executor().clone();
let message_id = message_id.clone();
let line_based_stream_diff: Task<anyhow::Result<()>> =
cx.background_spawn(async move {
cx.background_executor().spawn(async move {
let mut response_latency = None;
let request_start = Instant::now();
let diff = async {
@@ -806,7 +807,8 @@ impl CodegenAlternative {
cx.spawn(|codegen, mut cx| async move {
let (deleted_row_ranges, inserted_row_ranges) = cx
.background_spawn(async move {
.background_executor()
.spawn(async move {
let old_text = old_snapshot
.text_for_range(
Point::new(old_range.start.row, 0)
@@ -826,29 +828,52 @@ impl CodegenAlternative {
)
.collect::<String>();
let old_start_row = old_range.start.row;
let new_start_row = new_range.start.row;
let mut old_row = old_range.start.row;
let mut new_row = new_range.start.row;
let batch_diff =
similar::TextDiff::from_lines(old_text.as_str(), new_text.as_str());
let mut deleted_row_ranges: Vec<(Anchor, RangeInclusive<u32>)> = Vec::new();
let mut inserted_row_ranges = Vec::new();
for (old_rows, new_rows) in line_diff(&old_text, &new_text) {
let old_rows = old_start_row + old_rows.start..old_start_row + old_rows.end;
let new_rows = new_start_row + new_rows.start..new_start_row + new_rows.end;
if !old_rows.is_empty() {
deleted_row_ranges.push((
new_snapshot.anchor_before(Point::new(new_rows.start, 0)),
old_rows.start..=old_rows.end - 1,
));
}
if !new_rows.is_empty() {
let start = new_snapshot.anchor_before(Point::new(new_rows.start, 0));
let new_end_row = new_rows.end - 1;
let end = new_snapshot.anchor_before(Point::new(
new_end_row,
new_snapshot.line_len(MultiBufferRow(new_end_row)),
));
inserted_row_ranges.push(start..end);
for change in batch_diff.iter_all_changes() {
let line_count = change.value().lines().count() as u32;
match change.tag() {
similar::ChangeTag::Equal => {
old_row += line_count;
new_row += line_count;
}
similar::ChangeTag::Delete => {
let old_end_row = old_row + line_count - 1;
let new_row = new_snapshot.anchor_before(Point::new(new_row, 0));
if let Some((_, last_deleted_row_range)) =
deleted_row_ranges.last_mut()
{
if *last_deleted_row_range.end() + 1 == old_row {
*last_deleted_row_range =
*last_deleted_row_range.start()..=old_end_row;
} else {
deleted_row_ranges.push((new_row, old_row..=old_end_row));
}
} else {
deleted_row_ranges.push((new_row, old_row..=old_end_row));
}
old_row += line_count;
}
similar::ChangeTag::Insert => {
let new_end_row = new_row + line_count - 1;
let start = new_snapshot.anchor_before(Point::new(new_row, 0));
let end = new_snapshot.anchor_before(Point::new(
new_end_row,
new_snapshot.line_len(MultiBufferRow(new_end_row)),
));
inserted_row_ranges.push(start..end);
new_row += line_count;
}
}
}
(deleted_row_ranges, inserted_row_ranges)
})
.await;

View File

@@ -208,7 +208,8 @@ impl PickerDelegate for FetchContextPickerDelegate {
let confirm_behavior = self.confirm_behavior;
cx.spawn_in(window, |this, mut cx| async move {
let text = cx
.background_spawn(Self::build_message(http_client, url.clone()))
.background_executor()
.spawn(Self::build_message(http_client, url.clone()))
.await?;
this.update_in(&mut cx, |this, window, cx| {

View File

@@ -7,19 +7,19 @@ use std::sync::Arc;
use editor::actions::FoldAt;
use editor::display_map::{Crease, FoldId};
use editor::scroll::Autoscroll;
use editor::{Anchor, AnchorRangeExt, Editor, FoldPlaceholder, ToPoint};
use editor::{Anchor, Editor, FoldPlaceholder, ToPoint};
use file_icons::FileIcons;
use fuzzy::PathMatch;
use gpui::{
AnyElement, App, AppContext, DismissEvent, Empty, Entity, FocusHandle, Focusable, Stateful,
Task, WeakEntity,
AnyElement, App, DismissEvent, Empty, Entity, FocusHandle, Focusable, Stateful, Task,
WeakEntity,
};
use multi_buffer::{MultiBufferPoint, MultiBufferRow};
use picker::{Picker, PickerDelegate};
use project::{PathMatchCandidateSet, ProjectPath, WorktreeId};
use rope::Point;
use text::SelectionGoal;
use ui::{prelude::*, ButtonLike, Disclosure, ListItem, TintColor, Tooltip};
use ui::{prelude::*, ButtonLike, Disclosure, ElevationIndex, ListItem, Tooltip};
use util::ResultExt as _;
use workspace::{notifications::NotifyResultExt, Workspace};
@@ -238,11 +238,11 @@ impl PickerDelegate for FileContextPickerDelegate {
path: mat.path.clone(),
};
let Some(editor_entity) = self.editor.upgrade() else {
let Some(editor) = self.editor.upgrade() else {
return;
};
editor_entity.update(cx, |editor, cx| {
editor.update(cx, |editor, cx| {
editor.transact(window, cx, |editor, window, cx| {
// Move empty selections left by 1 column to select the `@`s, so they get overwritten when we insert.
{
@@ -288,15 +288,8 @@ impl PickerDelegate for FileContextPickerDelegate {
editor.insert("\n", window, cx); // Needed to end the fold
let file_icon = FileIcons::get_icon(&Path::new(&full_path), cx)
.unwrap_or_else(|| SharedString::new(""));
let placeholder = FoldPlaceholder {
render: render_fold_icon_button(
file_icon,
file_name.into(),
editor_entity.downgrade(),
),
render: render_fold_icon_button(IconName::File, file_name.into()),
..Default::default()
};
@@ -466,66 +459,15 @@ pub fn render_file_context_entry(
}
fn render_fold_icon_button(
icon: SharedString,
icon: IconName,
label: SharedString,
editor: WeakEntity<Editor>,
) -> Arc<dyn Send + Sync + Fn(FoldId, Range<Anchor>, &mut App) -> AnyElement> {
Arc::new(move |fold_id, fold_range, cx| {
let is_in_text_selection = editor.upgrade().is_some_and(|editor| {
editor.update(cx, |editor, cx| {
let snapshot = editor
.buffer()
.update(cx, |multi_buffer, cx| multi_buffer.snapshot(cx));
let is_in_pending_selection = || {
editor
.selections
.pending
.as_ref()
.is_some_and(|pending_selection| {
pending_selection
.selection
.range()
.includes(&fold_range, &snapshot)
})
};
let mut is_in_complete_selection = || {
editor
.selections
.disjoint_in_range::<usize>(fold_range.clone(), cx)
.into_iter()
.any(|selection| {
// This is needed to cover a corner case, if we just check for an existing
// selection in the fold range, having a cursor at the start of the fold
// marks it as selected. Non-empty selections don't cause this.
let length = selection.end - selection.start;
length > 0
})
};
is_in_pending_selection() || is_in_complete_selection()
})
});
) -> Arc<dyn Send + Sync + Fn(FoldId, Range<Anchor>, &mut Window, &mut App) -> AnyElement> {
Arc::new(move |fold_id, _fold_range, _window, _cx| {
ButtonLike::new(fold_id)
.style(ButtonStyle::Filled)
.selected_style(ButtonStyle::Tinted(TintColor::Accent))
.toggle_state(is_in_text_selection)
.child(
h_flex()
.gap_1()
.child(
Icon::from_path(icon.clone())
.size(IconSize::Small)
.color(Color::Muted),
)
.child(
Label::new(label.clone())
.size(LabelSize::Small)
.single_line(),
),
)
.layer(ElevationIndex::ElevatedSurface)
.child(Icon::new(icon))
.child(Label::new(label.clone()).single_line())
.into_any_element()
})
}

View File

@@ -123,7 +123,7 @@ impl PickerDelegate for ThreadContextPickerDelegate {
};
let executor = cx.background_executor().clone();
let search_task = cx.background_spawn(async move {
let search_task = cx.background_executor().spawn(async move {
if query.is_empty() {
threads
} else {

View File

@@ -4,7 +4,7 @@ use std::sync::Arc;
use anyhow::{anyhow, bail, Result};
use collections::{BTreeMap, HashMap, HashSet};
use futures::{self, future, Future, FutureExt};
use gpui::{App, AppContext as _, AsyncApp, Context, Entity, SharedString, Task, WeakEntity};
use gpui::{App, AsyncApp, Context, Entity, SharedString, Task, WeakEntity};
use language::Buffer;
use project::{ProjectPath, Worktree};
use rope::Rope;
@@ -79,8 +79,8 @@ impl ContextStore {
project.open_buffer(project_path.clone(), cx)
})?;
let buffer_entity = open_buffer_task.await?;
let buffer_id = this.update(&mut cx, |_, cx| buffer_entity.read(cx).remote_id())?;
let buffer_model = open_buffer_task.await?;
let buffer_id = this.update(&mut cx, |_, cx| buffer_model.read(cx).remote_id())?;
let already_included = this.update(&mut cx, |this, _cx| {
match this.will_include_buffer(buffer_id, &project_path.path) {
@@ -98,10 +98,10 @@ impl ContextStore {
}
let (buffer_info, text_task) = this.update(&mut cx, |_, cx| {
let buffer = buffer_entity.read(cx);
let buffer = buffer_model.read(cx);
collect_buffer_info_and_text(
project_path.path.clone(),
buffer_entity,
buffer_model,
buffer,
cx.to_async(),
)
@@ -119,18 +119,18 @@ impl ContextStore {
pub fn add_file_from_buffer(
&mut self,
buffer_entity: Entity<Buffer>,
buffer_model: Entity<Buffer>,
cx: &mut Context<Self>,
) -> Task<Result<()>> {
cx.spawn(|this, mut cx| async move {
let (buffer_info, text_task) = this.update(&mut cx, |_, cx| {
let buffer = buffer_entity.read(cx);
let buffer = buffer_model.read(cx);
let Some(file) = buffer.file() else {
return Err(anyhow!("Buffer has no path."));
};
Ok(collect_buffer_info_and_text(
file.path().clone(),
buffer_entity,
buffer_model,
buffer,
cx.to_async(),
))
@@ -207,11 +207,11 @@ impl ContextStore {
let mut buffer_infos = Vec::new();
let mut text_tasks = Vec::new();
this.update(&mut cx, |_, cx| {
for (path, buffer_entity) in files.into_iter().zip(buffers) {
let buffer_entity = buffer_entity?;
let buffer = buffer_entity.read(cx);
for (path, buffer_model) in files.into_iter().zip(buffers) {
let buffer_model = buffer_model?;
let buffer = buffer_model.read(cx);
let (buffer_info, text_task) =
collect_buffer_info_and_text(path, buffer_entity, buffer, cx.to_async());
collect_buffer_info_and_text(path, buffer_model, buffer, cx.to_async());
buffer_infos.push(buffer_info);
text_tasks.push(text_task);
}
@@ -429,7 +429,7 @@ pub enum FileInclusion {
// ContextBuffer without text.
struct BufferInfo {
buffer_entity: Entity<Buffer>,
buffer_model: Entity<Buffer>,
id: BufferId,
version: clock::Global,
}
@@ -437,7 +437,7 @@ struct BufferInfo {
fn make_context_buffer(info: BufferInfo, text: SharedString) -> ContextBuffer {
ContextBuffer {
id: info.id,
buffer: info.buffer_entity,
buffer: info.buffer_model,
version: info.version,
text,
}
@@ -445,18 +445,20 @@ fn make_context_buffer(info: BufferInfo, text: SharedString) -> ContextBuffer {
fn collect_buffer_info_and_text(
path: Arc<Path>,
buffer_entity: Entity<Buffer>,
buffer_model: Entity<Buffer>,
buffer: &Buffer,
cx: AsyncApp,
) -> (BufferInfo, Task<SharedString>) {
let buffer_info = BufferInfo {
id: buffer.remote_id(),
buffer_entity,
buffer_model,
version: buffer.version(),
};
// Important to collect version at the same time as content so that staleness logic is correct.
let content = buffer.as_rope().clone();
let text_task = cx.background_spawn(async move { to_fenced_codeblock(&path, content) });
let text_task = cx
.background_executor()
.spawn(async move { to_fenced_codeblock(&path, content) });
(buffer_info, text_task)
}

View File

@@ -92,8 +92,8 @@ impl ContextStrip {
let active_item = workspace.read(cx).active_item(cx)?;
let editor = active_item.to_any().downcast::<Editor>().ok()?.read(cx);
let active_buffer_entity = editor.buffer().read(cx).as_singleton()?;
let active_buffer = active_buffer_entity.read(cx);
let active_buffer_model = editor.buffer().read(cx).as_singleton()?;
let active_buffer = active_buffer_model.read(cx);
let path = active_buffer.file()?.path();
@@ -115,7 +115,7 @@ impl ContextStrip {
Some(SuggestedContext::File {
name,
buffer: active_buffer_entity.downgrade(),
buffer: active_buffer_model.downgrade(),
icon_path,
})
}
@@ -393,9 +393,9 @@ impl Render for ContextStrip {
.on_action(cx.listener(Self::remove_focused_context))
.on_action(cx.listener(Self::accept_suggested_context))
.on_children_prepainted({
let entity = cx.entity().downgrade();
let model = cx.entity().downgrade();
move |children_bounds, _window, cx| {
entity
model
.update(cx, |this, _| {
this.children_bounds = Some(children_bounds);
})
@@ -411,22 +411,22 @@ impl Render for ContextStrip {
Some(context_picker.clone())
})
.trigger_with_tooltip(
.trigger(
IconButton::new("add-context", IconName::Plus)
.icon_size(IconSize::Small)
.style(ui::ButtonStyle::Filled),
{
let focus_handle = focus_handle.clone();
move |window, cx| {
Tooltip::for_action_in(
"Add Context",
&ToggleContextPicker,
&focus_handle,
window,
cx,
)
}
},
.style(ui::ButtonStyle::Filled)
.tooltip({
let focus_handle = focus_handle.clone();
move |window, cx| {
Tooltip::for_action_in(
"Add Context",
&ToggleContextPicker,
&focus_handle,
window,
cx,
)
}
}),
)
.attach(gpui::Corner::TopLeft)
.anchor(gpui::Corner::BottomLeft)
@@ -453,7 +453,6 @@ impl Render for ContextStrip {
&ToggleContextPicker,
&focus_handle,
window,
cx,
)
.map(|binding| binding.into_any_element()),
),

View File

@@ -1,61 +0,0 @@
use assistant_context_editor::SavedContextMetadata;
use chrono::{DateTime, Utc};
use gpui::{prelude::*, Entity};
use crate::thread_store::{SavedThreadMetadata, ThreadStore};
pub enum HistoryEntry {
Thread(SavedThreadMetadata),
Context(SavedContextMetadata),
}
impl HistoryEntry {
pub fn updated_at(&self) -> DateTime<Utc> {
match self {
HistoryEntry::Thread(thread) => thread.updated_at,
HistoryEntry::Context(context) => context.mtime.to_utc(),
}
}
}
pub struct HistoryStore {
thread_store: Entity<ThreadStore>,
context_store: Entity<assistant_context_editor::ContextStore>,
}
impl HistoryStore {
pub fn new(
thread_store: Entity<ThreadStore>,
context_store: Entity<assistant_context_editor::ContextStore>,
_cx: &mut Context<Self>,
) -> Self {
Self {
thread_store,
context_store,
}
}
/// Returns the number of history entries.
pub fn entry_count(&self, cx: &mut Context<Self>) -> usize {
self.entries(cx).len()
}
pub fn entries(&self, cx: &mut Context<Self>) -> Vec<HistoryEntry> {
let mut history_entries = Vec::new();
for thread in self.thread_store.update(cx, |this, _cx| this.threads()) {
history_entries.push(HistoryEntry::Thread(thread));
}
for context in self.context_store.update(cx, |this, _cx| this.contexts()) {
history_entries.push(HistoryEntry::Context(context));
}
history_entries.sort_unstable_by_key(|entry| std::cmp::Reverse(entry.updated_at()));
history_entries
}
pub fn recent_entries(&self, limit: usize, cx: &mut Context<Self>) -> Vec<HistoryEntry> {
self.entries(cx).into_iter().take(limit).collect()
}
}

View File

@@ -24,7 +24,8 @@ use gpui::{
UpdateGlobal, WeakEntity, Window,
};
use language::{Buffer, Point, Selection, TransactionId};
use language_model::{report_assistant_event, LanguageModelRegistry};
use language_model::LanguageModelRegistry;
use language_models::report_assistant_event;
use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use project::{CodeAction, ProjectTransaction};
@@ -227,12 +228,8 @@ impl InlineAssistant {
return;
}
let Some(inline_assist_target) = Self::resolve_inline_assist_target(
workspace,
workspace.panel::<AssistantPanel>(cx),
window,
cx,
) else {
let Some(inline_assist_target) = Self::resolve_inline_assist_target(workspace, window, cx)
else {
return;
};
@@ -1348,7 +1345,7 @@ impl InlineAssistant {
editor.scroll_manager.set_forbid_vertical_scroll(true);
editor.set_show_scrollbars(false, cx);
editor.set_read_only(true);
editor.set_show_edit_predictions(Some(false), window, cx);
editor.set_show_inline_completions(Some(false), window, cx);
editor.highlight_rows::<DeletedLines>(
Anchor::min()..Anchor::max(),
cx.theme().status().deleted_background,
@@ -1387,7 +1384,6 @@ impl InlineAssistant {
fn resolve_inline_assist_target(
workspace: &mut Workspace,
assistant_panel: Option<Entity<AssistantPanel>>,
window: &mut Window,
cx: &mut App,
) -> Option<InlineAssistTarget> {
@@ -1407,20 +1403,7 @@ impl InlineAssistant {
}
}
let context_editor = assistant_panel
.and_then(|panel| panel.read(cx).active_context_editor())
.and_then(|editor| {
let editor = &editor.read(cx).editor().clone();
if editor.read(cx).is_focused(window) {
Some(editor.clone())
} else {
None
}
});
if let Some(context_editor) = context_editor {
Some(InlineAssistTarget::Editor(context_editor))
} else if let Some(workspace_editor) = workspace
if let Some(workspace_editor) = workspace
.active_item(cx)
.and_then(|item| item.act_as::<Editor>(cx))
{

View File

@@ -56,7 +56,7 @@ impl<T: 'static> EventEmitter<PromptEditorEvent> for PromptEditor<T> {}
impl<T: 'static> Render for PromptEditor<T> {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let ui_font_size = ThemeSettings::get_global(cx).ui_font_size(cx);
let ui_font_size = ThemeSettings::get_global(cx).ui_font_size;
let mut buttons = Vec::new();
let left_gutter_width = match &self.mode {
@@ -271,7 +271,7 @@ impl<T: 'static> PromptEditor<T> {
};
let assistant_panel_keybinding =
ui::text_for_action(&zed_actions::assistant::ToggleFocus, window, cx)
ui::text_for_action(&zed_actions::assistant::ToggleFocus, window)
.map(|keybinding| format!("{keybinding} to chat ― "))
.unwrap_or_default();
@@ -618,13 +618,12 @@ impl<T: 'static> PromptEditor<T> {
.tooltip({
let focus_handle = self.editor.focus_handle(cx);
move |window, cx| {
cx.new(|cx| {
cx.new(|_| {
let mut tooltip = Tooltip::new("Previous Alternative").key_binding(
KeyBinding::for_action_in(
&CyclePreviousInlineAssist,
&focus_handle,
window,
cx,
),
);
if !disabled && current_index != 0 {
@@ -660,13 +659,12 @@ impl<T: 'static> PromptEditor<T> {
.tooltip({
let focus_handle = self.editor.focus_handle(cx);
move |window, cx| {
cx.new(|cx| {
cx.new(|_| {
let mut tooltip = Tooltip::new("Next Alternative").key_binding(
KeyBinding::for_action_in(
&CycleNextInlineAssist,
&focus_handle,
window,
cx,
),
);
if !disabled && current_index != total_models - 1 {

View File

@@ -12,7 +12,6 @@ use language_model_selector::LanguageModelSelector;
use rope::Point;
use settings::Settings;
use std::time::Duration;
use text::Bias;
use theme::ThemeSettings;
use ui::{
prelude::*, ButtonLike, KeyBinding, PopoverMenu, PopoverMenuHandle, Switch, TintColor, Tooltip,
@@ -240,10 +239,7 @@ impl MessageEditor {
let snapshot = editor.buffer().read(cx).snapshot(cx);
let newest_cursor = editor.selections.newest::<Point>(cx).head();
if newest_cursor.column > 0 {
let behind_cursor = snapshot.clip_point(
Point::new(newest_cursor.row, newest_cursor.column - 1),
Bias::Left,
);
let behind_cursor = Point::new(newest_cursor.row, newest_cursor.column - 1);
let char_behind_cursor = snapshot.chars_at(behind_cursor).next();
if char_behind_cursor == Some('@') {
self.inline_context_picker_menu_handle.show(window, cx);
@@ -369,7 +365,11 @@ impl Render for MessageEditor {
.anchor(gpui::Corner::BottomLeft)
.offset(gpui::Point {
x: px(0.0),
y: (-ThemeSettings::get_global(cx).ui_font_size(cx) * 2) - px(4.0),
y: px(-ThemeSettings::clamp_font_size(
ThemeSettings::get_global(cx).ui_font_size,
)
.0 * 2.0)
- px(4.0),
})
.with_handle(self.inline_context_picker_menu_handle.clone()),
)
@@ -390,7 +390,6 @@ impl Render for MessageEditor {
&ChatMode,
&focus_handle,
window,
cx,
)),
)
.child(h_flex().gap_1().child(self.model_selector.clone()).child(
@@ -420,7 +419,6 @@ impl Render for MessageEditor {
&editor::actions::Cancel,
&focus_handle,
window,
cx,
)
.map(|binding| binding.into_any_element()),
),
@@ -451,7 +449,6 @@ impl Render for MessageEditor {
&Chat,
&focus_handle,
window,
cx,
)
.map(|binding| binding.into_any_element()),
),

View File

@@ -1,8 +1,9 @@
use crate::inline_prompt_editor::CodegenStatus;
use client::telemetry::Telemetry;
use futures::{channel::mpsc, SinkExt, StreamExt};
use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Task};
use language_model::{report_assistant_event, LanguageModelRegistry, LanguageModelRequest};
use gpui::{App, Context, Entity, EventEmitter, Task};
use language_model::{LanguageModelRegistry, LanguageModelRequest};
use language_models::report_assistant_event;
use std::{sync::Arc, time::Instant};
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
use terminal::Terminal;
@@ -52,7 +53,7 @@ impl TerminalCodegen {
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
let task = cx.background_spawn({
let task = cx.background_executor().spawn({
let message_id = message_id.clone();
let executor = cx.background_executor().clone();
async move {

View File

@@ -13,9 +13,9 @@ use fs::Fs;
use gpui::{App, Entity, Focusable, Global, Subscription, UpdateGlobal, WeakEntity};
use language::Buffer;
use language_model::{
report_assistant_event, LanguageModelRegistry, LanguageModelRequest,
LanguageModelRequestMessage, Role,
LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage, Role,
};
use language_models::report_assistant_event;
use prompt_library::PromptBuilder;
use std::sync::Arc;
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};

View File

@@ -10,9 +10,9 @@ use gpui::{App, Context, EventEmitter, SharedString, Task};
use language_model::{
LanguageModel, LanguageModelCompletionEvent, LanguageModelRegistry, LanguageModelRequest,
LanguageModelRequestMessage, LanguageModelToolResult, LanguageModelToolUse,
LanguageModelToolUseId, MaxMonthlySpendReachedError, MessageContent, PaymentRequiredError,
Role, StopReason,
LanguageModelToolUseId, MessageContent, Role, StopReason,
};
use language_models::provider::cloud::{MaxMonthlySpendReachedError, PaymentRequiredError};
use serde::{Deserialize, Serialize};
use util::{post_inc, TryFutureExt as _};
use uuid::Uuid;

View File

@@ -1,4 +1,3 @@
use assistant_context_editor::SavedContextMetadata;
use gpui::{
uniform_list, App, Entity, FocusHandle, Focusable, ScrollStrategy, UniformListScrollHandle,
WeakEntity,
@@ -6,14 +5,13 @@ use gpui::{
use time::{OffsetDateTime, UtcOffset};
use ui::{prelude::*, IconButtonShape, ListItem, ListItemSpacing, Tooltip};
use crate::history_store::{HistoryEntry, HistoryStore};
use crate::thread_store::SavedThreadMetadata;
use crate::thread_store::{SavedThreadMetadata, ThreadStore};
use crate::{AssistantPanel, RemoveSelectedThread};
pub struct ThreadHistory {
focus_handle: FocusHandle,
assistant_panel: WeakEntity<AssistantPanel>,
history_store: Entity<HistoryStore>,
thread_store: Entity<ThreadStore>,
scroll_handle: UniformListScrollHandle,
selected_index: usize,
}
@@ -21,13 +19,14 @@ pub struct ThreadHistory {
impl ThreadHistory {
pub(crate) fn new(
assistant_panel: WeakEntity<AssistantPanel>,
history_store: Entity<HistoryStore>,
thread_store: Entity<ThreadStore>,
cx: &mut Context<Self>,
) -> Self {
Self {
focus_handle: cx.focus_handle(),
assistant_panel,
history_store,
thread_store,
scroll_handle: UniformListScrollHandle::default(),
selected_index: 0,
}
@@ -39,9 +38,7 @@ impl ThreadHistory {
window: &mut Window,
cx: &mut Context<Self>,
) {
let count = self
.history_store
.update(cx, |this, cx| this.entry_count(cx));
let count = self.thread_store.read(cx).thread_count();
if count > 0 {
if self.selected_index == 0 {
self.set_selected_index(count - 1, window, cx);
@@ -57,9 +54,7 @@ impl ThreadHistory {
window: &mut Window,
cx: &mut Context<Self>,
) {
let count = self
.history_store
.update(cx, |this, cx| this.entry_count(cx));
let count = self.thread_store.read(cx).thread_count();
if count > 0 {
if self.selected_index == count - 1 {
self.set_selected_index(0, window, cx);
@@ -70,18 +65,14 @@ impl ThreadHistory {
}
fn select_first(&mut self, _: &menu::SelectFirst, window: &mut Window, cx: &mut Context<Self>) {
let count = self
.history_store
.update(cx, |this, cx| this.entry_count(cx));
let count = self.thread_store.read(cx).thread_count();
if count > 0 {
self.set_selected_index(0, window, cx);
}
}
fn select_last(&mut self, _: &menu::SelectLast, window: &mut Window, cx: &mut Context<Self>) {
let count = self
.history_store
.update(cx, |this, cx| this.entry_count(cx));
let count = self.thread_store.read(cx).thread_count();
if count > 0 {
self.set_selected_index(count - 1, window, cx);
}
@@ -95,23 +86,12 @@ impl ThreadHistory {
}
fn confirm(&mut self, _: &menu::Confirm, window: &mut Window, cx: &mut Context<Self>) {
let entries = self.history_store.update(cx, |this, cx| this.entries(cx));
let threads = self.thread_store.update(cx, |this, _cx| this.threads());
if let Some(entry) = entries.get(self.selected_index) {
match entry {
HistoryEntry::Thread(thread) => {
self.assistant_panel
.update(cx, move |this, cx| this.open_thread(&thread.id, window, cx))
.ok();
}
HistoryEntry::Context(context) => {
self.assistant_panel
.update(cx, move |this, cx| {
this.open_saved_prompt_editor(context.path.clone(), window, cx)
})
.ok();
}
}
if let Some(thread) = threads.get(self.selected_index) {
self.assistant_panel
.update(cx, move |this, cx| this.open_thread(&thread.id, window, cx))
.ok();
cx.notify();
}
@@ -123,19 +103,14 @@ impl ThreadHistory {
_window: &mut Window,
cx: &mut Context<Self>,
) {
let entries = self.history_store.update(cx, |this, cx| this.entries(cx));
let threads = self.thread_store.update(cx, |this, _cx| this.threads());
if let Some(entry) = entries.get(self.selected_index) {
match entry {
HistoryEntry::Thread(thread) => {
self.assistant_panel
.update(cx, |this, cx| {
this.delete_thread(&thread.id, cx);
})
.ok();
}
HistoryEntry::Context(_context) => {}
}
if let Some(thread) = threads.get(self.selected_index) {
self.assistant_panel
.update(cx, |this, cx| {
this.delete_thread(&thread.id, cx);
})
.ok();
cx.notify();
}
@@ -150,7 +125,7 @@ impl Focusable for ThreadHistory {
impl Render for ThreadHistory {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let history_entries = self.history_store.update(cx, |this, cx| this.entries(cx));
let threads = self.thread_store.update(cx, |this, _cx| this.threads());
let selected_index = self.selected_index;
v_flex()
@@ -167,7 +142,7 @@ impl Render for ThreadHistory {
.on_action(cx.listener(Self::confirm))
.on_action(cx.listener(Self::remove_selected_thread))
.map(|history| {
if history_entries.is_empty() {
if threads.is_empty() {
history
.justify_center()
.child(
@@ -181,26 +156,17 @@ impl Render for ThreadHistory {
uniform_list(
cx.entity().clone(),
"thread-history",
history_entries.len(),
threads.len(),
move |history, range, _window, _cx| {
history_entries[range]
threads[range]
.iter()
.enumerate()
.map(|(index, entry)| {
h_flex().w_full().pb_1().child(match entry {
HistoryEntry::Thread(thread) => PastThread::new(
thread.clone(),
history.assistant_panel.clone(),
selected_index == index,
)
.into_any_element(),
HistoryEntry::Context(context) => PastContext::new(
context.clone(),
history.assistant_panel.clone(),
selected_index == index,
)
.into_any_element(),
})
.map(|(index, thread)| {
h_flex().w_full().pb_1().child(PastThread::new(
thread.clone(),
history.assistant_panel.clone(),
selected_index == index,
))
})
.collect()
},
@@ -296,71 +262,3 @@ impl RenderOnce for PastThread {
})
}
}
#[derive(IntoElement)]
pub struct PastContext {
context: SavedContextMetadata,
assistant_panel: WeakEntity<AssistantPanel>,
selected: bool,
}
impl PastContext {
pub fn new(
context: SavedContextMetadata,
assistant_panel: WeakEntity<AssistantPanel>,
selected: bool,
) -> Self {
Self {
context,
assistant_panel,
selected,
}
}
}
impl RenderOnce for PastContext {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let summary = self.context.title;
let context_timestamp = time_format::format_localized_timestamp(
OffsetDateTime::from_unix_timestamp(self.context.mtime.timestamp()).unwrap(),
OffsetDateTime::now_utc(),
self.assistant_panel
.update(cx, |this, _cx| this.local_timezone())
.unwrap_or(UtcOffset::UTC),
time_format::TimestampFormat::EnhancedAbsolute,
);
ListItem::new(SharedString::from(
self.context.path.to_string_lossy().to_string(),
))
.outlined()
.toggle_state(self.selected)
.start_slot(
Icon::new(IconName::Code)
.size(IconSize::Small)
.color(Color::Muted),
)
.spacing(ListItemSpacing::Sparse)
.child(Label::new(summary).size(LabelSize::Small).text_ellipsis())
.end_slot(
h_flex().gap_1p5().child(
Label::new(context_timestamp)
.color(Color::Muted)
.size(LabelSize::XSmall),
),
)
.on_click({
let assistant_panel = self.assistant_panel.clone();
let path = self.context.path.clone();
move |_event, window, cx| {
assistant_panel
.update(cx, |this, cx| {
this.open_saved_prompt_editor(path.clone(), window, cx)
.detach_and_log_err(cx);
})
.ok();
}
})
}
}

View File

@@ -9,9 +9,7 @@ use context_server::manager::ContextServerManager;
use context_server::{ContextServerFactoryRegistry, ContextServerTool};
use futures::future::{self, BoxFuture, Shared};
use futures::FutureExt as _;
use gpui::{
prelude::*, App, BackgroundExecutor, Context, Entity, Global, ReadGlobal, SharedString, Task,
};
use gpui::{prelude::*, App, BackgroundExecutor, Context, Entity, SharedString, Task};
use heed::types::SerdeBincode;
use heed::Database;
use language_model::Role;
@@ -21,10 +19,6 @@ use util::ResultExt as _;
use crate::thread::{MessageId, Thread, ThreadId};
pub fn init(cx: &mut App) {
ThreadsDatabase::init(cx);
}
pub struct ThreadStore {
#[allow(unused)]
project: Entity<Project>,
@@ -32,6 +26,7 @@ pub struct ThreadStore {
context_server_manager: Entity<ContextServerManager>,
context_server_tool_ids: HashMap<Arc<str>, Vec<ToolId>>,
threads: Vec<SavedThreadMetadata>,
database_future: Shared<BoxFuture<'static, Result<Arc<ThreadsDatabase>, Arc<anyhow::Error>>>>,
}
impl ThreadStore {
@@ -46,12 +41,24 @@ impl ThreadStore {
ContextServerManager::new(context_server_factory_registry, project.clone(), cx)
});
let executor = cx.background_executor().clone();
let database_future = executor
.spawn({
let executor = executor.clone();
let database_path = paths::support_dir().join("threads/threads-db.0.mdb");
async move { ThreadsDatabase::new(database_path, executor) }
})
.then(|result| future::ready(result.map(Arc::new).map_err(Arc::new)))
.boxed()
.shared();
let this = Self {
project,
tools,
context_server_manager,
context_server_tool_ids: HashMap::default(),
threads: Vec::new(),
database_future,
};
this.register_context_server_handlers(cx);
this.reload(cx).detach_and_log_err(cx);
@@ -87,7 +94,7 @@ impl ThreadStore {
cx: &mut Context<Self>,
) -> Task<Result<Entity<Thread>>> {
let id = id.clone();
let database_future = ThreadsDatabase::global_future(cx);
let database_future = self.database_future.clone();
cx.spawn(|this, mut cx| async move {
let database = database_future.await.map_err(|err| anyhow!(err))?;
let thread = database
@@ -120,7 +127,7 @@ impl ThreadStore {
(id, thread)
});
let database_future = ThreadsDatabase::global_future(cx);
let database_future = self.database_future.clone();
cx.spawn(|this, mut cx| async move {
let database = database_future.await.map_err(|err| anyhow!(err))?;
database.save_thread(metadata, thread).await?;
@@ -131,7 +138,7 @@ impl ThreadStore {
pub fn delete_thread(&mut self, id: &ThreadId, cx: &mut Context<Self>) -> Task<Result<()>> {
let id = id.clone();
let database_future = ThreadsDatabase::global_future(cx);
let database_future = self.database_future.clone();
cx.spawn(|this, mut cx| async move {
let database = database_future.await.map_err(|err| anyhow!(err))?;
database.delete_thread(id.clone()).await?;
@@ -142,8 +149,8 @@ impl ThreadStore {
})
}
pub fn reload(&self, cx: &mut Context<Self>) -> Task<Result<()>> {
let database_future = ThreadsDatabase::global_future(cx);
fn reload(&self, cx: &mut Context<Self>) -> Task<Result<()>> {
let database_future = self.database_future.clone();
cx.spawn(|this, mut cx| async move {
let threads = database_future
.await
@@ -246,40 +253,13 @@ pub struct SavedMessage {
pub text: String,
}
struct GlobalThreadsDatabase(
Shared<BoxFuture<'static, Result<Arc<ThreadsDatabase>, Arc<anyhow::Error>>>>,
);
impl Global for GlobalThreadsDatabase {}
pub(crate) struct ThreadsDatabase {
struct ThreadsDatabase {
executor: BackgroundExecutor,
env: heed::Env,
threads: Database<SerdeBincode<ThreadId>, SerdeBincode<SavedThread>>,
}
impl ThreadsDatabase {
fn global_future(
cx: &mut App,
) -> Shared<BoxFuture<'static, Result<Arc<ThreadsDatabase>, Arc<anyhow::Error>>>> {
GlobalThreadsDatabase::global(cx).0.clone()
}
fn init(cx: &mut App) {
let executor = cx.background_executor().clone();
let database_future = executor
.spawn({
let executor = executor.clone();
let database_path = paths::support_dir().join("threads/threads-db.0.mdb");
async move { ThreadsDatabase::new(database_path, executor) }
})
.then(|result| future::ready(result.map(Arc::new).map_err(Arc::new)))
.boxed()
.shared();
cx.set_global(GlobalThreadsDatabase(database_future));
}
pub fn new(path: PathBuf, executor: BackgroundExecutor) -> Result<Self> {
std::fs::create_dir_all(&path)?;

View File

@@ -16,12 +16,14 @@ anyhow.workspace = true
assistant_settings.workspace = true
assistant_slash_command.workspace = true
assistant_slash_commands.workspace = true
assistant_tool.workspace = true
chrono.workspace = true
client.workspace = true
clock.workspace = true
collections.workspace = true
context_server.workspace = true
editor.workspace = true
feature_flags.workspace = true
fs.workspace = true
futures.workspace = true
fuzzy.workspace = true
@@ -30,6 +32,7 @@ indexed_docs.workspace = true
language.workspace = true
language_model.workspace = true
language_model_selector.workspace = true
language_models.workspace = true
log.workspace = true
multi_buffer.workspace = true
open_ai.workspace = true

View File

@@ -8,9 +8,11 @@ use assistant_slash_command::{
SlashCommandResult, SlashCommandWorkingSet,
};
use assistant_slash_commands::FileCommandMetadata;
use assistant_tool::ToolWorkingSet;
use client::{self, proto, telemetry::Telemetry};
use clock::ReplicaId;
use collections::{HashMap, HashSet};
use feature_flags::{FeatureFlagAppExt, ToolUseFeatureFlag};
use fs::{Fs, RemoveOptions};
use futures::{future::Shared, FutureExt, StreamExt};
use gpui::{
@@ -19,10 +21,14 @@ use gpui::{
};
use language::{AnchorRangeExt, Bias, Buffer, LanguageRegistry, OffsetRangeExt, Point, ToOffset};
use language_model::{
report_assistant_event, LanguageModel, LanguageModelCacheConfiguration,
LanguageModelCompletionEvent, LanguageModelImage, LanguageModelRegistry, LanguageModelRequest,
LanguageModelRequestMessage, LanguageModelToolUseId, MaxMonthlySpendReachedError,
MessageContent, PaymentRequiredError, Role, StopReason,
LanguageModel, LanguageModelCacheConfiguration, LanguageModelCompletionEvent,
LanguageModelImage, LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage,
LanguageModelRequestTool, LanguageModelToolResult, LanguageModelToolUse,
LanguageModelToolUseId, MessageContent, Role, StopReason,
};
use language_models::{
provider::cloud::{MaxMonthlySpendReachedError, PaymentRequiredError},
report_assistant_event,
};
use open_ai::Model as OpenAiModel;
use paths::contexts_dir;
@@ -432,6 +438,11 @@ pub enum ContextEvent {
SlashCommandOutputSectionAdded {
section: SlashCommandOutputSection<language::Anchor>,
},
UsePendingTools,
ToolFinished {
tool_use_id: LanguageModelToolUseId,
output_range: Range<language::Anchor>,
},
Operation(ContextOperation),
}
@@ -517,12 +528,21 @@ pub enum Content {
render_image: Arc<RenderImage>,
image: Shared<Task<Option<LanguageModelImage>>>,
},
ToolUse {
range: Range<language::Anchor>,
tool_use: LanguageModelToolUse,
},
ToolResult {
range: Range<language::Anchor>,
tool_use_id: LanguageModelToolUseId,
},
}
impl Content {
fn range(&self) -> Range<language::Anchor> {
match self {
Self::Image { anchor, .. } => *anchor..*anchor,
Self::ToolUse { range, .. } | Self::ToolResult { range, .. } => range.clone(),
}
}
@@ -579,7 +599,9 @@ pub struct AssistantContext {
invoked_slash_commands: HashMap<InvokedSlashCommandId, InvokedSlashCommand>,
edits_since_last_parse: language::Subscription,
slash_commands: Arc<SlashCommandWorkingSet>,
tools: Arc<ToolWorkingSet>,
slash_command_output_sections: Vec<SlashCommandOutputSection<language::Anchor>>,
pending_tool_uses_by_id: HashMap<LanguageModelToolUseId, PendingToolUse>,
message_anchors: Vec<MessageAnchor>,
contents: Vec<Content>,
messages_metadata: HashMap<MessageId, MessageMetadata>,
@@ -632,6 +654,7 @@ impl AssistantContext {
telemetry: Option<Arc<Telemetry>>,
prompt_builder: Arc<PromptBuilder>,
slash_commands: Arc<SlashCommandWorkingSet>,
tools: Arc<ToolWorkingSet>,
cx: &mut Context<Self>,
) -> Self {
Self::new(
@@ -641,6 +664,7 @@ impl AssistantContext {
language_registry,
prompt_builder,
slash_commands,
tools,
project,
telemetry,
cx,
@@ -655,6 +679,7 @@ impl AssistantContext {
language_registry: Arc<LanguageRegistry>,
prompt_builder: Arc<PromptBuilder>,
slash_commands: Arc<SlashCommandWorkingSet>,
tools: Arc<ToolWorkingSet>,
project: Option<Entity<Project>>,
telemetry: Option<Arc<Telemetry>>,
cx: &mut Context<Self>,
@@ -682,6 +707,7 @@ impl AssistantContext {
messages_metadata: Default::default(),
parsed_slash_commands: Vec::new(),
invoked_slash_commands: HashMap::default(),
pending_tool_uses_by_id: HashMap::default(),
slash_command_output_sections: Vec::new(),
edits_since_last_parse: edits_since_last_slash_command_parse,
summary: None,
@@ -699,6 +725,7 @@ impl AssistantContext {
project,
language_registry,
slash_commands,
tools,
patches: Vec::new(),
xml_tags: Vec::new(),
prompt_builder,
@@ -775,6 +802,7 @@ impl AssistantContext {
language_registry: Arc<LanguageRegistry>,
prompt_builder: Arc<PromptBuilder>,
slash_commands: Arc<SlashCommandWorkingSet>,
tools: Arc<ToolWorkingSet>,
project: Option<Entity<Project>>,
telemetry: Option<Arc<Telemetry>>,
cx: &mut Context<Self>,
@@ -787,6 +815,7 @@ impl AssistantContext {
language_registry,
prompt_builder,
slash_commands,
tools,
project,
telemetry,
cx,
@@ -819,6 +848,10 @@ impl AssistantContext {
&self.slash_commands
}
pub fn tools(&self) -> &Arc<ToolWorkingSet> {
&self.tools
}
pub fn set_capability(&mut self, capability: language::Capability, cx: &mut Context<Self>) {
self.buffer
.update(cx, |buffer, cx| buffer.set_capability(capability, cx));
@@ -848,7 +881,7 @@ impl AssistantContext {
.collect::<Vec<_>>();
context_ops.extend(self.pending_ops.iter().cloned());
cx.background_spawn(async move {
cx.background_executor().spawn(async move {
let buffer_ops = buffer_ops.await;
context_ops.sort_unstable_by_key(|op| op.timestamp());
buffer_ops
@@ -1144,6 +1177,14 @@ impl AssistantContext {
})
}
pub fn pending_tool_uses(&self) -> Vec<&PendingToolUse> {
self.pending_tool_uses_by_id.values().collect()
}
pub fn get_tool_use_by_id(&self, id: &LanguageModelToolUseId) -> Option<&PendingToolUse> {
self.pending_tool_uses_by_id.get(id)
}
fn set_language(&mut self, cx: &mut Context<Self>) {
let markdown = self.language_registry.language_for_name("Markdown");
cx.spawn(|this, mut cx| async move {
@@ -1189,14 +1230,11 @@ impl AssistantContext {
let Some(model) = LanguageModelRegistry::read_global(cx).active_model() else {
return;
};
let debounce = self.token_count.is_some();
self.pending_token_count = cx.spawn(|this, mut cx| {
async move {
if debounce {
cx.background_executor()
.timer(Duration::from_millis(200))
.await;
}
cx.background_executor()
.timer(Duration::from_millis(200))
.await;
let token_count = cx.update(|cx| model.count_tokens(request, cx))?.await?;
this.update(&mut cx, |this, cx| {
@@ -2168,6 +2206,68 @@ impl AssistantContext {
);
}
pub fn insert_tool_output(
&mut self,
tool_use_id: LanguageModelToolUseId,
output: Task<Result<String>>,
cx: &mut Context<Self>,
) {
let insert_output_task = cx.spawn(|this, mut cx| {
let tool_use_id = tool_use_id.clone();
async move {
let output = output.await;
this.update(&mut cx, |this, cx| match output {
Ok(mut output) => {
const NEWLINE: char = '\n';
if !output.ends_with(NEWLINE) {
output.push(NEWLINE);
}
let anchor_range = this.buffer.update(cx, |buffer, cx| {
let insert_start = buffer.len().to_offset(buffer);
let insert_end = insert_start;
let start = insert_start;
let end = start + output.len() - NEWLINE.len_utf8();
buffer.edit([(insert_start..insert_end, output)], None, cx);
let output_range = buffer.anchor_after(start)..buffer.anchor_after(end);
output_range
});
this.insert_content(
Content::ToolResult {
range: anchor_range.clone(),
tool_use_id: tool_use_id.clone(),
},
cx,
);
cx.emit(ContextEvent::ToolFinished {
tool_use_id,
output_range: anchor_range,
});
}
Err(err) => {
if let Some(tool_use) = this.pending_tool_uses_by_id.get_mut(&tool_use_id) {
tool_use.status = PendingToolUseStatus::Error(err.to_string());
}
}
})
.ok();
}
});
if let Some(tool_use) = self.pending_tool_uses_by_id.get_mut(&tool_use_id) {
tool_use.status = PendingToolUseStatus::Running {
_task: insert_output_task.shared(),
};
}
}
pub fn completion_provider_changed(&mut self, cx: &mut Context<Self>) {
self.count_remaining_tokens(cx);
}
@@ -2198,7 +2298,23 @@ impl AssistantContext {
// Compute which messages to cache, including the last one.
self.mark_cache_anchors(&model.cache_configuration(), false, cx);
let request = self.to_completion_request(request_type, cx);
let mut request = self.to_completion_request(request_type, cx);
// Don't attach tools for now; we'll be removing tool use from
// Assistant1 shortly.
#[allow(clippy::overly_complex_bool_expr)]
if false && cx.has_flag::<ToolUseFeatureFlag>() {
request.tools = self
.tools
.tools(cx)
.into_iter()
.map(|tool| LanguageModelRequestTool {
name: tool.name(),
description: tool.description(),
input_schema: tool.input_schema(),
})
.collect();
}
let assistant_message = self
.insert_message_after(last_message_id, Role::Assistant, MessageStatus::Pending, cx)
@@ -2255,7 +2371,44 @@ impl AssistantContext {
cx,
);
}
LanguageModelCompletionEvent::ToolUse(_) => {}
LanguageModelCompletionEvent::ToolUse(tool_use) => {
const NEWLINE: char = '\n';
let mut text = String::new();
text.push(NEWLINE);
text.push_str(
&serde_json::to_string_pretty(&tool_use)
.expect("failed to serialize tool use to JSON"),
);
text.push(NEWLINE);
let text_len = text.len();
buffer.edit(
[(
message_old_end_offset..message_old_end_offset,
text,
)],
None,
cx,
);
let start_ix = message_old_end_offset + NEWLINE.len_utf8();
let end_ix =
message_old_end_offset + text_len - NEWLINE.len_utf8();
let source_range = buffer.anchor_after(start_ix)
..buffer.anchor_after(end_ix);
this.pending_tool_uses_by_id.insert(
tool_use.id.clone(),
PendingToolUse {
id: tool_use.id,
name: tool_use.name,
input: tool_use.input,
status: PendingToolUseStatus::Idle,
source_range,
},
);
}
}
});
@@ -2338,7 +2491,9 @@ impl AssistantContext {
if let Ok(stop_reason) = result {
match stop_reason {
StopReason::ToolUse => {}
StopReason::ToolUse => {
cx.emit(ContextEvent::UsePendingTools);
}
StopReason::EndTurn => {}
StopReason::MaxTokens => {}
}
@@ -2417,6 +2572,23 @@ impl AssistantContext {
.push(language_model::MessageContent::Image(image));
}
}
Content::ToolUse { tool_use, .. } => {
request_message
.content
.push(language_model::MessageContent::ToolUse(tool_use.clone()));
}
Content::ToolResult { tool_use_id, .. } => {
request_message.content.push(
language_model::MessageContent::ToolResult(
LanguageModelToolResult {
tool_use_id: tool_use_id.to_string(),
is_error: false,
content: collect_text_content(buffer, range.clone())
.unwrap_or_default(),
},
),
);
}
}
offset = range.end;
@@ -3363,7 +3535,7 @@ impl SavedContextV0_1_0 {
}
}
#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct SavedContextMetadata {
pub title: String,
pub path: PathBuf,

View File

@@ -8,6 +8,7 @@ use assistant_slash_command::{
SlashCommandOutputSection, SlashCommandRegistry, SlashCommandResult, SlashCommandWorkingSet,
};
use assistant_slash_commands::FileSlashCommand;
use assistant_tool::ToolWorkingSet;
use collections::{HashMap, HashSet};
use fs::FakeFs;
use futures::{
@@ -55,6 +56,7 @@ fn test_inserting_and_removing_messages(cx: &mut App) {
None,
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
cx,
)
});
@@ -195,6 +197,7 @@ fn test_message_splitting(cx: &mut App) {
None,
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
cx,
)
});
@@ -297,6 +300,7 @@ fn test_messages_for_offsets(cx: &mut App) {
None,
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
cx,
)
});
@@ -410,6 +414,7 @@ async fn test_slash_commands(cx: &mut TestAppContext) {
None,
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
cx,
)
});
@@ -699,6 +704,7 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
None,
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
cx,
)
});
@@ -963,6 +969,7 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
registry.clone(),
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
None,
None,
cx,
@@ -1081,6 +1088,7 @@ async fn test_serialization(cx: &mut TestAppContext) {
None,
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
cx,
)
});
@@ -1124,6 +1132,7 @@ async fn test_serialization(cx: &mut TestAppContext) {
registry.clone(),
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
None,
None,
cx,
@@ -1182,6 +1191,7 @@ async fn test_random_context_collaboration(cx: &mut TestAppContext, mut rng: Std
registry.clone(),
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
None,
None,
cx,
@@ -1441,6 +1451,7 @@ fn test_mark_cache_anchors(cx: &mut App) {
None,
prompt_builder.clone(),
Arc::new(SlashCommandWorkingSet::default()),
Arc::new(ToolWorkingSet::default()),
cx,
)
});

View File

@@ -5,6 +5,7 @@ use assistant_slash_commands::{
selections_creases, DefaultSlashCommand, DocsSlashCommand, DocsSlashCommandArgs,
FileSlashCommand,
};
use assistant_tool::ToolWorkingSet;
use client::{proto, zed_urls};
use collections::{hash_map, BTreeSet, HashMap, HashSet};
use editor::{
@@ -32,7 +33,7 @@ use indexed_docs::IndexedDocsStore;
use language::{language_settings::SoftWrap, BufferSnapshot, LspAdapterDelegate, ToOffset};
use language_model::{
LanguageModelImage, LanguageModelProvider, LanguageModelProviderTosView, LanguageModelRegistry,
Role,
LanguageModelToolUse, Role,
};
use language_model_selector::{LanguageModelSelector, LanguageModelSelectorPopoverMenu};
use multi_buffer::MultiBufferRow;
@@ -170,6 +171,7 @@ pub struct ContextEditor {
context: Entity<AssistantContext>,
fs: Arc<dyn Fs>,
slash_commands: Arc<SlashCommandWorkingSet>,
tools: Arc<ToolWorkingSet>,
workspace: WeakEntity<Workspace>,
project: Entity<Project>,
lsp_adapter_delegate: Option<Arc<dyn LspAdapterDelegate>>,
@@ -180,6 +182,7 @@ pub struct ContextEditor {
remote_id: Option<workspace::ViewId>,
pending_slash_command_creases: HashMap<Range<language::Anchor>, CreaseId>,
invoked_slash_command_creases: HashMap<InvokedSlashCommandId, CreaseId>,
pending_tool_use_creases: HashMap<Range<language::Anchor>, CreaseId>,
_subscriptions: Vec<Subscription>,
patches: HashMap<Range<language::Anchor>, PatchViewState>,
active_patch: Option<Range<language::Anchor>>,
@@ -193,8 +196,6 @@ pub struct ContextEditor {
// the file is opened. In order to keep the worktree alive for the duration of the
// context editor, we keep a reference here.
dragged_file_worktrees: Vec<Entity<Worktree>>,
language_model_selector: Entity<LanguageModelSelector>,
language_model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
}
pub const DEFAULT_TAB_TITLE: &str = "New Chat";
@@ -240,28 +241,14 @@ impl ContextEditor {
cx.subscribe_in(&editor, window, Self::handle_editor_search_event),
];
let fs_clone = fs.clone();
let language_model_selector = cx.new(|cx| {
LanguageModelSelector::new(
move |model, cx| {
update_settings_file::<AssistantSettings>(
fs_clone.clone(),
cx,
move |settings, _| settings.set_model(model.clone()),
);
},
window,
cx,
)
});
let language_model_selector_menu_handle = PopoverMenuHandle::default();
let sections = context.read(cx).slash_command_output_sections().to_vec();
let patch_ranges = context.read(cx).patch_ranges().collect::<Vec<_>>();
let slash_commands = context.read(cx).slash_commands().clone();
let tools = context.read(cx).tools().clone();
let mut this = Self {
context,
slash_commands,
tools,
editor,
lsp_adapter_delegate,
blocks: Default::default(),
@@ -273,6 +260,7 @@ impl ContextEditor {
project,
pending_slash_command_creases: HashMap::default(),
invoked_slash_command_creases: HashMap::default(),
pending_tool_use_creases: HashMap::default(),
_subscriptions,
patches: HashMap::default(),
active_patch: None,
@@ -280,8 +268,6 @@ impl ContextEditor {
show_accept_terms: false,
slash_menu_handle: Default::default(),
dragged_file_worktrees: Vec::new(),
language_model_selector,
language_model_selector_menu_handle,
};
this.update_message_headers(cx);
this.update_image_blocks(cx);
@@ -479,7 +465,7 @@ impl ContextEditor {
window: &mut Window,
cx: &mut Context<Self>,
) {
if self.editor.read(cx).has_visible_completions_menu() {
if self.editor.read(cx).has_active_completions_menu() {
return;
}
@@ -594,6 +580,87 @@ impl ContextEditor {
cx,
);
}
let new_tool_uses = self
.context
.read(cx)
.pending_tool_uses()
.into_iter()
.filter(|tool_use| {
!self
.pending_tool_use_creases
.contains_key(&tool_use.source_range)
})
.cloned()
.collect::<Vec<_>>();
let buffer = editor.buffer().read(cx).snapshot(cx);
let (excerpt_id, _buffer_id, _) = buffer.as_singleton().unwrap();
let excerpt_id = *excerpt_id;
let mut buffer_rows_to_fold = BTreeSet::new();
let creases = new_tool_uses
.iter()
.map(|tool_use| {
let placeholder = FoldPlaceholder {
render: render_fold_icon_button(
cx.entity().downgrade(),
IconName::PocketKnife,
tool_use.name.clone().into(),
),
..Default::default()
};
let render_trailer =
move |_row, _unfold, _window: &mut Window, _cx: &mut App| {
Empty.into_any()
};
let start = buffer
.anchor_in_excerpt(excerpt_id, tool_use.source_range.start)
.unwrap();
let end = buffer
.anchor_in_excerpt(excerpt_id, tool_use.source_range.end)
.unwrap();
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
buffer_rows_to_fold.insert(buffer_row);
self.context.update(cx, |context, cx| {
context.insert_content(
Content::ToolUse {
range: tool_use.source_range.clone(),
tool_use: LanguageModelToolUse {
id: tool_use.id.clone(),
name: tool_use.name.clone(),
input: tool_use.input.clone(),
},
},
cx,
);
});
Crease::inline(
start..end,
placeholder,
fold_toggle("tool-use"),
render_trailer,
)
})
.collect::<Vec<_>>();
let crease_ids = editor.insert_creases(creases, cx);
for buffer_row in buffer_rows_to_fold.into_iter().rev() {
editor.fold_at(&FoldAt { buffer_row }, window, cx);
}
self.pending_tool_use_creases.extend(
new_tool_uses
.iter()
.map(|tool_use| tool_use.source_range.clone())
.zip(crease_ids),
);
});
}
ContextEvent::PatchesUpdated { removed, updated } => {
@@ -634,7 +701,7 @@ impl ContextEditor {
}
});
let placeholder = FoldPlaceholder {
render: Arc::new(move |_, _, _| Empty.into_any()),
render: Arc::new(move |_, _, _, _| Empty.into_any()),
..Default::default()
};
let render_toggle = {
@@ -691,6 +758,66 @@ impl ContextEditor {
ContextEvent::SlashCommandOutputSectionAdded { section } => {
self.insert_slash_command_output_sections([section.clone()], false, window, cx);
}
ContextEvent::UsePendingTools => {
let pending_tool_uses = self
.context
.read(cx)
.pending_tool_uses()
.into_iter()
.filter(|tool_use| tool_use.status.is_idle())
.cloned()
.collect::<Vec<_>>();
for tool_use in pending_tool_uses {
if let Some(tool) = self.tools.tool(&tool_use.name, cx) {
let task = tool.run(tool_use.input, self.workspace.clone(), window, cx);
self.context.update(cx, |context, cx| {
context.insert_tool_output(tool_use.id.clone(), task, cx);
});
}
}
}
ContextEvent::ToolFinished {
tool_use_id,
output_range,
} => {
self.editor.update(cx, |editor, cx| {
let buffer = editor.buffer().read(cx).snapshot(cx);
let (excerpt_id, _buffer_id, _) = buffer.as_singleton().unwrap();
let excerpt_id = *excerpt_id;
let placeholder = FoldPlaceholder {
render: render_fold_icon_button(
cx.entity().downgrade(),
IconName::PocketKnife,
format!("Tool Result: {tool_use_id}").into(),
),
..Default::default()
};
let render_trailer =
move |_row, _unfold, _window: &mut Window, _cx: &mut App| Empty.into_any();
let start = buffer
.anchor_in_excerpt(excerpt_id, output_range.start)
.unwrap();
let end = buffer
.anchor_in_excerpt(excerpt_id, output_range.end)
.unwrap();
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
let crease = Crease::inline(
start..end,
placeholder,
fold_toggle("tool-use"),
render_trailer,
);
editor.insert_creases([crease], cx);
editor.fold_at(&FoldAt { buffer_row }, window, cx);
});
}
ContextEvent::Operation(_) => {}
ContextEvent::ShowAssistError(error_message) => {
self.last_error = Some(AssistError::Message(error_message.clone()));
@@ -852,13 +979,12 @@ impl ContextEditor {
let render_block: RenderBlock = Arc::new({
let this = this.clone();
let patch_range = range.clone();
move |cx: &mut BlockContext| {
move |cx: &mut BlockContext<'_, '_>| {
let max_width = cx.max_width;
let gutter_width = cx.gutter_dimensions.full_width();
let block_id = cx.block_id;
let selected = cx.selected;
let window = &mut cx.window;
this.update(cx.app, |this, cx| {
this.update_in(cx, |this, window, cx| {
this.render_patch_block(
patch_range.clone(),
max_width,
@@ -1087,7 +1213,7 @@ impl ContextEditor {
patch: AssistantPatch,
mut cx: AsyncWindowContext,
) -> Result<()> {
let project = this.read_with(&cx, |this, _| this.project.clone())?;
let project = this.update(&mut cx, |this, _| this.project.clone())?;
let resolved_patch = patch.resolve(project.clone(), &mut cx).await;
let editor = cx.new_window_entity(|window, cx| {
@@ -1112,7 +1238,7 @@ impl ContextEditor {
editor
})?;
this.update(&mut cx, |this, _| {
this.update_in(&mut cx, |this, window, cx| {
if let Some(patch_state) = this.patches.get_mut(&patch.range) {
patch_state.editor = Some(PatchEditorState {
editor: editor.downgrade(),
@@ -1120,12 +1246,19 @@ impl ContextEditor {
});
patch_state.update_task.take();
}
this.workspace
.update(cx, |workspace, cx| {
workspace.add_item_to_active_pane(
Box::new(editor.clone()),
None,
false,
window,
cx,
)
})
.log_err();
})?;
this.read_with(&cx, |this, _| this.workspace.clone())?
.update_in(&mut cx, |workspace, window, cx| {
workspace.add_item_to_active_pane(Box::new(editor.clone()), None, false, window, cx)
})
.log_err();
Ok(())
}
@@ -1227,8 +1360,8 @@ impl ContextEditor {
.px_1()
.mr_0p5()
.border_1()
.border_color(colors.border_variant.alpha(0.6))
.bg(colors.element_background.alpha(0.6))
.border_color(theme::color_alpha(colors.border_variant, 0.6))
.bg(theme::color_alpha(colors.element_background, 0.6))
.child("esc"),
)
.child("to cancel")
@@ -1507,11 +1640,15 @@ impl ContextEditor {
(!text.is_empty()).then_some((text, true))
} else {
let selection = context_editor.selections.newest_adjusted(cx);
let buffer = context_editor.buffer().read(cx).snapshot(cx);
let selected_text = buffer.text_for_range(selection.range()).collect::<String>();
let anchor = context_editor.selections.newest_anchor();
let text = context_editor
.buffer()
.read(cx)
.read(cx)
.text_for_range(anchor.range())
.collect::<String>();
(!selected_text.is_empty()).then_some((selected_text, false))
(!text.is_empty()).then_some((text, false))
}
})
}
@@ -1766,16 +1903,23 @@ impl ContextEditor {
&mut self,
cx: &mut Context<Self>,
) -> (String, CopyMetadata, Vec<text::Selection<usize>>) {
let (selection, creases) = self.editor.update(cx, |editor, cx| {
let mut selection = editor.selections.newest_adjusted(cx);
let (snapshot, selection, creases) = self.editor.update(cx, |editor, cx| {
let mut selection = editor.selections.newest::<Point>(cx);
let snapshot = editor.buffer().read(cx).snapshot(cx);
selection.goal = SelectionGoal::None;
let is_entire_line = selection.is_empty() || editor.selections.line_mode;
if is_entire_line {
selection.start = Point::new(selection.start.row, 0);
selection.end =
cmp::min(snapshot.max_point(), Point::new(selection.start.row + 1, 0));
selection.goal = SelectionGoal::None;
}
let selection_start = snapshot.point_to_offset(selection.start);
(
selection.map(|point| snapshot.point_to_offset(point)),
snapshot.clone(),
selection.clone(),
editor.display_map.update(cx, |display_map, cx| {
display_map
.snapshot(cx)
@@ -1815,6 +1959,7 @@ impl ContextEditor {
)
});
let selection = selection.map(|point| snapshot.point_to_offset(point));
let context = self.context.read(cx);
let mut text = String::new();
@@ -1967,13 +2112,18 @@ impl ContextEditor {
.context
.read(cx)
.contents(cx)
.map(
|Content::Image {
anchor,
render_image,
..
}| (anchor, render_image),
)
.filter_map(|content| {
if let Content::Image {
anchor,
render_image,
..
} = content
{
Some((anchor, render_image))
} else {
None
}
})
.filter_map(|(anchor, render_image)| {
const MAX_HEIGHT_IN_LINES: u32 = 8;
let anchor = buffer.anchor_in_excerpt(excerpt_id, anchor).unwrap();
@@ -2024,15 +2174,6 @@ impl ContextEditor {
});
}
fn toggle_model_selector(
&mut self,
_: &ToggleModelSelector,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.language_model_selector_menu_handle.toggle(window, cx);
}
fn save(&mut self, _: &Save, _window: &mut Window, cx: &mut Context<Self>) {
self.context.update(cx, |context, cx| {
context.save(Some(Duration::from_millis(500)), self.fs.clone(), cx)
@@ -2300,7 +2441,7 @@ impl ContextEditor {
},
))
.children(
KeyBinding::for_action_in(&Assist, &focus_handle, window, cx)
KeyBinding::for_action_in(&Assist, &focus_handle, window)
.map(|binding| binding.into_any_element()),
)
.on_click(move |_event, window, cx| {
@@ -2353,7 +2494,7 @@ impl ContextEditor {
.layer(ElevationIndex::ModalSurface)
.child(Label::new("Suggest Edits"))
.children(
KeyBinding::for_action_in(&Edit, &focus_handle, window, cx)
KeyBinding::for_action_in(&Edit, &focus_handle, window)
.map(|binding| binding.into_any_element()),
)
.on_click(move |_event, window, cx| {
@@ -2365,61 +2506,15 @@ impl ContextEditor {
slash_command_picker::SlashCommandSelector::new(
self.slash_commands.clone(),
cx.entity().downgrade(),
IconButton::new("trigger", IconName::Plus)
Button::new("trigger", "Add Context")
.icon(IconName::Plus)
.icon_size(IconSize::Small)
.icon_color(Color::Muted),
move |window, cx| {
Tooltip::with_meta(
"Add Context",
None,
"Type / to insert via keyboard",
window,
cx,
)
},
.icon_color(Color::Muted)
.icon_position(IconPosition::Start)
.tooltip(Tooltip::text("Type / to insert via keyboard")),
)
}
fn render_language_model_selector(&self, cx: &mut Context<Self>) -> impl IntoElement {
let active_model = LanguageModelRegistry::read_global(cx).active_model();
let focus_handle = self.editor().focus_handle(cx).clone();
let model_name = match active_model {
Some(model) => model.name().0,
None => SharedString::from("No model selected"),
};
LanguageModelSelectorPopoverMenu::new(
self.language_model_selector.clone(),
ButtonLike::new("active-model")
.style(ButtonStyle::Subtle)
.child(
h_flex()
.gap_0p5()
.child(
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted),
)
.child(
Icon::new(IconName::ChevronDown)
.color(Color::Muted)
.size(IconSize::XSmall),
),
),
move |window, cx| {
Tooltip::for_action_in(
"Change Model",
&ToggleModelSelector,
&focus_handle,
window,
cx,
)
},
gpui::Corner::BottomLeft,
)
.with_handle(self.language_model_selector_menu_handle.clone())
}
fn render_last_error(&self, cx: &mut Context<Self>) -> Option<AnyElement> {
let last_error = self.last_error.as_ref()?;
@@ -2649,8 +2744,8 @@ fn render_fold_icon_button(
editor: WeakEntity<Editor>,
icon: IconName,
label: SharedString,
) -> Arc<dyn Send + Sync + Fn(FoldId, Range<Anchor>, &mut App) -> AnyElement> {
Arc::new(move |fold_id, fold_range, _cx| {
) -> Arc<dyn Send + Sync + Fn(FoldId, Range<Anchor>, &mut Window, &mut App) -> AnyElement> {
Arc::new(move |fold_id, fold_range, _window, _cx| {
let editor = editor.clone();
ButtonLike::new(fold_id)
.style(ButtonStyle::Filled)
@@ -2710,7 +2805,7 @@ pub fn fold_toggle(
fn quote_selection_fold_placeholder(title: String, editor: WeakEntity<Editor>) -> FoldPlaceholder {
FoldPlaceholder {
render: Arc::new({
move |fold_id, fold_range, _cx| {
move |fold_id, fold_range, _window, _cx| {
let editor = editor.clone();
ButtonLike::new(fold_id)
.style(ButtonStyle::Filled)
@@ -2876,7 +2971,6 @@ impl Render for ContextEditor {
.on_action(cx.listener(ContextEditor::edit))
.on_action(cx.listener(ContextEditor::assist))
.on_action(cx.listener(ContextEditor::split))
.on_action(cx.listener(ContextEditor::toggle_model_selector))
.size_full()
.children(self.render_notice(cx))
.child(
@@ -2909,17 +3003,7 @@ impl Render for ContextEditor {
.border_t_1()
.border_color(cx.theme().colors().border_variant)
.bg(cx.theme().colors().editor_background)
.child(
h_flex()
.gap_1()
.child(self.render_inject_context_menu(cx))
.child(ui::Divider::vertical())
.child(
div()
.pl_0p5()
.child(self.render_language_model_selector(cx)),
),
)
.child(h_flex().gap_1().child(self.render_inject_context_menu(cx)))
.child(
h_flex()
.w_full()
@@ -3230,67 +3314,80 @@ impl FollowableItem for ContextEditor {
pub struct ContextEditorToolbarItem {
active_context_editor: Option<WeakEntity<ContextEditor>>,
model_summary_editor: Entity<Editor>,
language_model_selector: Entity<LanguageModelSelector>,
language_model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
}
impl ContextEditorToolbarItem {
pub fn new(model_summary_editor: Entity<Editor>) -> Self {
pub fn new(
workspace: &Workspace,
model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
model_summary_editor: Entity<Editor>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
Self {
active_context_editor: None,
model_summary_editor,
language_model_selector: cx.new(|cx| {
let fs = workspace.app_state().fs.clone();
LanguageModelSelector::new(
move |model, cx| {
update_settings_file::<AssistantSettings>(
fs.clone(),
cx,
move |settings, _| settings.set_model(model.clone()),
);
},
window,
cx,
)
}),
language_model_selector_menu_handle: model_selector_menu_handle,
}
}
}
pub fn render_remaining_tokens(
context_editor: &Entity<ContextEditor>,
cx: &App,
) -> Option<impl IntoElement> {
let context = &context_editor.read(cx).context;
let (token_count_color, token_count, max_token_count, tooltip) = match token_state(context, cx)?
{
TokenState::NoTokensLeft {
max_token_count,
token_count,
} => (
Color::Error,
token_count,
max_token_count,
Some("Token Limit Reached"),
),
TokenState::HasMoreTokens {
max_token_count,
token_count,
over_warn_threshold,
} => {
let (color, tooltip) = if over_warn_threshold {
(Color::Warning, Some("Token Limit is Close to Exhaustion"))
} else {
(Color::Muted, None)
};
(color, token_count, max_token_count, tooltip)
}
};
Some(
h_flex()
.id("token-count")
.gap_0p5()
.child(
Label::new(humanize_token_count(token_count))
.size(LabelSize::Small)
.color(token_count_color),
)
.child(Label::new("/").size(LabelSize::Small).color(Color::Muted))
.child(
Label::new(humanize_token_count(max_token_count))
.size(LabelSize::Small)
.color(Color::Muted),
)
.when_some(tooltip, |element, tooltip| {
element.tooltip(Tooltip::text(tooltip))
}),
)
fn render_remaining_tokens(&self, cx: &mut Context<Self>) -> Option<impl IntoElement> {
let context = &self
.active_context_editor
.as_ref()?
.upgrade()?
.read(cx)
.context;
let (token_count_color, token_count, max_token_count) = match token_state(context, cx)? {
TokenState::NoTokensLeft {
max_token_count,
token_count,
} => (Color::Error, token_count, max_token_count),
TokenState::HasMoreTokens {
max_token_count,
token_count,
over_warn_threshold,
} => {
let color = if over_warn_threshold {
Color::Warning
} else {
Color::Muted
};
(color, token_count, max_token_count)
}
};
Some(
h_flex()
.gap_0p5()
.child(
Label::new(humanize_token_count(token_count))
.size(LabelSize::Small)
.color(token_count_color),
)
.child(Label::new("/").size(LabelSize::Small).color(Color::Muted))
.child(
Label::new(humanize_token_count(max_token_count))
.size(LabelSize::Small)
.color(Color::Muted),
),
)
}
}
impl Render for ContextEditorToolbarItem {
@@ -3317,7 +3414,8 @@ impl Render for ContextEditorToolbarItem {
})),
),
);
let active_provider = LanguageModelRegistry::read_global(cx).active_provider();
let active_model = LanguageModelRegistry::read_global(cx).active_model();
let right_side = h_flex()
.gap_2()
// TODO display this in a nicer way, once we have a design for it.
@@ -3333,12 +3431,57 @@ impl Render for ContextEditorToolbarItem {
// scan_items_remaining
// .map(|remaining_items| format!("Files to scan: {}", remaining_items))
// })
.children(
self.active_context_editor
.as_ref()
.and_then(|editor| editor.upgrade())
.and_then(|editor| render_remaining_tokens(&editor, cx)),
);
.child(
LanguageModelSelectorPopoverMenu::new(
self.language_model_selector.clone(),
ButtonLike::new("active-model")
.style(ButtonStyle::Subtle)
.child(
h_flex()
.w_full()
.gap_0p5()
.child(
div()
.overflow_x_hidden()
.flex_grow()
.whitespace_nowrap()
.child(match (active_provider, active_model) {
(Some(provider), Some(model)) => h_flex()
.gap_1()
.child(
Icon::new(
model
.icon()
.unwrap_or_else(|| provider.icon()),
)
.color(Color::Muted)
.size(IconSize::XSmall),
)
.child(
Label::new(model.name().0)
.size(LabelSize::Small)
.color(Color::Muted),
)
.into_any_element(),
_ => Label::new("No model selected")
.size(LabelSize::Small)
.color(Color::Muted)
.into_any_element(),
}),
)
.child(
Icon::new(IconName::ChevronDown)
.color(Color::Muted)
.size(IconSize::XSmall),
),
)
.tooltip(move |window, cx| {
Tooltip::for_action("Change Model", &ToggleModelSelector, window, cx)
}),
)
.with_handle(self.language_model_selector_menu_handle.clone()),
)
.children(self.render_remaining_tokens(cx));
h_flex()
.px_0p5()
@@ -3394,7 +3537,7 @@ fn invoked_slash_command_fold_placeholder(
FoldPlaceholder {
constrain_width: false,
merge_adjacent: false,
render: Arc::new(move |fold_id, _, cx| {
render: Arc::new(move |fold_id, _, _window, cx| {
let Some(context) = context.upgrade() else {
return Empty.into_any();
};

View File

@@ -4,11 +4,12 @@ use crate::{
};
use anyhow::{anyhow, Context as _, Result};
use assistant_slash_command::{SlashCommandId, SlashCommandWorkingSet};
use assistant_tool::{ToolId, ToolWorkingSet};
use client::{proto, telemetry::Telemetry, Client, TypedEnvelope};
use clock::ReplicaId;
use collections::HashMap;
use context_server::manager::ContextServerManager;
use context_server::ContextServerFactoryRegistry;
use context_server::{ContextServerFactoryRegistry, ContextServerTool};
use fs::Fs;
use futures::StreamExt;
use fuzzy::StringMatchCandidate;
@@ -31,11 +32,11 @@ use std::{
use util::{ResultExt, TryFutureExt};
pub(crate) fn init(client: &AnyProtoClient) {
client.add_entity_message_handler(ContextStore::handle_advertise_contexts);
client.add_entity_request_handler(ContextStore::handle_open_context);
client.add_entity_request_handler(ContextStore::handle_create_context);
client.add_entity_message_handler(ContextStore::handle_update_context);
client.add_entity_request_handler(ContextStore::handle_synchronize_contexts);
client.add_model_message_handler(ContextStore::handle_advertise_contexts);
client.add_model_request_handler(ContextStore::handle_open_context);
client.add_model_request_handler(ContextStore::handle_create_context);
client.add_model_message_handler(ContextStore::handle_update_context);
client.add_model_request_handler(ContextStore::handle_synchronize_contexts);
}
#[derive(Clone)]
@@ -49,10 +50,12 @@ pub struct ContextStore {
contexts_metadata: Vec<SavedContextMetadata>,
context_server_manager: Entity<ContextServerManager>,
context_server_slash_command_ids: HashMap<Arc<str>, Vec<SlashCommandId>>,
context_server_tool_ids: HashMap<Arc<str>, Vec<ToolId>>,
host_contexts: Vec<RemoteContextMetadata>,
fs: Arc<dyn Fs>,
languages: Arc<LanguageRegistry>,
slash_commands: Arc<SlashCommandWorkingSet>,
tools: Arc<ToolWorkingSet>,
telemetry: Arc<Telemetry>,
_watch_updates: Task<Option<()>>,
client: Arc<Client>,
@@ -95,6 +98,7 @@ impl ContextStore {
project: Entity<Project>,
prompt_builder: Arc<PromptBuilder>,
slash_commands: Arc<SlashCommandWorkingSet>,
tools: Arc<ToolWorkingSet>,
cx: &mut App,
) -> Task<Result<Entity<Self>>> {
let fs = project.read(cx).fs().clone();
@@ -115,10 +119,12 @@ impl ContextStore {
contexts_metadata: Vec::new(),
context_server_manager,
context_server_slash_command_ids: HashMap::default(),
context_server_tool_ids: HashMap::default(),
host_contexts: Vec::new(),
fs,
languages,
slash_commands,
tools,
telemetry,
_watch_updates: cx.spawn(|this, mut cx| {
async move {
@@ -144,9 +150,11 @@ impl ContextStore {
this.handle_project_changed(project.clone(), cx);
this.synchronize_contexts(cx);
this.register_context_server_handlers(cx);
this.reload(cx).detach_and_log_err(cx);
this
})?;
this.update(&mut cx, |this, cx| this.reload(cx))?
.await
.log_err();
Ok(this)
})
@@ -265,18 +273,19 @@ impl ContextStore {
local_versions.push(context.version(cx).to_proto(context_id.clone()));
let client = this.client.clone();
let project_id = envelope.payload.project_id;
cx.background_spawn(async move {
let operations = operations.await;
for operation in operations {
client.send(proto::UpdateContext {
project_id,
context_id: context_id.to_proto(),
operation: Some(operation),
})?;
}
anyhow::Ok(())
})
.detach_and_log_err(cx);
cx.background_executor()
.spawn(async move {
let operations = operations.await;
for operation in operations {
client.send(proto::UpdateContext {
project_id,
context_id: context_id.to_proto(),
operation: Some(operation),
})?;
}
anyhow::Ok(())
})
.detach_and_log_err(cx);
}
}
@@ -309,7 +318,7 @@ impl ContextStore {
.client
.subscribe_to_entity(remote_id)
.log_err()
.map(|subscription| subscription.set_entity(&cx.entity(), &mut cx.to_async()));
.map(|subscription| subscription.set_model(&cx.entity(), &mut cx.to_async()));
self.advertise_contexts(cx);
} else {
self.client_subscription = None;
@@ -350,12 +359,6 @@ impl ContextStore {
}
}
pub fn contexts(&self) -> Vec<SavedContextMetadata> {
let mut contexts = self.contexts_metadata.iter().cloned().collect::<Vec<_>>();
contexts.sort_unstable_by_key(|thread| std::cmp::Reverse(thread.mtime));
contexts
}
pub fn create(&mut self, cx: &mut Context<Self>) -> Entity<AssistantContext> {
let context = cx.new(|cx| {
AssistantContext::local(
@@ -364,6 +367,7 @@ impl ContextStore {
Some(self.telemetry.clone()),
self.prompt_builder.clone(),
self.slash_commands.clone(),
self.tools.clone(),
cx,
)
});
@@ -387,6 +391,7 @@ impl ContextStore {
let telemetry = self.telemetry.clone();
let prompt_builder = self.prompt_builder.clone();
let slash_commands = self.slash_commands.clone();
let tools = self.tools.clone();
let request = self.client.request(proto::CreateContext { project_id });
cx.spawn(|this, mut cx| async move {
let response = request.await?;
@@ -400,13 +405,15 @@ impl ContextStore {
language_registry,
prompt_builder,
slash_commands,
tools,
Some(project),
Some(telemetry),
cx,
)
})?;
let operations = cx
.background_spawn(async move {
.background_executor()
.spawn(async move {
context_proto
.operations
.into_iter()
@@ -440,7 +447,7 @@ impl ContextStore {
let languages = self.languages.clone();
let project = self.project.clone();
let telemetry = self.telemetry.clone();
let load = cx.background_spawn({
let load = cx.background_executor().spawn({
let path = path.clone();
async move {
let saved_context = fs.load(&path).await?;
@@ -449,6 +456,7 @@ impl ContextStore {
});
let prompt_builder = self.prompt_builder.clone();
let slash_commands = self.slash_commands.clone();
let tools = self.tools.clone();
cx.spawn(|this, mut cx| async move {
let saved_context = load.await?;
@@ -459,6 +467,7 @@ impl ContextStore {
languages,
prompt_builder,
slash_commands,
tools,
Some(project),
Some(telemetry),
cx,
@@ -526,6 +535,7 @@ impl ContextStore {
});
let prompt_builder = self.prompt_builder.clone();
let slash_commands = self.slash_commands.clone();
let tools = self.tools.clone();
cx.spawn(|this, mut cx| async move {
let response = request.await?;
let context_proto = response.context.context("invalid context")?;
@@ -537,13 +547,15 @@ impl ContextStore {
language_registry,
prompt_builder,
slash_commands,
tools,
Some(project),
Some(telemetry),
cx,
)
})?;
let operations = cx
.background_spawn(async move {
.background_executor()
.spawn(async move {
context_proto
.operations
.into_iter()
@@ -696,7 +708,7 @@ impl ContextStore {
pub fn search(&self, query: String, cx: &App) -> Task<Vec<SavedContextMetadata>> {
let metadata = self.contexts_metadata.clone();
let executor = cx.background_executor().clone();
cx.background_spawn(async move {
cx.background_executor().spawn(async move {
if query.is_empty() {
metadata
} else {
@@ -804,6 +816,7 @@ impl ContextStore {
cx: &mut Context<Self>,
) {
let slash_command_working_set = self.slash_commands.clone();
let tool_working_set = self.tools.clone();
match event {
context_server::manager::Event::ServerStarted { server_id } => {
if let Some(server) = context_server_manager.read(cx).get_server(server_id) {
@@ -843,6 +856,29 @@ impl ContextStore {
.log_err();
}
}
if protocol.capable(context_server::protocol::ServerCapability::Tools) {
if let Some(tools) = protocol.list_tools().await.log_err() {
let tool_ids = tools.tools.into_iter().map(|tool| {
log::info!("registering context server tool: {:?}", tool.name);
tool_working_set.insert(
Arc::new(ContextServerTool::new(
context_server_manager.clone(),
server.id(),
tool,
)),
)
}).collect::<Vec<_>>();
this.update(&mut cx, |this, _cx| {
this.context_server_tool_ids
.insert(server_id, tool_ids);
})
.log_err();
}
}
}
})
.detach();
@@ -854,6 +890,10 @@ impl ContextStore {
{
slash_command_working_set.remove(&slash_command_ids);
}
if let Some(tool_ids) = self.context_server_tool_ids.remove(server_id) {
tool_working_set.remove(&tool_ids);
}
}
}
}

View File

@@ -2,7 +2,7 @@ use anyhow::{anyhow, Context as _, Result};
use collections::HashMap;
use editor::ProposedChangesEditor;
use futures::{future, TryFutureExt as _};
use gpui::{App, AppContext as _, AsyncApp, Entity, SharedString};
use gpui::{App, AsyncApp, Entity, SharedString};
use language::{AutoindentMode, Buffer, BufferSnapshot};
use project::{Project, ProjectPath};
use std::{cmp, ops::Range, path::Path, sync::Arc};
@@ -140,7 +140,7 @@ impl ResolvedPatch {
buffer.edit(
edits,
Some(AutoindentMode::Block {
original_start_columns: Vec::new(),
original_indent_columns: Vec::new(),
}),
cx,
);
@@ -258,7 +258,8 @@ impl AssistantEdit {
let snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
let suggestion = cx
.background_spawn(async move { kind.resolve(&snapshot) })
.background_executor()
.spawn(async move { kind.resolve(&snapshot) })
.await;
Ok((buffer, suggestion))
@@ -546,7 +547,7 @@ impl Eq for AssistantPatch {}
#[cfg(test)]
mod tests {
use super::*;
use gpui::App;
use gpui::{App, AppContext as _};
use language::{
language_settings::AllLanguageSettings, Language, LanguageConfig, LanguageMatcher,
};

View File

@@ -4,10 +4,10 @@ pub use assistant_slash_command::SlashCommand;
use assistant_slash_command::{AfterCompletion, SlashCommandLine, SlashCommandWorkingSet};
use editor::{CompletionProvider, Editor};
use fuzzy::{match_strings, StringMatchCandidate};
use gpui::{App, AppContext as _, Context, Entity, Task, WeakEntity, Window};
use language::{Anchor, Buffer, LanguageServerId, ToPoint};
use gpui::{App, Context, Entity, Task, WeakEntity, Window};
use language::{Anchor, Buffer, Documentation, LanguageServerId, ToPoint};
use parking_lot::Mutex;
use project::{lsp_store::CompletionDocumentation, CompletionIntent};
use project::CompletionIntent;
use rope::Point;
use std::{
cell::RefCell,
@@ -120,9 +120,7 @@ impl SlashCommandCompletionProvider {
});
Some(project::Completion {
old_range: name_range.clone(),
documentation: Some(CompletionDocumentation::SingleLine(
command.description().into(),
)),
documentation: Some(Documentation::SingleLine(command.description())),
new_text,
label: command.label(cx),
server_id: LanguageServerId(0),
@@ -163,7 +161,7 @@ impl SlashCommandCompletionProvider {
let editor = self.editor.clone();
let workspace = self.workspace.clone();
let arguments = arguments.to_vec();
cx.background_spawn(async move {
cx.background_executor().spawn(async move {
Ok(completions
.await?
.into_iter()

View File

@@ -1,22 +1,17 @@
use std::sync::Arc;
use assistant_slash_command::SlashCommandWorkingSet;
use gpui::{AnyElement, AnyView, DismissEvent, SharedString, Task, WeakEntity};
use gpui::{AnyElement, DismissEvent, SharedString, Task, WeakEntity};
use picker::{Picker, PickerDelegate, PickerEditorPosition};
use ui::{prelude::*, ListItem, ListItemSpacing, PopoverMenu, PopoverTrigger, Tooltip};
use crate::context_editor::ContextEditor;
#[derive(IntoElement)]
pub(super) struct SlashCommandSelector<T, TT>
where
T: PopoverTrigger + ButtonCommon,
TT: Fn(&mut Window, &mut App) -> AnyView + 'static,
{
pub(super) struct SlashCommandSelector<T: PopoverTrigger> {
working_set: Arc<SlashCommandWorkingSet>,
active_context_editor: WeakEntity<ContextEditor>,
trigger: T,
tooltip: TT,
}
#[derive(Clone)]
@@ -53,22 +48,16 @@ pub(crate) struct SlashCommandDelegate {
selected_index: usize,
}
impl<T, TT> SlashCommandSelector<T, TT>
where
T: PopoverTrigger + ButtonCommon,
TT: Fn(&mut Window, &mut App) -> AnyView + 'static,
{
impl<T: PopoverTrigger> SlashCommandSelector<T> {
pub(crate) fn new(
working_set: Arc<SlashCommandWorkingSet>,
active_context_editor: WeakEntity<ContextEditor>,
trigger: T,
tooltip: TT,
) -> Self {
SlashCommandSelector {
working_set,
active_context_editor,
trigger,
tooltip,
}
}
}
@@ -102,7 +91,8 @@ impl PickerDelegate for SlashCommandDelegate {
let all_commands = self.all_commands.clone();
cx.spawn_in(window, |this, mut cx| async move {
let filtered_commands = cx
.background_spawn(async move {
.background_executor()
.spawn(async move {
if query.is_empty() {
all_commands
} else {
@@ -251,11 +241,7 @@ impl PickerDelegate for SlashCommandDelegate {
}
}
impl<T, TT> RenderOnce for SlashCommandSelector<T, TT>
where
T: PopoverTrigger + ButtonCommon,
TT: Fn(&mut Window, &mut App) -> AnyView + 'static,
{
impl<T: PopoverTrigger> RenderOnce for SlashCommandSelector<T> {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let all_models = self
.working_set
@@ -336,7 +322,7 @@ where
.ok();
PopoverMenu::new("model-switcher")
.menu(move |_window, _cx| Some(picker_view.clone()))
.trigger_with_tooltip(self.trigger, self.tooltip)
.trigger(self.trigger)
.attach(gpui::Corner::TopLeft)
.anchor(gpui::Corner::BottomLeft)
.offset(gpui::Point {

View File

@@ -359,7 +359,6 @@ fn providers_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema:
schemars::schema::SchemaObject {
enum_values: Some(vec![
"anthropic".into(),
"bedrock".into(),
"google".into(),
"lmstudio".into(),
"ollama".into(),
@@ -435,7 +434,7 @@ pub struct LegacyAssistantSettingsContent {
pub default_open_ai_model: Option<OpenAiModel>,
/// OpenAI API base URL to use when creating new chats.
///
/// Default: <https://api.openai.com/v1>
/// Default: https://api.openai.com/v1
pub openai_api_url: Option<String>,
}
@@ -513,7 +512,7 @@ mod tests {
AssistantSettings::get_global(cx).default_model,
LanguageModelSelection {
provider: "zed.dev".into(),
model: "claude-3-5-sonnet-latest".into(),
model: "claude-3-5-sonnet".into(),
}
);
});

View File

@@ -103,7 +103,7 @@ impl SlashCommand for ExtensionSlashCommand {
) -> Task<Result<Vec<ArgumentCompletion>>> {
let command = self.command.clone();
let arguments = arguments.to_owned();
cx.background_spawn(async move {
cx.background_executor().spawn(async move {
let completions = self
.extension
.complete_slash_command_argument(command, arguments)
@@ -135,7 +135,7 @@ impl SlashCommand for ExtensionSlashCommand {
) -> Task<SlashCommandResult> {
let command = self.command.clone();
let arguments = arguments.to_owned();
let output = cx.background_spawn(async move {
let output = cx.background_executor().spawn(async move {
let delegate =
delegate.map(|delegate| Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _);
let output = self

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