Compare commits
1 Commits
v0.122.2
...
views-post
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
809776f6bc |
46
.github/actions/check_style/action.yml
vendored
46
.github/actions/check_style/action.yml
vendored
@@ -2,29 +2,29 @@ name: "Check formatting"
|
||||
description: "Checks code formatting use cargo fmt"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: cargo fmt
|
||||
shell: bash -euxo pipefail {0}
|
||||
run: cargo fmt --all -- --check
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: cargo fmt
|
||||
shell: bash -euxo pipefail {0}
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
- name: cargo clippy
|
||||
shell: bash -euxo pipefail {0}
|
||||
# clippy.toml is not currently supporting specifying allowed lints
|
||||
# so specify those here, and disable the rest until Zed's workspace
|
||||
# will have more fixes & suppression for the standard lint set
|
||||
run: |
|
||||
cargo clippy --release --workspace --all-features --all-targets -- -A clippy::all -D clippy::dbg_macro -D clippy::todo
|
||||
cargo clippy -p gpui
|
||||
- name: cargo clippy
|
||||
shell: bash -euxo pipefail {0}
|
||||
# clippy.toml is not currently supporting specifying allowed lints
|
||||
# so specify those here, and disable the rest until Zed's workspace
|
||||
# will have more fixes & suppression for the standard lint set
|
||||
run: |
|
||||
cargo clippy --release --workspace --all-features --all-targets -- -A clippy::all -D clippy::dbg_macro -D clippy::todo
|
||||
cargo clippy -p gpui
|
||||
|
||||
- name: Find modified migrations
|
||||
shell: bash -euxo pipefail {0}
|
||||
run: |
|
||||
export SQUAWK_GITHUB_TOKEN=${{ github.token }}
|
||||
. ./script/squawk
|
||||
- name: Find modified migrations
|
||||
shell: bash -euxo pipefail {0}
|
||||
run: |
|
||||
export SQUAWK_GITHUB_TOKEN=${{ github.token }}
|
||||
. ./script/squawk
|
||||
|
||||
- uses: bufbuild/buf-setup-action@v1
|
||||
- uses: bufbuild/buf-breaking-action@v1
|
||||
with:
|
||||
input: "crates/rpc/proto/"
|
||||
against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=main,subdir=crates/rpc/proto/"
|
||||
- uses: bufbuild/buf-setup-action@v1
|
||||
- uses: bufbuild/buf-breaking-action@v1
|
||||
with:
|
||||
input: "crates/rpc/proto/"
|
||||
against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=main,subdir=crates/rpc/proto/"
|
||||
|
||||
2
.github/actions/run_tests/action.yml
vendored
2
.github/actions/run_tests/action.yml
vendored
@@ -10,7 +10,7 @@ runs:
|
||||
cargo install cargo-nextest
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
|
||||
6
.github/pull_request_template.md
vendored
6
.github/pull_request_template.md
vendored
@@ -2,8 +2,4 @@
|
||||
|
||||
Release Notes:
|
||||
|
||||
- Added/Fixed/Improved ... ([#<public_issue_number_if_exists>](https://github.com/zed-industries/zed/issues/<public_issue_number_if_exists>)).
|
||||
|
||||
**or**
|
||||
|
||||
- N/A
|
||||
- (Added|Fixed|Improved) ... ([#<public_issue_number_if_exists>](https://github.com/zed-industries/zed/issues/<public_issue_number_if_exists>)).
|
||||
|
||||
262
.github/workflows/ci.yml
vendored
262
.github/workflows/ci.yml
vendored
@@ -1,149 +1,149 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "v[0-9]+.[0-9]+.x"
|
||||
tags:
|
||||
- "v*"
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "v[0-9]+.[0-9]+.x"
|
||||
tags:
|
||||
- "v*"
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
|
||||
concurrency:
|
||||
# Allow only one workflow per any non-`main` branch.
|
||||
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
|
||||
cancel-in-progress: true
|
||||
# Allow only one workflow per any non-`main` branch.
|
||||
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUST_BACKTRACE: 1
|
||||
CARGO_TERM_COLOR: always
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
jobs:
|
||||
style:
|
||||
name: Check formatting, Clippy lints, and spelling
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- test
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
fetch-depth: 0
|
||||
style:
|
||||
name: Check formatting, Clippy lints, and spelling
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- test
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up default .cargo/config.toml
|
||||
run: cp ./.cargo/ci-config.toml ~/.cargo/config.toml
|
||||
- name: Set up default .cargo/config.toml
|
||||
run: cp ./.cargo/ci-config.toml ~/.cargo/config.toml
|
||||
|
||||
- name: Check spelling
|
||||
run: |
|
||||
if ! which typos > /dev/null; then
|
||||
cargo install typos-cli
|
||||
fi
|
||||
typos
|
||||
- name: Check spelling
|
||||
run: |
|
||||
if ! which typos > /dev/null; then
|
||||
cargo install typos-cli
|
||||
fi
|
||||
typos
|
||||
|
||||
- name: Run style checks
|
||||
uses: ./.github/actions/check_style
|
||||
- name: Run style checks
|
||||
uses: ./.github/actions/check_style
|
||||
|
||||
tests:
|
||||
name: Run tests
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- test
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
tests:
|
||||
name: Run tests
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- test
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Run tests
|
||||
uses: ./.github/actions/run_tests
|
||||
- name: Run tests
|
||||
uses: ./.github/actions/run_tests
|
||||
|
||||
- name: Build collab
|
||||
run: cargo build -p collab
|
||||
- name: Build collab
|
||||
run: cargo build -p collab
|
||||
|
||||
- name: Build other binaries
|
||||
run: cargo build --workspace --bins --all-features
|
||||
- name: Build other binaries
|
||||
run: cargo build --workspace --bins --all-features
|
||||
|
||||
bundle:
|
||||
name: Bundle app
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- bundle
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
|
||||
needs: tests
|
||||
bundle:
|
||||
name: Bundle app
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- bundle
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
|
||||
needs: tests
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
|
||||
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Limit target directory size
|
||||
run: script/clear-target-dir-if-larger-than 100
|
||||
|
||||
- name: Determine version and release channel
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
version=$(script/get-crate-version zed)
|
||||
channel=$(cat crates/zed/RELEASE_CHANNEL)
|
||||
echo "Publishing version: ${version} on release channel ${channel}"
|
||||
echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
|
||||
|
||||
expected_tag_name=""
|
||||
case ${channel} in
|
||||
stable)
|
||||
expected_tag_name="v${version}";;
|
||||
preview)
|
||||
expected_tag_name="v${version}-pre";;
|
||||
nightly)
|
||||
expected_tag_name="v${version}-nightly";;
|
||||
*)
|
||||
echo "can't publish a release on channel ${channel}"
|
||||
exit 1;;
|
||||
esac
|
||||
if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
|
||||
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Generate license file
|
||||
run: script/generate-licenses
|
||||
|
||||
- name: Create app bundle
|
||||
run: script/bundle
|
||||
|
||||
- name: Upload app bundle to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
|
||||
with:
|
||||
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
|
||||
path: target/release/Zed.dmg
|
||||
|
||||
- uses: softprops/action-gh-release@v1
|
||||
name: Upload app bundle to release
|
||||
if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
|
||||
with:
|
||||
draft: true
|
||||
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
|
||||
files: target/release/Zed.dmg
|
||||
body: ""
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
|
||||
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Limit target directory size
|
||||
run: script/clear-target-dir-if-larger-than 100
|
||||
|
||||
- name: Determine version and release channel
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
version=$(script/get-crate-version zed)
|
||||
channel=$(cat crates/zed/RELEASE_CHANNEL)
|
||||
echo "Publishing version: ${version} on release channel ${channel}"
|
||||
echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
|
||||
|
||||
expected_tag_name=""
|
||||
case ${channel} in
|
||||
stable)
|
||||
expected_tag_name="v${version}";;
|
||||
preview)
|
||||
expected_tag_name="v${version}-pre";;
|
||||
nightly)
|
||||
expected_tag_name="v${version}-nightly";;
|
||||
*)
|
||||
echo "can't publish a release on channel ${channel}"
|
||||
exit 1;;
|
||||
esac
|
||||
if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
|
||||
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Generate license file
|
||||
run: script/generate-licenses
|
||||
|
||||
- name: Create app bundle
|
||||
run: script/bundle
|
||||
|
||||
- name: Upload app bundle to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
|
||||
with:
|
||||
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
|
||||
path: target/release/Zed.dmg
|
||||
|
||||
- uses: softprops/action-gh-release@v1
|
||||
name: Upload app bundle to release
|
||||
if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
|
||||
with:
|
||||
draft: true
|
||||
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
|
||||
files: target/release/Zed.dmg
|
||||
body: ""
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
50
.github/workflows/danger.yml
vendored
50
.github/workflows/danger.yml
vendored
@@ -1,35 +1,35 @@
|
||||
name: Danger
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- edited
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- edited
|
||||
|
||||
jobs:
|
||||
danger:
|
||||
runs-on: ubuntu-latest
|
||||
danger:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v2.2.4
|
||||
with:
|
||||
version: 8
|
||||
- uses: pnpm/action-setup@v2.2.4
|
||||
with:
|
||||
version: 8
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "script/danger/pnpm-lock.yaml"
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "script/danger/pnpm-lock.yaml"
|
||||
|
||||
- run: pnpm install --dir script/danger
|
||||
- run: pnpm install --dir script/danger
|
||||
|
||||
- name: Run Danger
|
||||
run: pnpm run --dir script/danger danger ci
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Run Danger
|
||||
run: pnpm run --dir script/danger danger ci
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
52
.github/workflows/randomized_tests.yml
vendored
52
.github/workflows/randomized_tests.yml
vendored
@@ -3,35 +3,35 @@ name: Randomized Tests
|
||||
concurrency: randomized-tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- randomized-tests-runner
|
||||
# schedule:
|
||||
# - cron: '0 * * * *'
|
||||
push:
|
||||
branches:
|
||||
- randomized-tests-runner
|
||||
# schedule:
|
||||
# - cron: '0 * * * *'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUST_BACKTRACE: 1
|
||||
ZED_SERVER_URL: https://zed.dev
|
||||
CARGO_TERM_COLOR: always
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUST_BACKTRACE: 1
|
||||
ZED_SERVER_URL: https://zed.dev
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Run randomized tests
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- randomized-tests
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18"
|
||||
tests:
|
||||
name: Run randomized tests
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- randomized-tests
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Run randomized tests
|
||||
run: script/randomized-test-ci
|
||||
- name: Run randomized tests
|
||||
run: script/randomized-test-ci
|
||||
|
||||
6
.github/workflows/release_nightly.yml
vendored
6
.github/workflows/release_nightly.yml
vendored
@@ -16,7 +16,6 @@ env:
|
||||
jobs:
|
||||
style:
|
||||
name: Check formatting and Clippy lints
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- test
|
||||
@@ -33,7 +32,6 @@ jobs:
|
||||
|
||||
tests:
|
||||
name: Run tests
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- test
|
||||
@@ -50,7 +48,6 @@ jobs:
|
||||
|
||||
bundle:
|
||||
name: Bundle app
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- bundle
|
||||
@@ -62,10 +59,9 @@ jobs:
|
||||
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
|
||||
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ on:
|
||||
jobs:
|
||||
update_top_ranking_issues:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
|
||||
@@ -6,7 +6,6 @@ on:
|
||||
jobs:
|
||||
update_top_ranking_issues:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
|
||||
138
Cargo.lock
generated
138
Cargo.lock
generated
@@ -103,9 +103,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alacritty_terminal"
|
||||
version = "0.22.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc7ceabf6fc76511f616ca216b51398a2511f19ba9f71bcbd977999edff1b0d1"
|
||||
checksum = "35229555d7cc7e83392dfc27c96bec560b1076d756184893296cd60125f4a264"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"bitflags 2.4.1",
|
||||
@@ -441,18 +441,6 @@ dependencies = [
|
||||
"event-listener",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-native-tls"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"native-tls",
|
||||
"thiserror",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-net"
|
||||
version = "1.7.0"
|
||||
@@ -582,6 +570,19 @@ version = "4.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
|
||||
|
||||
[[package]]
|
||||
name = "async-tls"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f23d769dbf1838d5df5156e7b1ad404f4c463d1ac2c6aeb6cd943630f8a8400"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"rustls 0.19.1",
|
||||
"webpki",
|
||||
"webpki-roots 0.21.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.73"
|
||||
@@ -599,8 +600,7 @@ version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5682ea0913e5c20780fe5785abacb85a411e7437bf52a1bedb93ddb3972cb8dd"
|
||||
dependencies = [
|
||||
"async-native-tls",
|
||||
"async-std",
|
||||
"async-tls",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"log",
|
||||
@@ -2417,7 +2417,6 @@ dependencies = [
|
||||
"itertools 0.10.5",
|
||||
"language",
|
||||
"lazy_static",
|
||||
"linkify",
|
||||
"log",
|
||||
"lsp",
|
||||
"multi_buffer",
|
||||
@@ -3868,6 +3867,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json_comments"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dbbfed4e59ba9750e15ba154fdfd9329cee16ff3df539c2666b70f58cc32105"
|
||||
|
||||
[[package]]
|
||||
name = "jwt"
|
||||
version = "0.16.0"
|
||||
@@ -4136,15 +4141,6 @@ dependencies = [
|
||||
"safemem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linkify"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1dfa36d52c581e9ec783a7ce2a5e0143da6237be5811a0b3153fedfdbe9f780"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linkme"
|
||||
version = "0.3.17"
|
||||
@@ -6065,7 +6061,6 @@ dependencies = [
|
||||
"editor",
|
||||
"gpui",
|
||||
"search",
|
||||
"settings",
|
||||
"ui",
|
||||
"workspace",
|
||||
]
|
||||
@@ -6736,6 +6731,19 @@ dependencies = [
|
||||
"rustix 0.38.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.19.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"log",
|
||||
"ring",
|
||||
"sct 0.6.1",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.7"
|
||||
@@ -6744,7 +6752,7 @@ checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
"sct 0.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6887,6 +6895,16 @@ dependencies = [
|
||||
"sha2 0.9.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
@@ -7530,7 +7548,6 @@ name = "sqlez"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collections",
|
||||
"futures 0.3.28",
|
||||
"indoc",
|
||||
"lazy_static",
|
||||
@@ -7609,7 +7626,7 @@ dependencies = [
|
||||
"paste",
|
||||
"percent-encoding",
|
||||
"rust_decimal",
|
||||
"rustls",
|
||||
"rustls 0.21.7",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -7623,7 +7640,7 @@ dependencies = [
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid 1.4.1",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.24.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8106,7 +8123,6 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"alacritty_terminal",
|
||||
"anyhow",
|
||||
"collections",
|
||||
"db",
|
||||
"dirs 4.0.0",
|
||||
"futures 0.3.28",
|
||||
@@ -8137,7 +8153,6 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"client",
|
||||
"collections",
|
||||
"db",
|
||||
"dirs 4.0.0",
|
||||
"editor",
|
||||
@@ -8202,7 +8217,6 @@ name = "theme"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collections",
|
||||
"color",
|
||||
"derive_more",
|
||||
"fs",
|
||||
@@ -8237,6 +8251,7 @@ dependencies = [
|
||||
"gpui",
|
||||
"indexmap 1.9.3",
|
||||
"indoc",
|
||||
"json_comments",
|
||||
"log",
|
||||
"palette",
|
||||
"pathfinder_color",
|
||||
@@ -8244,7 +8259,6 @@ dependencies = [
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_json_lenient",
|
||||
"simplelog",
|
||||
"strum",
|
||||
"theme",
|
||||
@@ -8733,15 +8747,6 @@ dependencies = [
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-beancount"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/polarmutex/tree-sitter-beancount?rev=da1bf8c6eb0ae7a97588affde7227630bcd678b6#da1bf8c6eb0ae7a97588affde7227630bcd678b6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-c"
|
||||
version = "0.20.6"
|
||||
@@ -8880,15 +8885,6 @@ dependencies = [
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-hcl"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/MichaHoffmann/tree-sitter-hcl?rev=v1.1.0#636dbe70301ecbab8f353c8c78b3406fe4f185f5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-heex"
|
||||
version = "0.0.1"
|
||||
@@ -8964,15 +8960,6 @@ dependencies = [
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-ocaml"
|
||||
version = "0.20.4"
|
||||
source = "git+https://github.com/tree-sitter/tree-sitter-ocaml?rev=4abfdc1c7af2c6c77a370aee974627be1c285b3b#4abfdc1c7af2c6c77a370aee974627be1c285b3b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-php"
|
||||
version = "0.21.1"
|
||||
@@ -9142,7 +9129,6 @@ dependencies = [
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"native-tls",
|
||||
"rand 0.8.5",
|
||||
"sha-1 0.9.8",
|
||||
"thiserror",
|
||||
@@ -9346,7 +9332,6 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"backtrace",
|
||||
"collections",
|
||||
"dirs 3.0.2",
|
||||
"futures 0.3.28",
|
||||
"git2",
|
||||
@@ -9851,6 +9836,25 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.24.0"
|
||||
@@ -10297,7 +10301,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.122.2"
|
||||
version = "0.122.0"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"ai",
|
||||
@@ -10340,7 +10344,6 @@ dependencies = [
|
||||
"indexmap 1.9.3",
|
||||
"install_cli",
|
||||
"isahc",
|
||||
"itertools 0.11.0",
|
||||
"journal",
|
||||
"language",
|
||||
"language_selector",
|
||||
@@ -10392,7 +10395,6 @@ dependencies = [
|
||||
"toml",
|
||||
"tree-sitter",
|
||||
"tree-sitter-bash",
|
||||
"tree-sitter-beancount",
|
||||
"tree-sitter-c",
|
||||
"tree-sitter-c-sharp",
|
||||
"tree-sitter-cpp",
|
||||
@@ -10408,7 +10410,6 @@ dependencies = [
|
||||
"tree-sitter-gomod",
|
||||
"tree-sitter-gowork",
|
||||
"tree-sitter-haskell",
|
||||
"tree-sitter-hcl",
|
||||
"tree-sitter-heex",
|
||||
"tree-sitter-html",
|
||||
"tree-sitter-json 0.20.0",
|
||||
@@ -10416,7 +10417,6 @@ dependencies = [
|
||||
"tree-sitter-markdown",
|
||||
"tree-sitter-nix",
|
||||
"tree-sitter-nu",
|
||||
"tree-sitter-ocaml",
|
||||
"tree-sitter-php",
|
||||
"tree-sitter-proto",
|
||||
"tree-sitter-purescript",
|
||||
|
||||
103
Cargo.toml
103
Cargo.toml
@@ -92,90 +92,6 @@ default-members = ["crates/zed"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
activity_indicator = { path = "crates/activity_indicator" }
|
||||
ai = { path = "crates/ai" }
|
||||
assets = { path = "crates/assets" }
|
||||
assistant = { path = "crates/assistant" }
|
||||
audio = { path = "crates/audio" }
|
||||
auto_update = { path = "crates/auto_update" }
|
||||
breadcrumbs = { path = "crates/breadcrumbs" }
|
||||
call = { path = "crates/call" }
|
||||
channel = { path = "crates/channel" }
|
||||
cli = { path = "crates/cli" }
|
||||
client = { path = "crates/client" }
|
||||
clock = { path = "crates/clock" }
|
||||
collab = { path = "crates/collab" }
|
||||
collab_ui = { path = "crates/collab_ui" }
|
||||
collections = { path = "crates/collections" }
|
||||
color = { path = "crates/color" }
|
||||
command_palette = { path = "crates/command_palette" }
|
||||
copilot = { path = "crates/copilot" }
|
||||
copilot_ui = { path = "crates/copilot_ui" }
|
||||
db = { path = "crates/db" }
|
||||
diagnostics = { path = "crates/diagnostics" }
|
||||
editor = { path = "crates/editor" }
|
||||
feature_flags = { path = "crates/feature_flags" }
|
||||
feedback = { path = "crates/feedback" }
|
||||
file_finder = { path = "crates/file_finder" }
|
||||
fs = { path = "crates/fs" }
|
||||
fsevent = { path = "crates/fsevent" }
|
||||
fuzzy = { path = "crates/fuzzy" }
|
||||
git = { path = "crates/git" }
|
||||
go_to_line = { path = "crates/go_to_line" }
|
||||
gpui = { path = "crates/gpui" }
|
||||
gpui_macros = { path = "crates/gpui_macros" }
|
||||
install_cli = { path = "crates/install_cli" }
|
||||
journal = { path = "crates/journal" }
|
||||
language = { path = "crates/language" }
|
||||
language_selector = { path = "crates/language_selector" }
|
||||
language_tools = { path = "crates/language_tools" }
|
||||
live_kit_client = { path = "crates/live_kit_client" }
|
||||
live_kit_server = { path = "crates/live_kit_server" }
|
||||
lsp = { path = "crates/lsp" }
|
||||
markdown_preview = { path = "crates/markdown_preview" }
|
||||
media = { path = "crates/media" }
|
||||
menu = { path = "crates/menu" }
|
||||
multi_buffer = { path = "crates/multi_buffer" }
|
||||
node_runtime = { path = "crates/node_runtime" }
|
||||
notifications = { path = "crates/notifications" }
|
||||
outline = { path = "crates/outline" }
|
||||
picker = { path = "crates/picker" }
|
||||
plugin = { path = "crates/plugin" }
|
||||
plugin_macros = { path = "crates/plugin_macros" }
|
||||
prettier = { path = "crates/prettier" }
|
||||
project = { path = "crates/project" }
|
||||
project_panel = { path = "crates/project_panel" }
|
||||
project_symbols = { path = "crates/project_symbols" }
|
||||
quick_action_bar = { path = "crates/quick_action_bar" }
|
||||
recent_projects = { path = "crates/recent_projects" }
|
||||
release_channel = { path = "crates/release_channel" }
|
||||
rich_text = { path = "crates/rich_text" }
|
||||
rope = { path = "crates/rope" }
|
||||
rpc = { path = "crates/rpc" }
|
||||
search = { path = "crates/search" }
|
||||
semantic_index = { path = "crates/semantic_index" }
|
||||
settings = { path = "crates/settings" }
|
||||
snippet = { path = "crates/snippet" }
|
||||
sqlez = { path = "crates/sqlez" }
|
||||
sqlez_macros = { path = "crates/sqlez_macros" }
|
||||
story = { path = "crates/story" }
|
||||
storybook = { path = "crates/storybook" }
|
||||
sum_tree = { path = "crates/sum_tree" }
|
||||
terminal = { path = "crates/terminal" }
|
||||
terminal_view = { path = "crates/terminal_view" }
|
||||
text = { path = "crates/text" }
|
||||
theme = { path = "crates/theme" }
|
||||
theme_importer = { path = "crates/theme_importer" }
|
||||
theme_selector = { path = "crates/theme_selector" }
|
||||
ui = { path = "crates/ui" }
|
||||
util = { path = "crates/util" }
|
||||
vcs_menu = { path = "crates/vcs_menu" }
|
||||
vim = { path = "crates/vim" }
|
||||
welcome = { path = "crates/welcome" }
|
||||
workspace = { path = "crates/workspace" }
|
||||
zed = { path = "crates/zed" }
|
||||
zed_actions = { path = "crates/zed_actions" }
|
||||
|
||||
anyhow = "1.0.57"
|
||||
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
||||
async-trait = "0.1"
|
||||
@@ -184,14 +100,11 @@ ctor = "0.2.6"
|
||||
derive_more = "0.99.17"
|
||||
env_logger = "0.9"
|
||||
futures = "0.3"
|
||||
git2 = { version = "0.15", default-features = false }
|
||||
git2 = { version = "0.15", default-features = false}
|
||||
globset = "0.4"
|
||||
indoc = "1"
|
||||
# We explicitly disable a http2 support in isahc.
|
||||
isahc = { version = "1.7.2", default-features = false, features = [
|
||||
"static-curl",
|
||||
"text-decoding",
|
||||
] }
|
||||
isahc = { version = "1.7.2", default-features = false, features = ["static-curl", "text-decoding"] }
|
||||
lazy_static = "1.4.0"
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
|
||||
ordered-float = "2.1.1"
|
||||
@@ -209,10 +122,7 @@ schemars = "0.8"
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
serde_derive = { version = "1.0", features = ["deserialize_in_place"] }
|
||||
serde_json = { version = "1.0", features = ["preserve_order", "raw_value"] }
|
||||
serde_json_lenient = { version = "0.1", features = [
|
||||
"preserve_order",
|
||||
"raw_value",
|
||||
] }
|
||||
serde_json_lenient = { version = "0.1", features = ["preserve_order", "raw_value"] }
|
||||
serde_repr = "0.1"
|
||||
smallvec = { version = "1.6", features = ["union"] }
|
||||
smol = "1.2"
|
||||
@@ -225,10 +135,9 @@ time = { version = "0.3", features = ["serde", "serde-well-known"] }
|
||||
toml = "0.5"
|
||||
tree-sitter = { version = "0.20", features = ["wasm"] }
|
||||
tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "7331995b19b8f8aba2d5e26deb51d2195c18bc94" }
|
||||
tree-sitter-beancount = { git = "https://github.com/polarmutex/tree-sitter-beancount", rev = "da1bf8c6eb0ae7a97588affde7227630bcd678b6" }
|
||||
tree-sitter-c = "0.20.1"
|
||||
tree-sitter-c-sharp = { git = "https://github.com/tree-sitter/tree-sitter-c-sharp", rev = "dd5e59721a5f8dae34604060833902b882023aaf" }
|
||||
tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev = "f44509141e7e483323d2ec178f2d2e6c0fc041c1" }
|
||||
tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev="f44509141e7e483323d2ec178f2d2e6c0fc041c1" }
|
||||
tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" }
|
||||
tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "a2861e88a730287a60c11ea9299c033c7d076e30" }
|
||||
tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40" }
|
||||
@@ -241,7 +150,6 @@ tree-sitter-go = { git = "https://github.com/tree-sitter/tree-sitter-go", rev =
|
||||
tree-sitter-gomod = { git = "https://github.com/camdencheek/tree-sitter-go-mod" }
|
||||
tree-sitter-gowork = { git = "https://github.com/d1y/tree-sitter-go-work" }
|
||||
tree-sitter-haskell = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "cf98de23e4285b8e6bcb57b050ef2326e2cc284b" }
|
||||
tree-sitter-hcl = { git = "https://github.com/MichaHoffmann/tree-sitter-hcl", rev = "v1.1.0" }
|
||||
tree-sitter-heex = { git = "https://github.com/phoenixframework/tree-sitter-heex", rev = "2e1348c3cf2c9323e87c2744796cf3f3868aa82a" }
|
||||
tree-sitter-html = "0.19.0"
|
||||
tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "40a81c01a40ac48744e0c8ccabbaba1920441199" }
|
||||
@@ -249,9 +157,8 @@ tree-sitter-lua = "0.0.14"
|
||||
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
|
||||
tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "66e3e9ce9180ae08fc57372061006ef83f0abde7" }
|
||||
tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "26bbaecda0039df4067861ab38ea8ea169f7f5aa" }
|
||||
tree-sitter-ocaml = { git = "https://github.com/tree-sitter/tree-sitter-ocaml", rev = "4abfdc1c7af2c6c77a370aee974627be1c285b3b" }
|
||||
tree-sitter-php = "0.21.1"
|
||||
tree-sitter-proto = { git = "https://github.com/rewinfrey/tree-sitter-proto", rev = "36d54f288aee112f13a67b550ad32634d0c2cb52" }
|
||||
tree-sitter-proto = {git = "https://github.com/rewinfrey/tree-sitter-proto", rev = "36d54f288aee112f13a67b550ad32634d0c2cb52" }
|
||||
tree-sitter-purescript = { git = "https://github.com/ivanmoreau/tree-sitter-purescript", rev = "a37140f0c7034977b90faa73c94fcb8a5e45ed08" }
|
||||
tree-sitter-python = "0.20.2"
|
||||
tree-sitter-racket = { git = "https://github.com/zed-industries/tree-sitter-racket", rev = "eb010cf2c674c6fd9a6316a84e28ef90190fe51a" }
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.7295 12.1981L7.17677 7.64544C7.07914 7.5478 6.92085 7.5478 6.82322 7.64544L2.27053 12.1981C2.11304 12.3556 2.22458 12.6249 2.4473 12.6249H11.5527C11.7754 12.6249 11.887 12.3556 11.7295 12.1981Z" fill="black" fill-opacity="0.9"/>
|
||||
<path d="M1.80178 11.7294L6.35447 7.17668C6.4521 7.07905 6.4521 6.92076 6.35447 6.82312L1.80178 2.27043C1.64429 2.11294 1.375 2.22448 1.375 2.44721L1.375 11.5526C1.375 11.7753 1.64428 11.8869 1.80178 11.7294Z" fill="black" fill-opacity="0.9"/>
|
||||
<path d="M9.98928 9.16694L11.9794 7.17751C12.0771 7.0799 12.0771 6.92161 11.9795 6.82396L9.98928 4.833C9.89165 4.73534 9.73333 4.73532 9.63569 4.83297L7.64553 6.82313C7.5479 6.92076 7.5479 7.07905 7.64553 7.17668L9.63575 9.16691C9.73337 9.26453 9.89164 9.26455 9.98928 9.16694Z" fill="black" fill-opacity="0.9"/>
|
||||
<path d="M7.89553 1.80168L12.1982 6.10438C12.3557 6.26187 12.625 6.15033 12.625 5.9276V2.37491C12.625 1.82262 12.1773 1.37491 11.625 1.37491H8.0723C7.84958 1.37491 7.73804 1.64419 7.89553 1.80168Z" fill="black" fill-opacity="0.6"/>
|
||||
<path d="M8.73976 4.18772L5.25981 4.1895C5.03708 4.18962 4.92567 4.45896 5.08325 4.61637L6.82322 6.35456C6.92087 6.45211 7.07909 6.45207 7.17669 6.35447L8.91666 4.61449C9.0742 4.45696 8.96255 4.1876 8.73976 4.18772Z" fill="black" fill-opacity="0.6"/>
|
||||
<path d="M8.1147 3.55936L4.13431 3.55936C4.06801 3.55936 4.00442 3.53302 3.95753 3.48614L2.27057 1.79918C2.11308 1.64169 2.22462 1.37241 2.44735 1.37241L6.42774 1.37241C6.49405 1.37241 6.55763 1.39874 6.60452 1.44563L8.29148 3.13258C8.44897 3.29007 8.33743 3.55936 8.1147 3.55936Z" fill="black" fill-opacity="0.6"/>
|
||||
<path d="M12.625 8.07221V11.5526C12.625 11.7753 12.3557 11.8869 12.1982 11.7294L10.458 9.98918C10.3604 9.89155 10.3604 9.73326 10.458 9.63563L12.1982 7.89544C12.3557 7.73794 12.625 7.84949 12.625 8.07221Z" fill="black" fill-opacity="0.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.9 KiB |
@@ -25,7 +25,6 @@
|
||||
"doc": "document",
|
||||
"docx": "document",
|
||||
"eex": "elixir",
|
||||
"elm": "elm",
|
||||
"erl": "erlang",
|
||||
"escript": "erlang",
|
||||
"eslintrc": "eslint",
|
||||
@@ -70,8 +69,6 @@
|
||||
"mdb": "storage",
|
||||
"mdf": "storage",
|
||||
"mdx": "document",
|
||||
"ml": "ocaml",
|
||||
"mli": "ocaml",
|
||||
"mp3": "audio",
|
||||
"mp4": "video",
|
||||
"myd": "storage",
|
||||
@@ -88,7 +85,6 @@
|
||||
"pptx": "document",
|
||||
"prettierignore": "prettier",
|
||||
"prettierrc": "prettier",
|
||||
"prisma": "prisma",
|
||||
"profile": "terminal",
|
||||
"ps1": "terminal",
|
||||
"psd": "image",
|
||||
@@ -120,8 +116,8 @@
|
||||
"xlsx": "document",
|
||||
"xml": "template",
|
||||
"xrl": "erlang",
|
||||
"yaml": "settings",
|
||||
"yml": "settings",
|
||||
"yaml": "yaml",
|
||||
"yml": "yaml",
|
||||
"yrl": "erlang",
|
||||
"zlogin": "terminal",
|
||||
"zsh": "terminal",
|
||||
@@ -156,9 +152,6 @@
|
||||
"elixir": {
|
||||
"icon": "icons/file_icons/elixir.svg"
|
||||
},
|
||||
"elm": {
|
||||
"icon": "icons/file_icons/elm.svg"
|
||||
},
|
||||
"erlang": {
|
||||
"icon": "icons/file_icons/erlang.svg"
|
||||
},
|
||||
@@ -186,21 +179,18 @@
|
||||
"log": {
|
||||
"icon": "icons/file_icons/info.svg"
|
||||
},
|
||||
"ocaml": {
|
||||
"icon": "icons/file_icons/ocaml.svg"
|
||||
},
|
||||
"phoenix": {
|
||||
"icon": "icons/file_icons/phoenix.svg"
|
||||
},
|
||||
"php": {
|
||||
"icon": "icons/file_icons/php.svg"
|
||||
},
|
||||
"yaml": {
|
||||
"icon": "icons/file_icons/yaml.svg"
|
||||
},
|
||||
"prettier": {
|
||||
"icon": "icons/file_icons/prettier.svg"
|
||||
},
|
||||
"prisma": {
|
||||
"icon": "icons/file_icons/prisma.svg"
|
||||
},
|
||||
"python": {
|
||||
"icon": "icons/file_icons/python.svg"
|
||||
},
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.73843 11.709C6.70584 11.6334 6.60683 11.4367 6.55712 11.3736C6.44917 11.2362 6.42396 11.2258 6.39221 11.0523C6.33703 10.7501 6.19094 10.202 6.01879 9.82381C5.92987 9.62863 5.78201 9.46467 5.64665 9.32312C5.52847 9.19895 5.26214 8.99002 5.2157 9.00037C4.7807 9.09487 4.64576 9.55902 4.44115 9.92673C4.32795 10.1301 4.208 10.3031 4.1188 10.5195C4.03641 10.7184 4.04373 10.9387 3.90268 11.1095C3.75801 11.2849 3.66398 11.4715 3.59311 11.6981C3.57968 11.7412 3.54148 12.1939 3.5 12.3006L4.14649 12.2511C4.74896 12.2958 4.57496 12.547 5.51526 12.4922L7 12.4423C6.95398 12.2942 6.89056 12.1228 6.86613 12.067C6.82472 11.9732 6.77267 11.7897 6.73843 11.709Z" fill="black"/>
|
||||
<path d="M8.72454 8.42043C8.61775 8.50889 8.40904 8.72165 7.95506 8.8021C7.75133 8.83825 7.56076 8.84122 7.35158 8.82925C7.24918 8.8236 7.15263 8.81758 7.04997 8.81605C6.9895 8.81552 6.78663 8.80812 6.79667 8.83039L6.77408 8.89506C6.7776 8.91633 6.78497 8.96949 6.78703 8.98237C6.79534 9.03461 6.79766 9.07617 6.79939 9.12421C6.80252 9.22297 6.79228 9.32592 6.79667 9.42559C6.80577 9.63232 6.87262 9.82076 6.88106 10.0293C6.89029 10.2615 6.99037 10.5072 7.08718 10.6969C7.12393 10.7691 7.17988 10.7773 7.20426 10.8663C7.23284 10.9681 7.20579 11.0762 7.21968 11.1848C7.27417 11.6058 7.37982 12.0459 7.54501 12.4259C7.54621 12.4291 7.54747 12.4325 7.54893 12.4354C7.75293 12.3961 7.95732 12.3119 8.22239 12.2669C8.70839 12.1841 9.3843 12.2268 9.81848 12.1801C10.9171 12.0616 11.5133 12.6972 12.5 12.4367V3.09052C12.5 2.21217 11.8798 1.5 11.1142 1.5H2.88578C2.1205 1.5 1.5 2.21217 1.5 3.09052V6.5608C1.69828 6.47851 1.98348 5.99435 2.07285 5.87661C2.2292 5.67071 2.25758 5.40808 2.33546 5.24267C2.51281 4.86596 2.54331 4.60691 2.94645 4.60691C3.13436 4.60691 3.20899 4.65663 3.3361 4.85238C3.42454 4.98851 3.57731 5.24 3.64881 5.40815C3.73134 5.60215 3.86583 5.86464 3.92497 5.91763C3.96876 5.95698 4.01221 5.9865 4.05275 6.00396C4.11813 6.0321 4.17222 5.98047 4.21595 5.94051C4.27176 5.8895 4.29582 5.78556 4.34751 5.64692C4.422 5.44689 4.5032 5.20721 4.54938 5.12356C4.62932 4.97897 4.65656 4.80739 4.74288 4.72427C4.8702 4.60172 5.03632 4.59311 5.08203 4.58274C5.33779 4.52478 5.45408 4.72419 5.58006 4.85315C5.66253 4.93764 5.77522 5.10785 5.85523 5.33594C5.91776 5.51408 5.99736 5.67887 6.03065 5.78174C6.06281 5.88103 6.14222 6.04018 6.18926 6.23098C6.23199 6.40424 6.34635 6.537 6.3898 6.61936C6.3898 6.61936 6.45632 6.83319 6.86079 7.02864C6.9485 7.07104 7.12579 7.13998 7.23157 7.18413C7.40733 7.25741 7.57757 7.24788 7.79432 7.21807C7.94888 7.21807 8.03261 6.96123 8.10284 6.75556C8.14437 6.634 8.18418 6.28566 8.21129 6.18675C8.23754 6.09051 8.17614 6.01608 8.22843 5.93174C8.28956 5.83329 8.32591 5.82796 8.3612 5.69961C8.43701 5.42478 8.87524 5.4109 9.12156 5.4109C9.32689 5.4109 9.30078 5.63967 9.6491 5.56143C9.84858 5.51652 10.0408 5.59094 10.2526 5.65531C10.4309 5.7096 10.5986 5.77145 10.699 5.90642C10.764 5.99382 10.9254 6.43169 10.761 6.45037C10.7768 6.47257 10.7884 6.5126 10.8179 6.53456C10.7813 6.69974 10.622 6.58207 10.5335 6.56087C10.4142 6.5325 10.33 6.56514 10.2133 6.6244C10.0138 6.72635 9.72206 6.71446 9.5483 6.88055C9.40085 7.02132 9.40111 7.33558 9.33234 7.51166C9.33234 7.51166 9.14137 8.07551 8.72454 8.42043Z" fill="black"/>
|
||||
<path d="M3.6514 8.80413C3.57333 8.79137 3.50083 8.77702 3.425 8.75238C3.28339 8.70644 3.12867 8.66165 2.9892 8.60788C2.90451 8.57488 2.62239 8.41409 2.5611 8.36877C2.41737 8.26211 2.32191 7.97231 2.20955 8.00214C2.13782 8.02098 2.06795 8.06058 2.02333 8.17701C1.98692 8.27196 1.97457 8.43521 1.94936 8.54469C1.92011 8.67177 1.86959 8.7904 1.82536 8.91149C1.74401 9.13362 1.59759 9.33453 1.5345 9.55093C1.52181 9.59546 1.51055 9.64527 1.5 9.6972V10.5274V11.9637V12.1713C1.57359 12.1915 1.65057 12.2164 1.73674 12.2535C2.37264 12.5265 2.52781 12.5497 3.15152 12.4348L3.21002 12.4223C3.25775 12.2625 3.2946 11.718 3.32555 11.5494C3.34966 11.4202 3.38279 11.3173 3.39537 11.1853C3.40723 11.06 3.39427 10.9406 3.3876 10.8267C3.37011 10.5414 3.51669 10.4395 3.58667 10.1945C3.64976 9.97283 3.68617 9.7206 3.73839 9.49399C3.78847 9.27653 3.86665 8.96922 4 8.85975C3.98382 8.82938 3.72144 8.81539 3.6514 8.80413Z" fill="black"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -1,6 +0,0 @@
|
||||
<svg width="14" height="14" viewBox="
|
||||
0 0 425 512" xmlns="http://www.w3.org/2000/svg" fill="#000000
|
||||
">
|
||||
<path
|
||||
d="m381.38934 405.88714-229.67062 67.92744c-7.01651 2.07778-13.74132-3.99173-12.2669-11.07217l82.04834-392.9335c1.53436-7.352147 11.69152-8.514905 14.89609-1.710173l151.9177 322.59543c2.86494 6.08949-.40357 13.26702-6.92461 15.19297zm39.38512-16.02808-175.89887-373.53306c-11.59465-21.691431-39.0351-20.904032-49.75484-2.749064l-190.77231 308.99c-5.9096786 9.63371-5.7938027 21.50903.3356409 31.01887l93.252489 144.4589c9.615412 11.46292 18.506512 16.87006 33.692012 12.37878l270.68561-80.05849c18.03265-5.40039 26.72265-22.82202 18.46027-40.50593z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 680 B |
1
assets/icons/file_icons/yaml.svg
Normal file
1
assets/icons/file_icons/yaml.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="457px" height="512px"><polygon points="342.0159302,0 457,0 114.9831009,512 0,512 171.0082092,256 0,0 114.9831009,0 228.4997559,169.9342041 "/></svg>
|
||||
|
After Width: | Height: | Size: 209 B |
@@ -415,15 +415,7 @@
|
||||
"cmd-?": "assistant::ToggleFocus",
|
||||
"cmd-alt-s": "workspace::SaveAll",
|
||||
"cmd-k m": "language_selector::Toggle",
|
||||
"escape": "workspace::Unfollow",
|
||||
"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"]
|
||||
"escape": "workspace::Unfollow"
|
||||
}
|
||||
},
|
||||
// Bindings from Sublime Text
|
||||
@@ -449,6 +441,18 @@
|
||||
"ctrl-alt-shift-f": "editor::SelectToNextSubwordEnd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"bindings": {
|
||||
"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"]
|
||||
}
|
||||
},
|
||||
// Bindings from Atom
|
||||
{
|
||||
"context": "Pane",
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
"shift-alt-up": "editor::MoveLineUp",
|
||||
"shift-alt-down": "editor::MoveLineDown",
|
||||
"cmd-alt-l": "editor::Format",
|
||||
"shift-f6": "editor::Rename",
|
||||
"cmd-[": "pane::GoBack",
|
||||
"cmd-]": "pane::GoForward",
|
||||
"alt-f7": "editor::FindAllReferences",
|
||||
@@ -81,18 +80,10 @@
|
||||
"cmd-6": "diagnostics::Deploy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Pane",
|
||||
"bindings": {
|
||||
"cmd-alt-left": "pane::GoBack",
|
||||
"cmd-alt-right": "pane::GoForward"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ProjectPanel",
|
||||
"bindings": {
|
||||
"enter": "project_panel::Open",
|
||||
"shift-f6": "project_panel::Rename"
|
||||
"enter": "project_panel::Open"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -284,8 +284,7 @@
|
||||
"ctrl-w o": "workspace::CloseInactiveTabsAndPanes",
|
||||
"ctrl-w ctrl-o": "workspace::CloseInactiveTabsAndPanes",
|
||||
"ctrl-w n": ["workspace::NewFileInDirection", "Up"],
|
||||
"ctrl-w ctrl-n": ["workspace::NewFileInDirection", "Up"],
|
||||
"-": "pane::RevealInProjectPanel"
|
||||
"ctrl-w ctrl-n": ["workspace::NewFileInDirection", "Up"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -503,5 +502,18 @@
|
||||
"enter": "vim::SearchSubmit",
|
||||
"escape": "buffer_search::Dismiss"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Dock",
|
||||
"bindings": {
|
||||
"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 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"]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -104,17 +104,8 @@
|
||||
"show_whitespaces": "selection",
|
||||
// Settings related to calls in Zed
|
||||
"calls": {
|
||||
// Join calls with the microphone live by default
|
||||
"mute_on_join": false,
|
||||
// Share your project when you are the first to join a channel
|
||||
"share_on_join": true
|
||||
},
|
||||
// Toolbar related settings
|
||||
"toolbar": {
|
||||
// Whether to show breadcrumbs.
|
||||
"breadcrumbs": true,
|
||||
// Whether to show quick action buttons.
|
||||
"quick_actions": true
|
||||
// Join calls with the microphone muted by default
|
||||
"mute_on_join": false
|
||||
},
|
||||
// Scrollbar related settings
|
||||
"scrollbar": {
|
||||
@@ -136,12 +127,8 @@
|
||||
// Whether to show selections in the scrollbar.
|
||||
"selections": true,
|
||||
// Whether to show symbols selections in the scrollbar.
|
||||
"symbols_selections": true,
|
||||
// Whether to show diagnostic indicators in the scrollbar.
|
||||
"diagnostics": true
|
||||
"symbols_selections": true
|
||||
},
|
||||
// The number of lines to keep above/below the cursor when scrolling.
|
||||
"vertical_scroll_margin": 3,
|
||||
"relative_line_numbers": false,
|
||||
// When to populate a new search's query based on the text under the cursor.
|
||||
// This setting can take the following three values:
|
||||
@@ -498,9 +485,6 @@
|
||||
"JavaScript": {
|
||||
"tab_size": 2
|
||||
},
|
||||
"Terraform": {
|
||||
"tab_size": 2
|
||||
},
|
||||
"TypeScript": {
|
||||
"tab_size": 2
|
||||
},
|
||||
@@ -512,12 +496,6 @@
|
||||
},
|
||||
"JSON": {
|
||||
"tab_size": 2
|
||||
},
|
||||
"OCaml": {
|
||||
"tab_size": 2
|
||||
},
|
||||
"OCaml Interface": {
|
||||
"tab_size": 2
|
||||
}
|
||||
},
|
||||
// Zed's Prettier integration settings.
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#21242bff",
|
||||
"tab.inactive_background": "#21242bff",
|
||||
"tab.active_background": "#1e2025ff",
|
||||
"search.match_background": "#11a79366",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#21242bff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#221f26ff",
|
||||
"tab.inactive_background": "#221f26ff",
|
||||
"tab.active_background": "#19171cff",
|
||||
"search.match_background": "#576dda66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#221f26ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -426,7 +426,7 @@
|
||||
"tab_bar.background": "#e6e3ebff",
|
||||
"tab.inactive_background": "#e6e3ebff",
|
||||
"tab.active_background": "#efecf4ff",
|
||||
"search.match_background": "#586dda66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#e6e3ebff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -810,7 +810,7 @@
|
||||
"tab_bar.background": "#262622ff",
|
||||
"tab.inactive_background": "#262622ff",
|
||||
"tab.active_background": "#20201dff",
|
||||
"search.match_background": "#6684e066",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#262622ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -1194,7 +1194,7 @@
|
||||
"tab_bar.background": "#eeebd7ff",
|
||||
"tab.inactive_background": "#eeebd7ff",
|
||||
"tab.active_background": "#fefbecff",
|
||||
"search.match_background": "#6784e066",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#eeebd7ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -1578,7 +1578,7 @@
|
||||
"tab_bar.background": "#2c2b23ff",
|
||||
"tab.inactive_background": "#2c2b23ff",
|
||||
"tab.active_background": "#22221bff",
|
||||
"search.match_background": "#37a16666",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#2c2b23ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -1962,7 +1962,7 @@
|
||||
"tab_bar.background": "#ebeae3ff",
|
||||
"tab.inactive_background": "#ebeae3ff",
|
||||
"tab.active_background": "#f4f3ecff",
|
||||
"search.match_background": "#38a16666",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#ebeae3ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -2346,7 +2346,7 @@
|
||||
"tab_bar.background": "#27211eff",
|
||||
"tab.inactive_background": "#27211eff",
|
||||
"tab.active_background": "#1b1918ff",
|
||||
"search.match_background": "#417ee666",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#27211eff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -2730,7 +2730,7 @@
|
||||
"tab_bar.background": "#e9e6e4ff",
|
||||
"tab.inactive_background": "#e9e6e4ff",
|
||||
"tab.active_background": "#f0eeedff",
|
||||
"search.match_background": "#417ee666",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#e9e6e4ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -3114,7 +3114,7 @@
|
||||
"tab_bar.background": "#252025ff",
|
||||
"tab.inactive_background": "#252025ff",
|
||||
"tab.active_background": "#1b181bff",
|
||||
"search.match_background": "#526aeb66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#252025ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -3498,7 +3498,7 @@
|
||||
"tab_bar.background": "#e0d5e0ff",
|
||||
"tab.inactive_background": "#e0d5e0ff",
|
||||
"tab.active_background": "#f7f3f7ff",
|
||||
"search.match_background": "#526aeb66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#e0d5e0ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -3882,7 +3882,7 @@
|
||||
"tab_bar.background": "#1c2529ff",
|
||||
"tab.inactive_background": "#1c2529ff",
|
||||
"tab.active_background": "#161b1dff",
|
||||
"search.match_background": "#277fad66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#1c2529ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -4266,7 +4266,7 @@
|
||||
"tab_bar.background": "#cdeaf9ff",
|
||||
"tab.inactive_background": "#cdeaf9ff",
|
||||
"tab.active_background": "#ebf8ffff",
|
||||
"search.match_background": "#277fad66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#cdeaf9ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -4650,7 +4650,7 @@
|
||||
"tab_bar.background": "#252020ff",
|
||||
"tab.inactive_background": "#252020ff",
|
||||
"tab.active_background": "#1b1818ff",
|
||||
"search.match_background": "#7272ca66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#252020ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -5034,7 +5034,7 @@
|
||||
"tab_bar.background": "#ebe3e3ff",
|
||||
"tab.inactive_background": "#ebe3e3ff",
|
||||
"tab.active_background": "#f4ececff",
|
||||
"search.match_background": "#7372ca66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#ebe3e3ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -5418,7 +5418,7 @@
|
||||
"tab_bar.background": "#1f2621ff",
|
||||
"tab.inactive_background": "#1f2621ff",
|
||||
"tab.active_background": "#171c19ff",
|
||||
"search.match_background": "#478c9066",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#1f2621ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -5802,7 +5802,7 @@
|
||||
"tab_bar.background": "#e3ebe6ff",
|
||||
"tab.inactive_background": "#e3ebe6ff",
|
||||
"tab.active_background": "#ecf4eeff",
|
||||
"search.match_background": "#488c9066",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#e3ebe6ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -6186,7 +6186,7 @@
|
||||
"tab_bar.background": "#1f231fff",
|
||||
"tab.inactive_background": "#1f231fff",
|
||||
"tab.active_background": "#131513ff",
|
||||
"search.match_background": "#3e62f466",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#1f231fff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -6570,7 +6570,7 @@
|
||||
"tab_bar.background": "#daeedaff",
|
||||
"tab.inactive_background": "#daeedaff",
|
||||
"tab.active_background": "#f3faf3ff",
|
||||
"search.match_background": "#3f62f466",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#daeedaff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -6954,7 +6954,7 @@
|
||||
"tab_bar.background": "#262f51ff",
|
||||
"tab.inactive_background": "#262f51ff",
|
||||
"tab.active_background": "#202646ff",
|
||||
"search.match_background": "#3e8fd066",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#262f51ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -7338,7 +7338,7 @@
|
||||
"tab_bar.background": "#e5e8f5ff",
|
||||
"tab.inactive_background": "#e5e8f5ff",
|
||||
"tab.active_background": "#f5f7ffff",
|
||||
"search.match_background": "#3f8fd066",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#e5e8f5ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#1f2127ff",
|
||||
"tab.inactive_background": "#1f2127ff",
|
||||
"tab.active_background": "#0d1016ff",
|
||||
"search.match_background": "#5ac2fe66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#1f2127ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -411,7 +411,7 @@
|
||||
"tab_bar.background": "#ececedff",
|
||||
"tab.inactive_background": "#ececedff",
|
||||
"tab.active_background": "#fcfcfcff",
|
||||
"search.match_background": "#3b9ee566",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#ececedff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -780,7 +780,7 @@
|
||||
"tab_bar.background": "#353944ff",
|
||||
"tab.inactive_background": "#353944ff",
|
||||
"tab.active_background": "#242835ff",
|
||||
"search.match_background": "#73cffe66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#353944ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#3a3735ff",
|
||||
"tab.inactive_background": "#3a3735ff",
|
||||
"tab.active_background": "#282828ff",
|
||||
"search.match_background": "#83a59866",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#3a3735ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -416,7 +416,7 @@
|
||||
"tab_bar.background": "#393634ff",
|
||||
"tab.inactive_background": "#393634ff",
|
||||
"tab.active_background": "#1d2021ff",
|
||||
"search.match_background": "#83a59866",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#393634ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -790,7 +790,7 @@
|
||||
"tab_bar.background": "#3b3735ff",
|
||||
"tab.inactive_background": "#3b3735ff",
|
||||
"tab.active_background": "#32302fff",
|
||||
"search.match_background": "#83a59866",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#3b3735ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -1164,7 +1164,7 @@
|
||||
"tab_bar.background": "#ecddb4ff",
|
||||
"tab.inactive_background": "#ecddb4ff",
|
||||
"tab.active_background": "#fbf1c7ff",
|
||||
"search.match_background": "#0b667866",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#ecddb4ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -1538,7 +1538,7 @@
|
||||
"tab_bar.background": "#ecddb5ff",
|
||||
"tab.inactive_background": "#ecddb5ff",
|
||||
"tab.active_background": "#f9f5d7ff",
|
||||
"search.match_background": "#0b667866",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#ecddb5ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -1912,7 +1912,7 @@
|
||||
"tab_bar.background": "#ecdcb3ff",
|
||||
"tab.inactive_background": "#ecdcb3ff",
|
||||
"tab.active_background": "#f2e5bcff",
|
||||
"search.match_background": "#0b667866",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#ecdcb3ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#2f343eff",
|
||||
"tab.inactive_background": "#2f343eff",
|
||||
"tab.active_background": "#282c33ff",
|
||||
"search.match_background": "#74ade866",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#2f343eff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -416,7 +416,7 @@
|
||||
"tab_bar.background": "#ebebecff",
|
||||
"tab.inactive_background": "#ebebecff",
|
||||
"tab.active_background": "#fafafaff",
|
||||
"search.match_background": "#5c79e266",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#ebebecff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#1c1b2aff",
|
||||
"tab.inactive_background": "#1c1b2aff",
|
||||
"tab.active_background": "#191724ff",
|
||||
"search.match_background": "#57949f66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#1c1b2aff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -421,7 +421,7 @@
|
||||
"tab_bar.background": "#fef9f2ff",
|
||||
"tab.inactive_background": "#fef9f2ff",
|
||||
"tab.active_background": "#faf4edff",
|
||||
"search.match_background": "#9cced766",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#fef9f2ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -800,7 +800,7 @@
|
||||
"tab_bar.background": "#28253cff",
|
||||
"tab.inactive_background": "#28253cff",
|
||||
"tab.active_background": "#232136ff",
|
||||
"search.match_background": "#9cced766",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#28253cff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#2b3038ff",
|
||||
"tab.inactive_background": "#2b3038ff",
|
||||
"tab.active_background": "#282c33ff",
|
||||
"search.match_background": "#528b8b66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#2b3038ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#04313bff",
|
||||
"tab.inactive_background": "#04313bff",
|
||||
"tab.active_background": "#002a35ff",
|
||||
"search.match_background": "#288bd166",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#04313bff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
@@ -411,7 +411,7 @@
|
||||
"tab_bar.background": "#f3eddaff",
|
||||
"tab.inactive_background": "#f3eddaff",
|
||||
"tab.active_background": "#fdf6e3ff",
|
||||
"search.match_background": "#298bd166",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#f3eddaff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"tab_bar.background": "#231f16ff",
|
||||
"tab.inactive_background": "#231f16ff",
|
||||
"tab.active_background": "#1b1810ff",
|
||||
"search.match_background": "#499bef66",
|
||||
"search.match_background": null,
|
||||
"panel.background": "#231f16ff",
|
||||
"panel.focused_border": null,
|
||||
"pane.focused_border": null,
|
||||
|
||||
@@ -11,18 +11,18 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
auto_update.workspace = true
|
||||
editor.workspace = true
|
||||
auto_update = { path = "../auto_update" }
|
||||
editor = { path = "../editor" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
project.workspace = true
|
||||
settings.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
language = { path = "../language" }
|
||||
project = { path = "../project" }
|
||||
settings = { path = "../settings" }
|
||||
smallvec.workspace = true
|
||||
theme.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
ui = { path = "../ui" }
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace", package = "workspace" }
|
||||
|
||||
[dev-dependencies]
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
|
||||
@@ -17,9 +17,9 @@ anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
bincode = "1.3.3"
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
isahc.workspace = true
|
||||
language.workspace = true
|
||||
language = { path = "../language" }
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
matrixmultiply = "0.3.7"
|
||||
@@ -33,7 +33,7 @@ rusqlite = { version = "0.29.0", features = ["blob", "array", "modern_sqlite"] }
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
tiktoken-rs.workspace = true
|
||||
util.workspace = true
|
||||
util = { path = "../util" }
|
||||
|
||||
[dev-dependencies]
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
|
||||
@@ -134,7 +134,7 @@ impl OpenAiEmbeddingProvider {
|
||||
spans: Vec<&str>,
|
||||
request_timeout: u64,
|
||||
) -> Result<Response<AsyncBody>> {
|
||||
let request = Request::post(format!("{OPEN_AI_API_URL}/embeddings"))
|
||||
let request = Request::post("https://api.openai.com/v1/embeddings")
|
||||
.redirect_policy(isahc::config::RedirectPolicy::Follow)
|
||||
.timeout(Duration::from_secs(request_timeout))
|
||||
.header("Content-Type", "application/json")
|
||||
|
||||
@@ -7,5 +7,5 @@ license = "GPL-3.0-or-later"
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
rust-embed.workspace = true
|
||||
|
||||
@@ -10,44 +10,44 @@ path = "src/assistant.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
ai.workspace = true
|
||||
ai = { path = "../ai" }
|
||||
anyhow.workspace = true
|
||||
chrono.workspace = true
|
||||
client.workspace = true
|
||||
collections.workspace = true
|
||||
editor.workspace = true
|
||||
fs.workspace = true
|
||||
client = { path = "../client" }
|
||||
collections = { path = "../collections" }
|
||||
editor = { path = "../editor" }
|
||||
fs = { path = "../fs" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
indoc.workspace = true
|
||||
isahc.workspace = true
|
||||
language.workspace = true
|
||||
language = { path = "../language" }
|
||||
log.workspace = true
|
||||
menu.workspace = true
|
||||
multi_buffer.workspace = true
|
||||
menu = { path = "../menu" }
|
||||
multi_buffer = { path = "../multi_buffer" }
|
||||
ordered-float.workspace = true
|
||||
parking_lot.workspace = true
|
||||
project.workspace = true
|
||||
project = { path = "../project" }
|
||||
regex.workspace = true
|
||||
schemars.workspace = true
|
||||
search.workspace = true
|
||||
semantic_index.workspace = true
|
||||
search = { path = "../search" }
|
||||
semantic_index = { path = "../semantic_index" }
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smol.workspace = true
|
||||
theme.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
tiktoken-rs.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
ui = { path = "../ui" }
|
||||
util = { path = "../util" }
|
||||
uuid.workspace = true
|
||||
workspace.workspace = true
|
||||
workspace = { path = "../workspace" }
|
||||
|
||||
[dev-dependencies]
|
||||
ai = { workspace = true, features = ["test-support"] }
|
||||
ai = { path = "../ai", features = ["test-support"] }
|
||||
ctor.workspace = true
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
env_logger.workspace = true
|
||||
log.workspace = true
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
rand.workspace = true
|
||||
|
||||
@@ -962,7 +962,6 @@ impl AssistantPanel {
|
||||
line_height: relative(1.3).into(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
};
|
||||
EditorElement::new(
|
||||
@@ -3167,7 +3166,6 @@ impl InlineAssistant {
|
||||
line_height: relative(1.3).into(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
};
|
||||
EditorElement::new(
|
||||
|
||||
@@ -11,11 +11,11 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
collections.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
derive_more.workspace = true
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
log.workspace = true
|
||||
parking_lot.workspace = true
|
||||
rodio = { version = "0.17.1", default-features = false, features = ["wav"] }
|
||||
util.workspace = true
|
||||
util = { path = "../util" }
|
||||
|
||||
@@ -11,22 +11,22 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
client.workspace = true
|
||||
db.workspace = true
|
||||
gpui.workspace = true
|
||||
client = { path = "../client" }
|
||||
db = { path = "../db" }
|
||||
gpui = { path = "../gpui" }
|
||||
isahc.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
menu.workspace = true
|
||||
project.workspace = true
|
||||
release_channel.workspace = true
|
||||
menu = { path = "../menu" }
|
||||
project = { path = "../project" }
|
||||
release_channel = { path = "../release_channel" }
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smol.workspace = true
|
||||
tempfile.workspace = true
|
||||
theme.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace" }
|
||||
|
||||
@@ -40,11 +40,10 @@ impl Render for UpdateNotification {
|
||||
.id("notes")
|
||||
.child(Label::new("View the release notes"))
|
||||
.cursor_pointer()
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
.on_click(|_, cx| {
|
||||
crate::view_release_notes(&Default::default(), cx);
|
||||
this.dismiss(&menu::Cancel, cx)
|
||||
})),
|
||||
);
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,20 +10,20 @@ path = "src/breadcrumbs.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
collections.workspace = true
|
||||
editor.workspace = true
|
||||
gpui.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
editor = { path = "../editor" }
|
||||
gpui = { path = "../gpui" }
|
||||
itertools = "0.10"
|
||||
language.workspace = true
|
||||
outline.workspace = true
|
||||
project.workspace = true
|
||||
search.workspace = true
|
||||
settings.workspace = true
|
||||
theme.workspace = true
|
||||
ui.workspace = true
|
||||
workspace.workspace = true
|
||||
language = { path = "../language" }
|
||||
outline = { path = "../outline" }
|
||||
project = { path = "../project" }
|
||||
search = { path = "../search" }
|
||||
settings = { path = "../settings" }
|
||||
theme = { path = "../theme" }
|
||||
ui = { path = "../ui" }
|
||||
workspace = { path = "../workspace" }
|
||||
|
||||
[dev-dependencies]
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
@@ -22,33 +22,33 @@ test-support = [
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
async-broadcast = "0.4"
|
||||
audio.workspace = true
|
||||
client.workspace = true
|
||||
collections.workspace = true
|
||||
fs.workspace = true
|
||||
audio = { path = "../audio" }
|
||||
client = { path = "../client" }
|
||||
collections = { path = "../collections" }
|
||||
fs = { path = "../fs" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
image = "0.23"
|
||||
language.workspace = true
|
||||
live_kit_client.workspace = true
|
||||
language = { path = "../language" }
|
||||
live_kit_client = { path = "../live_kit_client" }
|
||||
log.workspace = true
|
||||
media.workspace = true
|
||||
media = { path = "../media" }
|
||||
postage.workspace = true
|
||||
project.workspace = true
|
||||
project = { path = "../project" }
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smallvec.workspace = true
|
||||
util.workspace = true
|
||||
util = { path = "../util" }
|
||||
|
||||
[dev-dependencies]
|
||||
client = { workspace = true, features = ["test-support"] }
|
||||
collections = { workspace = true, features = ["test-support"] }
|
||||
fs = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
live_kit_client = { workspace = true, features = ["test-support"] }
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
util = { workspace = true, features = ["test-support"] }
|
||||
client = { path = "../client", features = ["test-support"] }
|
||||
collections = { path = "../collections", features = ["test-support"] }
|
||||
fs = { path = "../fs", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
live_kit_client = { path = "../live_kit_client", features = ["test-support"] }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
|
||||
@@ -7,7 +7,6 @@ use settings::Settings;
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct CallSettings {
|
||||
pub mute_on_join: bool,
|
||||
pub share_on_join: bool,
|
||||
}
|
||||
|
||||
/// Configuration of voice calls in Zed.
|
||||
@@ -17,11 +16,6 @@ pub struct CallSettingsContent {
|
||||
///
|
||||
/// Default: false
|
||||
pub mute_on_join: Option<bool>,
|
||||
|
||||
/// Whether your current project should be shared when joining an empty channel.
|
||||
///
|
||||
/// Default: true
|
||||
pub share_on_join: Option<bool>,
|
||||
}
|
||||
|
||||
impl Settings for CallSettings {
|
||||
|
||||
@@ -617,10 +617,6 @@ impl Room {
|
||||
self.local_participant.role == proto::ChannelRole::Admin
|
||||
}
|
||||
|
||||
pub fn local_participant_is_guest(&self) -> bool {
|
||||
self.local_participant.role == proto::ChannelRole::Guest
|
||||
}
|
||||
|
||||
pub fn set_participant_role(
|
||||
&mut self,
|
||||
user_id: u64,
|
||||
@@ -1206,7 +1202,7 @@ impl Room {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn share_project(
|
||||
pub(crate) fn share_project(
|
||||
&mut self,
|
||||
project: Model<Project>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
|
||||
@@ -14,42 +14,42 @@ test-support = ["collections/test-support", "gpui/test-support", "rpc/test-suppo
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
client.workspace = true
|
||||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
db.workspace = true
|
||||
feature_flags.workspace = true
|
||||
client = { path = "../client" }
|
||||
clock = { path = "../clock" }
|
||||
collections = { path = "../collections" }
|
||||
db = { path = "../db" }
|
||||
feature_flags = { path = "../feature_flags" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
image = "0.23"
|
||||
language.workspace = true
|
||||
language = { path = "../language" }
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
parking_lot.workspace = true
|
||||
postage.workspace = true
|
||||
rand.workspace = true
|
||||
release_channel.workspace = true
|
||||
rpc.workspace = true
|
||||
release_channel = { path = "../release_channel" }
|
||||
rpc = { path = "../rpc" }
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smallvec.workspace = true
|
||||
smol.workspace = true
|
||||
sum_tree.workspace = true
|
||||
sum_tree = { path = "../sum_tree" }
|
||||
tempfile.workspace = true
|
||||
text.workspace = true
|
||||
text = { path = "../text" }
|
||||
thiserror.workspace = true
|
||||
time.workspace = true
|
||||
tiny_http = "0.8"
|
||||
url.workspace = true
|
||||
util.workspace = true
|
||||
util = { path = "../util" }
|
||||
uuid.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
collections = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
rpc = { workspace = true, features = ["test-support"] }
|
||||
client = { workspace = true, features = ["test-support"] }
|
||||
settings = { workspace = true, features = ["test-support"] }
|
||||
util = { workspace = true, features = ["test-support"] }
|
||||
collections = { path = "../collections", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
rpc = { path = "../rpc", features = ["test-support"] }
|
||||
client = { path = "../client", features = ["test-support"] }
|
||||
settings = { path = "../settings", features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
|
||||
@@ -5,13 +5,12 @@ use client::{
|
||||
user::{User, UserStore},
|
||||
Client, Subscription, TypedEnvelope, UserId,
|
||||
};
|
||||
use collections::HashSet;
|
||||
use futures::lock::Mutex;
|
||||
use gpui::{
|
||||
AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, Task, WeakModel,
|
||||
};
|
||||
use gpui::{AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, Task};
|
||||
use rand::prelude::*;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
mem,
|
||||
ops::{ControlFlow, Range},
|
||||
sync::Arc,
|
||||
};
|
||||
@@ -27,7 +26,6 @@ pub struct ChannelChat {
|
||||
loaded_all_messages: bool,
|
||||
last_acknowledged_id: Option<u64>,
|
||||
next_pending_message_id: usize,
|
||||
first_loaded_message_id: Option<u64>,
|
||||
user_store: Model<UserStore>,
|
||||
rpc: Arc<Client>,
|
||||
outgoing_messages_lock: Arc<Mutex<()>>,
|
||||
@@ -39,7 +37,6 @@ pub struct ChannelChat {
|
||||
pub struct MessageParams {
|
||||
pub text: String,
|
||||
pub mentions: Vec<(Range<usize>, UserId)>,
|
||||
pub reply_to_message_id: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -50,7 +47,6 @@ pub struct ChannelMessage {
|
||||
pub sender: Arc<User>,
|
||||
pub nonce: u128,
|
||||
pub mentions: Vec<(Range<usize>, UserId)>,
|
||||
pub reply_to_message_id: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
@@ -59,15 +55,6 @@ pub enum ChannelMessageId {
|
||||
Pending(usize),
|
||||
}
|
||||
|
||||
impl Into<Option<u64>> for ChannelMessageId {
|
||||
fn into(self) -> Option<u64> {
|
||||
match self {
|
||||
ChannelMessageId::Saved(id) => Some(id),
|
||||
ChannelMessageId::Pending(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ChannelMessageSummary {
|
||||
max_id: ChannelMessageId,
|
||||
@@ -109,35 +96,28 @@ impl ChannelChat {
|
||||
let response = client
|
||||
.request(proto::JoinChannelChat { channel_id })
|
||||
.await?;
|
||||
let messages = messages_from_proto(response.messages, &user_store, &mut cx).await?;
|
||||
let loaded_all_messages = response.done;
|
||||
|
||||
let handle = cx.new_model(|cx| {
|
||||
Ok(cx.new_model(|cx| {
|
||||
cx.on_release(Self::release).detach();
|
||||
Self {
|
||||
let mut this = Self {
|
||||
channel_id: channel.id,
|
||||
user_store: user_store.clone(),
|
||||
user_store,
|
||||
channel_store,
|
||||
rpc: client.clone(),
|
||||
rpc: client,
|
||||
outgoing_messages_lock: Default::default(),
|
||||
messages: Default::default(),
|
||||
acknowledged_message_ids: Default::default(),
|
||||
loaded_all_messages: false,
|
||||
loaded_all_messages,
|
||||
next_pending_message_id: 0,
|
||||
last_acknowledged_id: None,
|
||||
rng: StdRng::from_entropy(),
|
||||
first_loaded_message_id: None,
|
||||
_subscription: subscription.set_model(&cx.handle(), &mut cx.to_async()),
|
||||
}
|
||||
})?;
|
||||
Self::handle_loaded_messages(
|
||||
handle.downgrade(),
|
||||
user_store,
|
||||
client,
|
||||
response.messages,
|
||||
response.done,
|
||||
&mut cx,
|
||||
)
|
||||
.await?;
|
||||
Ok(handle)
|
||||
};
|
||||
this.insert_messages(messages, cx);
|
||||
this
|
||||
})?)
|
||||
}
|
||||
|
||||
fn release(&mut self, _: &mut AppContext) {
|
||||
@@ -186,7 +166,6 @@ impl ChannelChat {
|
||||
timestamp: OffsetDateTime::now_utc(),
|
||||
mentions: message.mentions.clone(),
|
||||
nonce,
|
||||
reply_to_message_id: message.reply_to_message_id,
|
||||
},
|
||||
&(),
|
||||
),
|
||||
@@ -204,7 +183,6 @@ impl ChannelChat {
|
||||
body: message.text,
|
||||
nonce: Some(nonce.into()),
|
||||
mentions: mentions_to_proto(&message.mentions),
|
||||
reply_to_message_id: message.reply_to_message_id,
|
||||
});
|
||||
let response = request.await?;
|
||||
drop(outgoing_message_guard);
|
||||
@@ -249,16 +227,12 @@ impl ChannelChat {
|
||||
before_message_id,
|
||||
})
|
||||
.await?;
|
||||
Self::handle_loaded_messages(
|
||||
this,
|
||||
user_store,
|
||||
rpc,
|
||||
response.messages,
|
||||
response.done,
|
||||
&mut cx,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let loaded_all_messages = response.done;
|
||||
let messages = messages_from_proto(response.messages, &user_store, &mut cx).await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.loaded_all_messages = loaded_all_messages;
|
||||
this.insert_messages(messages, cx);
|
||||
})?;
|
||||
anyhow::Ok(())
|
||||
}
|
||||
.log_err()
|
||||
@@ -266,14 +240,9 @@ impl ChannelChat {
|
||||
}
|
||||
|
||||
pub fn first_loaded_message_id(&mut self) -> Option<u64> {
|
||||
self.first_loaded_message_id
|
||||
}
|
||||
|
||||
/// Load a message by its id, if it's already stored locally.
|
||||
pub fn find_loaded_message(&self, id: u64) -> Option<&ChannelMessage> {
|
||||
self.messages.iter().find(|message| match message.id {
|
||||
ChannelMessageId::Saved(message_id) => message_id == id,
|
||||
ChannelMessageId::Pending(_) => false,
|
||||
self.messages.first().and_then(|message| match message.id {
|
||||
ChannelMessageId::Saved(id) => Some(id),
|
||||
ChannelMessageId::Pending(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -335,66 +304,6 @@ impl ChannelChat {
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_loaded_messages(
|
||||
this: WeakModel<Self>,
|
||||
user_store: Model<UserStore>,
|
||||
rpc: Arc<Client>,
|
||||
proto_messages: Vec<proto::ChannelMessage>,
|
||||
loaded_all_messages: bool,
|
||||
cx: &mut AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
let loaded_messages = messages_from_proto(proto_messages, &user_store, cx).await?;
|
||||
|
||||
let first_loaded_message_id = loaded_messages.first().map(|m| m.id);
|
||||
let loaded_message_ids = this.update(cx, |this, _| {
|
||||
let mut loaded_message_ids: HashSet<u64> = HashSet::default();
|
||||
for message in loaded_messages.iter() {
|
||||
if let Some(saved_message_id) = message.id.into() {
|
||||
loaded_message_ids.insert(saved_message_id);
|
||||
}
|
||||
}
|
||||
for message in this.messages.iter() {
|
||||
if let Some(saved_message_id) = message.id.into() {
|
||||
loaded_message_ids.insert(saved_message_id);
|
||||
}
|
||||
}
|
||||
loaded_message_ids
|
||||
})?;
|
||||
|
||||
let missing_ancestors = loaded_messages
|
||||
.iter()
|
||||
.filter_map(|message| {
|
||||
if let Some(ancestor_id) = message.reply_to_message_id {
|
||||
if !loaded_message_ids.contains(&ancestor_id) {
|
||||
return Some(ancestor_id);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let loaded_ancestors = if missing_ancestors.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let response = rpc
|
||||
.request(proto::GetChannelMessagesById {
|
||||
message_ids: missing_ancestors,
|
||||
})
|
||||
.await?;
|
||||
Some(messages_from_proto(response.messages, &user_store, cx).await?)
|
||||
};
|
||||
this.update(cx, |this, cx| {
|
||||
this.first_loaded_message_id = first_loaded_message_id.and_then(|msg_id| msg_id.into());
|
||||
this.loaded_all_messages = loaded_all_messages;
|
||||
this.insert_messages(loaded_messages, cx);
|
||||
if let Some(loaded_ancestors) = loaded_ancestors {
|
||||
this.insert_messages(loaded_ancestors, cx);
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn rejoin(&mut self, cx: &mut ModelContext<Self>) {
|
||||
let user_store = self.user_store.clone();
|
||||
let rpc = self.rpc.clone();
|
||||
@@ -402,17 +311,28 @@ impl ChannelChat {
|
||||
cx.spawn(move |this, mut cx| {
|
||||
async move {
|
||||
let response = rpc.request(proto::JoinChannelChat { channel_id }).await?;
|
||||
Self::handle_loaded_messages(
|
||||
this.clone(),
|
||||
user_store.clone(),
|
||||
rpc.clone(),
|
||||
response.messages,
|
||||
response.done,
|
||||
&mut cx,
|
||||
)
|
||||
.await?;
|
||||
let messages = messages_from_proto(response.messages, &user_store, &mut cx).await?;
|
||||
let loaded_all_messages = response.done;
|
||||
|
||||
let pending_messages = this.update(&mut cx, |this, cx| {
|
||||
if let Some((first_new_message, last_old_message)) =
|
||||
messages.first().zip(this.messages.last())
|
||||
{
|
||||
if first_new_message.id > last_old_message.id {
|
||||
let old_messages = mem::take(&mut this.messages);
|
||||
cx.emit(ChannelChatEvent::MessagesUpdated {
|
||||
old_range: 0..old_messages.summary().count,
|
||||
new_count: 0,
|
||||
});
|
||||
this.loaded_all_messages = loaded_all_messages;
|
||||
}
|
||||
}
|
||||
|
||||
this.insert_messages(messages, cx);
|
||||
if loaded_all_messages {
|
||||
this.loaded_all_messages = loaded_all_messages;
|
||||
}
|
||||
|
||||
let pending_messages = this.update(&mut cx, |this, _| {
|
||||
this.pending_messages().cloned().collect::<Vec<_>>()
|
||||
})?;
|
||||
|
||||
@@ -422,7 +342,6 @@ impl ChannelChat {
|
||||
body: pending_message.body,
|
||||
mentions: mentions_to_proto(&pending_message.mentions),
|
||||
nonce: Some(pending_message.nonce.into()),
|
||||
reply_to_message_id: pending_message.reply_to_message_id,
|
||||
});
|
||||
let response = request.await?;
|
||||
let message = ChannelMessage::from_proto(
|
||||
@@ -634,7 +553,6 @@ impl ChannelMessage {
|
||||
.nonce
|
||||
.ok_or_else(|| anyhow!("nonce is required"))?
|
||||
.into(),
|
||||
reply_to_message_id: message.reply_to_message_id,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -724,7 +642,6 @@ impl<'a> From<&'a str> for MessageParams {
|
||||
Self {
|
||||
text: value.into(),
|
||||
mentions: Vec::new(),
|
||||
reply_to_message_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,19 +74,11 @@ impl Channel {
|
||||
pub fn link(&self) -> String {
|
||||
RELEASE_CHANNEL.link_prefix().to_owned()
|
||||
+ "channel/"
|
||||
+ &Self::slug(&self.name)
|
||||
+ &self.slug()
|
||||
+ "-"
|
||||
+ &self.id.to_string()
|
||||
}
|
||||
|
||||
pub fn notes_link(&self, heading: Option<String>) -> String {
|
||||
self.link()
|
||||
+ "/notes"
|
||||
+ &heading
|
||||
.map(|h| format!("#{}", Self::slug(&h)))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn is_root_channel(&self) -> bool {
|
||||
self.parent_path.is_empty()
|
||||
}
|
||||
@@ -98,8 +90,9 @@ impl Channel {
|
||||
.unwrap_or(self.id)
|
||||
}
|
||||
|
||||
pub fn slug(str: &str) -> String {
|
||||
let slug: String = str
|
||||
pub fn slug(&self) -> String {
|
||||
let slug: String = self
|
||||
.name
|
||||
.chars()
|
||||
.map(|c| if c.is_alphanumeric() { c } else { '-' })
|
||||
.collect();
|
||||
|
||||
@@ -184,7 +184,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
||||
sender_id: 5,
|
||||
mentions: vec![],
|
||||
nonce: Some(1.into()),
|
||||
reply_to_message_id: None,
|
||||
},
|
||||
proto::ChannelMessage {
|
||||
id: 11,
|
||||
@@ -193,7 +192,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
||||
sender_id: 6,
|
||||
mentions: vec![],
|
||||
nonce: Some(2.into()),
|
||||
reply_to_message_id: None,
|
||||
},
|
||||
],
|
||||
done: false,
|
||||
@@ -241,7 +239,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
||||
sender_id: 7,
|
||||
mentions: vec![],
|
||||
nonce: Some(3.into()),
|
||||
reply_to_message_id: None,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -295,7 +292,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
||||
sender_id: 5,
|
||||
nonce: Some(4.into()),
|
||||
mentions: vec![],
|
||||
reply_to_message_id: None,
|
||||
},
|
||||
proto::ChannelMessage {
|
||||
id: 9,
|
||||
@@ -304,7 +300,6 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
|
||||
sender_id: 6,
|
||||
nonce: Some(5.into()),
|
||||
mentions: vec![],
|
||||
reply_to_message_id: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -20,7 +20,7 @@ dirs = "3.0"
|
||||
ipc-channel = "0.16"
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
util.workspace = true
|
||||
util = { path = "../util" }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-foundation = "0.9"
|
||||
|
||||
@@ -14,20 +14,20 @@ test-support = ["collections/test-support", "gpui/test-support", "rpc/test-suppo
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
collections.workspace = true
|
||||
db.workspace = true
|
||||
gpui.workspace = true
|
||||
util.workspace = true
|
||||
release_channel.workspace = true
|
||||
rpc.workspace = true
|
||||
text.workspace = true
|
||||
settings.workspace = true
|
||||
feature_flags.workspace = true
|
||||
sum_tree.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
db = { path = "../db" }
|
||||
gpui = { path = "../gpui" }
|
||||
util = { path = "../util" }
|
||||
release_channel = { path = "../release_channel" }
|
||||
rpc = { path = "../rpc" }
|
||||
text = { path = "../text" }
|
||||
settings = { path = "../settings" }
|
||||
feature_flags = { path = "../feature_flags" }
|
||||
sum_tree = { path = "../sum_tree" }
|
||||
|
||||
anyhow.workspace = true
|
||||
async-recursion = "0.3"
|
||||
async-tungstenite = { version = "0.16", features = ["async-std", "async-native-tls"] }
|
||||
async-tungstenite = { version = "0.16", features = ["async-tls"] }
|
||||
futures.workspace = true
|
||||
image = "0.23"
|
||||
lazy_static.workspace = true
|
||||
@@ -51,8 +51,8 @@ uuid.workspace = true
|
||||
url.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
collections = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
rpc = { workspace = true, features = ["test-support"] }
|
||||
settings = { workspace = true, features = ["test-support"] }
|
||||
util = { workspace = true, features = ["test-support"] }
|
||||
collections = { path = "../collections", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
rpc = { path = "../rpc", features = ["test-support"] }
|
||||
settings = { path = "../settings", features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
|
||||
@@ -10,7 +10,6 @@ use async_tungstenite::tungstenite::{
|
||||
error::Error as WebsocketError,
|
||||
http::{Request, StatusCode},
|
||||
};
|
||||
use collections::HashMap;
|
||||
use futures::{
|
||||
channel::oneshot, future::LocalBoxFuture, AsyncReadExt, FutureExt, SinkExt, StreamExt,
|
||||
TryFutureExt as _, TryStreamExt,
|
||||
@@ -30,6 +29,7 @@ use serde_json;
|
||||
use settings::{Settings, SettingsStore};
|
||||
use std::{
|
||||
any::TypeId,
|
||||
collections::HashMap,
|
||||
convert::TryFrom,
|
||||
fmt::Write as _,
|
||||
future::Future,
|
||||
@@ -1040,7 +1040,7 @@ impl Client {
|
||||
rpc_url.set_scheme("wss").unwrap();
|
||||
let request = request.uri(rpc_url.as_str()).body(())?;
|
||||
let (stream, _) =
|
||||
async_tungstenite::async_std::client_async_tls(request, stream).await?;
|
||||
async_tungstenite::async_tls::client_async_tls(request, stream).await?;
|
||||
Ok(Connection::new(
|
||||
stream
|
||||
.map_err(|error| anyhow!(error))
|
||||
|
||||
@@ -145,14 +145,11 @@ const FLUSH_INTERVAL: Duration = Duration::from_secs(1);
|
||||
#[cfg(not(debug_assertions))]
|
||||
const FLUSH_INTERVAL: Duration = Duration::from_secs(60 * 5);
|
||||
|
||||
static ZED_CLIENT_CHECKSUM_SEED: Lazy<Option<Vec<u8>>> = Lazy::new(|| {
|
||||
static ZED_CLIENT_CHECKSUM_SEED: Lazy<Vec<u8>> = Lazy::new(|| {
|
||||
option_env!("ZED_CLIENT_CHECKSUM_SEED")
|
||||
.map(|s| s.as_bytes().into())
|
||||
.or_else(|| {
|
||||
env::var("ZED_CLIENT_CHECKSUM_SEED")
|
||||
.ok()
|
||||
.map(|s| s.as_bytes().into())
|
||||
})
|
||||
.unwrap_or("development-checksum-seed")
|
||||
.as_bytes()
|
||||
.into()
|
||||
});
|
||||
|
||||
impl Telemetry {
|
||||
@@ -513,10 +510,6 @@ impl Telemetry {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(checksum_seed) = &*ZED_CLIENT_CHECKSUM_SEED else {
|
||||
return;
|
||||
};
|
||||
|
||||
let this = self.clone();
|
||||
self.executor
|
||||
.spawn(
|
||||
@@ -558,9 +551,9 @@ impl Telemetry {
|
||||
}
|
||||
|
||||
let mut summer = Sha256::new();
|
||||
summer.update(checksum_seed);
|
||||
summer.update(&*ZED_CLIENT_CHECKSUM_SEED);
|
||||
summer.update(&json_bytes);
|
||||
summer.update(checksum_seed);
|
||||
summer.update(&*ZED_CLIENT_CHECKSUM_SEED);
|
||||
let mut checksum = String::new();
|
||||
for byte in summer.finalize().as_slice() {
|
||||
use std::fmt::Write;
|
||||
|
||||
@@ -22,15 +22,15 @@ axum-extra = { version = "0.3", features = ["erased-json"] }
|
||||
base64 = "0.13"
|
||||
chrono.workspace = true
|
||||
clap = { version = "3.1", features = ["derive"], optional = true }
|
||||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
clock = { path = "../clock" }
|
||||
collections = { path = "../collections" }
|
||||
dashmap = "5.4"
|
||||
envy = "0.4.2"
|
||||
futures.workspace = true
|
||||
hyper = "0.14"
|
||||
lazy_static.workspace = true
|
||||
lipsum = { version = "0.8", optional = true }
|
||||
live_kit_server.workspace = true
|
||||
live_kit_server = { path = "../live_kit_server" }
|
||||
log.workspace = true
|
||||
nanoid = "0.4"
|
||||
parking_lot.workspace = true
|
||||
@@ -38,7 +38,7 @@ prometheus = "0.13"
|
||||
prost.workspace = true
|
||||
rand.workspace = true
|
||||
reqwest = { version = "0.11", features = ["json"], optional = true }
|
||||
rpc.workspace = true
|
||||
rpc = { path = "../rpc" }
|
||||
scrypt = "0.7"
|
||||
sea-orm = { version = "0.12.x", features = ["sqlx-postgres", "postgres-array", "runtime-tokio-rustls", "with-uuid"] }
|
||||
serde.workspace = true
|
||||
@@ -47,7 +47,7 @@ serde_json.workspace = true
|
||||
sha-1 = "0.9"
|
||||
smallvec.workspace = true
|
||||
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "json", "time", "uuid", "any"] }
|
||||
text.workspace = true
|
||||
text = { path = "../text" }
|
||||
time.workspace = true
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-tungstenite = "0.17"
|
||||
@@ -57,44 +57,44 @@ tower = "0.4"
|
||||
tracing = "0.1.34"
|
||||
tracing-log = "0.1.3"
|
||||
tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] }
|
||||
util.workspace = true
|
||||
util = { path = "../util" }
|
||||
uuid.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
release_channel.workspace = true
|
||||
release_channel = { path = "../release_channel" }
|
||||
async-trait.workspace = true
|
||||
audio.workspace = true
|
||||
call = { workspace = true, features = ["test-support"] }
|
||||
channel.workspace = true
|
||||
client = { workspace = true, features = ["test-support"] }
|
||||
collab_ui = { workspace = true, features = ["test-support"] }
|
||||
collections = { workspace = true, features = ["test-support"] }
|
||||
audio = { path = "../audio" }
|
||||
call = { path = "../call", features = ["test-support"] }
|
||||
channel = { path = "../channel" }
|
||||
client = { path = "../client", features = ["test-support"] }
|
||||
collab_ui = { path = "../collab_ui", features = ["test-support"] }
|
||||
collections = { path = "../collections", features = ["test-support"] }
|
||||
ctor.workspace = true
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
env_logger.workspace = true
|
||||
file_finder.workspace = true
|
||||
fs = { workspace = true, features = ["test-support"] }
|
||||
git = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
file_finder = { path = "../file_finder" }
|
||||
fs = { path = "../fs", features = ["test-support"] }
|
||||
git = { path = "../git", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
indoc.workspace = true
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
lazy_static.workspace = true
|
||||
live_kit_client = { workspace = true, features = ["test-support"] }
|
||||
lsp = { workspace = true, features = ["test-support"] }
|
||||
menu.workspace = true
|
||||
node_runtime.workspace = true
|
||||
notifications = { workspace = true, features = ["test-support"] }
|
||||
live_kit_client = { path = "../live_kit_client", features = ["test-support"] }
|
||||
lsp = { path = "../lsp", features = ["test-support"] }
|
||||
menu = { path = "../menu" }
|
||||
node_runtime = { path = "../node_runtime" }
|
||||
notifications = { path = "../notifications", features = ["test-support"] }
|
||||
pretty_assertions.workspace = true
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
rpc = { workspace = true, features = ["test-support"] }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
rpc = { path = "../rpc", features = ["test-support"] }
|
||||
sea-orm = { version = "0.12.x", features = ["sqlx-sqlite"] }
|
||||
serde_json.workspace = true
|
||||
settings = { workspace = true, features = ["test-support"] }
|
||||
settings = { path = "../settings", features = ["test-support"] }
|
||||
sqlx = { version = "0.7", features = ["sqlite"] }
|
||||
theme.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
unindent.workspace = true
|
||||
util.workspace = true
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
[features]
|
||||
seed-support = ["clap", "lipsum", "reqwest"]
|
||||
|
||||
@@ -217,8 +217,7 @@ CREATE TABLE IF NOT EXISTS "channel_messages" (
|
||||
"sender_id" INTEGER NOT NULL REFERENCES users (id),
|
||||
"body" TEXT NOT NULL,
|
||||
"sent_at" TIMESTAMP,
|
||||
"nonce" BLOB NOT NULL,
|
||||
"reply_to_message_id" INTEGER DEFAULT NULL
|
||||
"nonce" BLOB NOT NULL
|
||||
);
|
||||
CREATE INDEX "index_channel_messages_on_channel_id" ON "channel_messages" ("channel_id");
|
||||
CREATE UNIQUE INDEX "index_channel_messages_on_sender_id_nonce" ON "channel_messages" ("sender_id", "nonce");
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE channel_messages ADD reply_to_message_id INTEGER DEFAULT NULL
|
||||
@@ -692,7 +692,7 @@ impl ProjectCollaborator {
|
||||
pub struct LeftProject {
|
||||
pub id: ProjectId,
|
||||
pub host_user_id: UserId,
|
||||
pub host_connection_id: Option<ConnectionId>,
|
||||
pub host_connection_id: ConnectionId,
|
||||
pub connection_ids: Vec<ConnectionId>,
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,6 @@ impl Database {
|
||||
upper_half: nonce.0,
|
||||
lower_half: nonce.1,
|
||||
}),
|
||||
reply_to_message_id: row.reply_to_message_id.map(|id| id.to_proto()),
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -208,7 +207,6 @@ impl Database {
|
||||
mentions: &[proto::ChatMention],
|
||||
timestamp: OffsetDateTime,
|
||||
nonce: u128,
|
||||
reply_to_message_id: Option<MessageId>,
|
||||
) -> Result<CreatedChannelMessage> {
|
||||
self.transaction(|tx| async move {
|
||||
let channel = self.get_channel_internal(channel_id, &*tx).await?;
|
||||
@@ -247,7 +245,6 @@ impl Database {
|
||||
sent_at: ActiveValue::Set(timestamp),
|
||||
nonce: ActiveValue::Set(Uuid::from_u128(nonce)),
|
||||
id: ActiveValue::NotSet,
|
||||
reply_to_message_id: ActiveValue::Set(reply_to_message_id),
|
||||
})
|
||||
.on_conflict(
|
||||
OnConflict::columns([
|
||||
|
||||
@@ -778,7 +778,7 @@ impl Database {
|
||||
let left_project = LeftProject {
|
||||
id: project_id,
|
||||
host_user_id: project.host_user_id,
|
||||
host_connection_id: Some(project.host_connection()?),
|
||||
host_connection_id: project.host_connection()?,
|
||||
connection_ids,
|
||||
};
|
||||
Ok((room, left_project))
|
||||
|
||||
@@ -862,7 +862,7 @@ impl Database {
|
||||
id: collaborator.project_id,
|
||||
host_user_id: Default::default(),
|
||||
connection_ids: Default::default(),
|
||||
host_connection_id: None,
|
||||
host_connection_id: Default::default(),
|
||||
});
|
||||
|
||||
let collaborator_connection_id = collaborator.connection();
|
||||
@@ -872,7 +872,7 @@ impl Database {
|
||||
|
||||
if collaborator.is_host {
|
||||
left_project.host_user_id = collaborator.user_id;
|
||||
left_project.host_connection_id = Some(collaborator_connection_id);
|
||||
left_project.host_connection_id = collaborator_connection_id;
|
||||
}
|
||||
}
|
||||
drop(collaborators);
|
||||
|
||||
@@ -12,7 +12,6 @@ pub struct Model {
|
||||
pub body: String,
|
||||
pub sent_at: PrimitiveDateTime,
|
||||
pub nonce: Uuid,
|
||||
pub reply_to_message_id: Option<MessageId>,
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
@@ -32,7 +32,6 @@ async fn test_channel_message_retrieval(db: &Arc<Database>) {
|
||||
&[],
|
||||
OffsetDateTime::now_utc(),
|
||||
i,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -107,7 +106,6 @@ async fn test_channel_message_nonces(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[(3..10, user_b.to_proto())]),
|
||||
OffsetDateTime::now_utc(),
|
||||
100,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -120,7 +118,6 @@ async fn test_channel_message_nonces(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[]),
|
||||
OffsetDateTime::now_utc(),
|
||||
200,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -133,7 +130,6 @@ async fn test_channel_message_nonces(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[(4..11, user_c.to_proto())]),
|
||||
OffsetDateTime::now_utc(),
|
||||
100,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -146,7 +142,6 @@ async fn test_channel_message_nonces(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[]),
|
||||
OffsetDateTime::now_utc(),
|
||||
200,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -162,7 +157,6 @@ async fn test_channel_message_nonces(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[(4..11, user_a.to_proto())]),
|
||||
OffsetDateTime::now_utc(),
|
||||
100,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -237,41 +231,17 @@ async fn test_unseen_channel_messages(db: &Arc<Database>) {
|
||||
.unwrap();
|
||||
|
||||
let _ = db
|
||||
.create_channel_message(
|
||||
channel_1,
|
||||
user,
|
||||
"1_1",
|
||||
&[],
|
||||
OffsetDateTime::now_utc(),
|
||||
1,
|
||||
None,
|
||||
)
|
||||
.create_channel_message(channel_1, user, "1_1", &[], OffsetDateTime::now_utc(), 1)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let _ = db
|
||||
.create_channel_message(
|
||||
channel_1,
|
||||
user,
|
||||
"1_2",
|
||||
&[],
|
||||
OffsetDateTime::now_utc(),
|
||||
2,
|
||||
None,
|
||||
)
|
||||
.create_channel_message(channel_1, user, "1_2", &[], OffsetDateTime::now_utc(), 2)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let third_message = db
|
||||
.create_channel_message(
|
||||
channel_1,
|
||||
user,
|
||||
"1_3",
|
||||
&[],
|
||||
OffsetDateTime::now_utc(),
|
||||
3,
|
||||
None,
|
||||
)
|
||||
.create_channel_message(channel_1, user, "1_3", &[], OffsetDateTime::now_utc(), 3)
|
||||
.await
|
||||
.unwrap()
|
||||
.message_id;
|
||||
@@ -281,15 +251,7 @@ async fn test_unseen_channel_messages(db: &Arc<Database>) {
|
||||
.unwrap();
|
||||
|
||||
let fourth_message = db
|
||||
.create_channel_message(
|
||||
channel_2,
|
||||
user,
|
||||
"2_1",
|
||||
&[],
|
||||
OffsetDateTime::now_utc(),
|
||||
4,
|
||||
None,
|
||||
)
|
||||
.create_channel_message(channel_2, user, "2_1", &[], OffsetDateTime::now_utc(), 4)
|
||||
.await
|
||||
.unwrap()
|
||||
.message_id;
|
||||
@@ -355,7 +317,6 @@ async fn test_channel_message_mentions(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[(3..10, user_b.to_proto()), (15..22, user_c.to_proto())]),
|
||||
OffsetDateTime::now_utc(),
|
||||
1,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -366,7 +327,6 @@ async fn test_channel_message_mentions(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[(4..11, user_c.to_proto())]),
|
||||
OffsetDateTime::now_utc(),
|
||||
2,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -377,7 +337,6 @@ async fn test_channel_message_mentions(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[]),
|
||||
OffsetDateTime::now_utc(),
|
||||
3,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -388,7 +347,6 @@ async fn test_channel_message_mentions(db: &Arc<Database>) {
|
||||
&mentions_to_proto(&[(0..7, user_b.to_proto())]),
|
||||
OffsetDateTime::now_utc(),
|
||||
4,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -1691,7 +1691,7 @@ async fn leave_project(request: proto::LeaveProject, session: Session) -> Result
|
||||
tracing::info!(
|
||||
%project_id,
|
||||
host_user_id = %project.host_user_id,
|
||||
host_connection_id = ?project.host_connection_id,
|
||||
host_connection_id = %project.host_connection_id,
|
||||
"leave project"
|
||||
);
|
||||
|
||||
@@ -3019,10 +3019,6 @@ async fn send_channel_message(
|
||||
&request.mentions,
|
||||
timestamp,
|
||||
nonce.clone().into(),
|
||||
match request.reply_to_message_id {
|
||||
Some(reply_to_message_id) => Some(MessageId::from_proto(reply_to_message_id)),
|
||||
None => None,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
let message = proto::ChannelMessage {
|
||||
@@ -3032,7 +3028,6 @@ async fn send_channel_message(
|
||||
mentions: request.mentions,
|
||||
timestamp: timestamp.unix_timestamp() as u64,
|
||||
nonce: Some(nonce),
|
||||
reply_to_message_id: request.reply_to_message_id,
|
||||
};
|
||||
broadcast(
|
||||
Some(session.connection_id),
|
||||
|
||||
@@ -161,15 +161,15 @@ async fn test_channel_notes_participant_indices(
|
||||
|
||||
// Clients A, B, and C open the channel notes
|
||||
let channel_view_a = cx_a
|
||||
.update(|cx| ChannelView::open(channel_id, None, workspace_a.clone(), cx))
|
||||
.update(|cx| ChannelView::open(channel_id, workspace_a.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
let channel_view_b = cx_b
|
||||
.update(|cx| ChannelView::open(channel_id, None, workspace_b.clone(), cx))
|
||||
.update(|cx| ChannelView::open(channel_id, workspace_b.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
let channel_view_c = cx_c
|
||||
.update(|cx| ChannelView::open(channel_id, None, workspace_c.clone(), cx))
|
||||
.update(|cx| ChannelView::open(channel_id, workspace_c.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -644,7 +644,7 @@ async fn test_channel_buffer_changes(
|
||||
let project_b = client_b.build_empty_local_project(cx_b);
|
||||
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
|
||||
let channel_view_b = cx_b
|
||||
.update(|cx| ChannelView::open(channel_id, None, workspace_b.clone(), cx))
|
||||
.update(|cx| ChannelView::open(channel_id, workspace_b.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
deterministic.run_until_parked();
|
||||
|
||||
@@ -43,7 +43,6 @@ async fn test_basic_channel_messages(
|
||||
MessageParams {
|
||||
text: "hi @user_c!".into(),
|
||||
mentions: vec![(3..10, client_c.id())],
|
||||
reply_to_message_id: None,
|
||||
},
|
||||
cx,
|
||||
)
|
||||
@@ -403,66 +402,3 @@ async fn test_channel_message_changes(
|
||||
|
||||
assert!(b_has_messages);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_chat_replies(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
|
||||
let mut server = TestServer::start(cx_a.executor()).await;
|
||||
let client_a = server.create_client(cx_a, "user_a").await;
|
||||
let client_b = server.create_client(cx_b, "user_b").await;
|
||||
|
||||
let channel_id = server
|
||||
.make_channel(
|
||||
"the-channel",
|
||||
None,
|
||||
(&client_a, cx_a),
|
||||
&mut [(&client_b, cx_b)],
|
||||
)
|
||||
.await;
|
||||
|
||||
// Client A sends a message, client B should see that there is a new message.
|
||||
let channel_chat_a = client_a
|
||||
.channel_store()
|
||||
.update(cx_a, |store, cx| store.open_channel_chat(channel_id, cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let channel_chat_b = client_b
|
||||
.channel_store()
|
||||
.update(cx_b, |store, cx| store.open_channel_chat(channel_id, cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let msg_id = channel_chat_a
|
||||
.update(cx_a, |c, cx| c.send_message("one".into(), cx).unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
cx_a.run_until_parked();
|
||||
|
||||
let reply_id = channel_chat_b
|
||||
.update(cx_b, |c, cx| {
|
||||
c.send_message(
|
||||
MessageParams {
|
||||
text: "reply".into(),
|
||||
reply_to_message_id: Some(msg_id),
|
||||
mentions: Vec::new(),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
cx_a.run_until_parked();
|
||||
|
||||
channel_chat_a.update(cx_a, |channel_chat, _| {
|
||||
assert_eq!(
|
||||
channel_chat
|
||||
.find_loaded_message(reply_id)
|
||||
.unwrap()
|
||||
.reply_to_message_id,
|
||||
Some(msg_id),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ use workspace::{
|
||||
SplitDirection, Workspace,
|
||||
};
|
||||
|
||||
use super::TestClient;
|
||||
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_basic_following(
|
||||
cx_a: &mut TestAppContext,
|
||||
@@ -1907,7 +1905,7 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
||||
|
||||
// Client A opens the notes for channel 1.
|
||||
let channel_notes_1_a = cx_a
|
||||
.update(|cx| ChannelView::open(channel_1_id, None, workspace_a.clone(), cx))
|
||||
.update(|cx| ChannelView::open(channel_1_id, workspace_a.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
channel_notes_1_a.update(cx_a, |notes, cx| {
|
||||
@@ -1953,7 +1951,7 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
||||
|
||||
// Client A opens the notes for channel 2.
|
||||
let channel_notes_2_a = cx_a
|
||||
.update(|cx| ChannelView::open(channel_2_id, None, workspace_a.clone(), cx))
|
||||
.update(|cx| ChannelView::open(channel_2_id, workspace_a.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
channel_notes_2_a.update(cx_a, |notes, cx| {
|
||||
@@ -1998,82 +1996,3 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async fn join_channel(
|
||||
channel_id: u64,
|
||||
client: &TestClient,
|
||||
cx: &mut TestAppContext,
|
||||
) -> anyhow::Result<()> {
|
||||
cx.update(|cx| workspace::join_channel(channel_id, client.app_state.clone(), None, cx))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn share_workspace(
|
||||
workspace: &View<Workspace>,
|
||||
cx: &mut VisualTestContext,
|
||||
) -> anyhow::Result<u64> {
|
||||
let project = workspace.update(cx, |workspace, _| workspace.project().clone());
|
||||
cx.read(ActiveCall::global)
|
||||
.update(cx, |call, cx| call.share_project(project, cx))
|
||||
.await
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_following_to_channel_notes_other_workspace(
|
||||
cx_a: &mut TestAppContext,
|
||||
cx_b: &mut TestAppContext,
|
||||
) {
|
||||
let (_, client_a, client_b, channel) = TestServer::start2(cx_a, cx_b).await;
|
||||
|
||||
let mut cx_a2 = cx_a.clone();
|
||||
let (workspace_a, cx_a) = client_a.build_test_workspace(cx_a).await;
|
||||
join_channel(channel, &client_a, cx_a).await.unwrap();
|
||||
share_workspace(&workspace_a, cx_a).await.unwrap();
|
||||
|
||||
// a opens 1.txt
|
||||
cx_a.simulate_keystrokes("cmd-p 1 enter");
|
||||
cx_a.run_until_parked();
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
let editor = workspace.active_item(cx).unwrap();
|
||||
assert_eq!(editor.tab_description(0, cx).unwrap(), "1.txt");
|
||||
});
|
||||
|
||||
// b joins channel and is following a
|
||||
join_channel(channel, &client_b, cx_b).await.unwrap();
|
||||
cx_b.run_until_parked();
|
||||
let (workspace_b, cx_b) = client_b.active_workspace(cx_b);
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
let editor = workspace.active_item(cx).unwrap();
|
||||
assert_eq!(editor.tab_description(0, cx).unwrap(), "1.txt");
|
||||
});
|
||||
|
||||
// a opens a second workspace and the channel notes
|
||||
let (workspace_a2, cx_a2) = client_a.build_test_workspace(&mut cx_a2).await;
|
||||
cx_a2.update(|cx| cx.activate_window());
|
||||
cx_a2
|
||||
.update(|cx| ChannelView::open(channel, None, workspace_a2, cx))
|
||||
.await
|
||||
.unwrap();
|
||||
cx_a2.run_until_parked();
|
||||
|
||||
// b should follow a to the channel notes
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
let editor = workspace.active_item_as::<ChannelView>(cx).unwrap();
|
||||
assert_eq!(editor.read(cx).channel(cx).unwrap().id, channel);
|
||||
});
|
||||
|
||||
// a returns to the shared project
|
||||
cx_a.update(|cx| cx.activate_window());
|
||||
cx_a.run_until_parked();
|
||||
|
||||
workspace_a.update(cx_a, |workspace, cx| {
|
||||
let editor = workspace.active_item(cx).unwrap();
|
||||
assert_eq!(editor.tab_description(0, cx).unwrap(), "1.txt");
|
||||
});
|
||||
|
||||
// b should follow a back
|
||||
workspace_b.update(cx_b, |workspace, cx| {
|
||||
let editor = workspace.active_item_as::<Editor>(cx).unwrap();
|
||||
assert_eq!(editor.tab_description(0, cx).unwrap(), "1.txt");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5967,6 +5967,6 @@ async fn test_cmd_k_left(cx: &mut TestAppContext) {
|
||||
cx.executor().advance_clock(Duration::from_secs(2));
|
||||
cx.simulate_keystrokes("left");
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(workspace.items(cx).collect::<Vec<_>>().len() == 2);
|
||||
assert!(workspace.items(cx).collect::<Vec<_>>().len() == 3);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,12 +123,7 @@ impl TestServer {
|
||||
let client_a = server.create_client(cx_a, "user_a").await;
|
||||
let client_b = server.create_client(cx_b, "user_b").await;
|
||||
let channel_id = server
|
||||
.make_channel(
|
||||
"test-channel",
|
||||
None,
|
||||
(&client_a, cx_a),
|
||||
&mut [(&client_b, cx_b)],
|
||||
)
|
||||
.make_channel("a", None, (&client_a, cx_a), &mut [(&client_b, cx_b)])
|
||||
.await;
|
||||
cx_a.run_until_parked();
|
||||
|
||||
|
||||
@@ -26,58 +26,58 @@ test-support = [
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
auto_update.workspace = true
|
||||
call.workspace = true
|
||||
channel.workspace = true
|
||||
client.workspace = true
|
||||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
db.workspace = true
|
||||
editor.workspace = true
|
||||
feature_flags.workspace = true
|
||||
feedback.workspace = true
|
||||
auto_update = { path = "../auto_update" }
|
||||
call = { path = "../call" }
|
||||
channel = { path = "../channel" }
|
||||
client = { path = "../client" }
|
||||
clock = { path = "../clock" }
|
||||
collections = { path = "../collections" }
|
||||
db = { path = "../db" }
|
||||
editor = { path = "../editor" }
|
||||
feature_flags = { path = "../feature_flags" }
|
||||
feedback = { path = "../feedback" }
|
||||
futures.workspace = true
|
||||
fuzzy.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
fuzzy = { path = "../fuzzy" }
|
||||
gpui = { path = "../gpui" }
|
||||
language = { path = "../language" }
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
menu.workspace = true
|
||||
notifications.workspace = true
|
||||
menu = { path = "../menu" }
|
||||
notifications = { path = "../notifications" }
|
||||
parking_lot.workspace = true
|
||||
picker.workspace = true
|
||||
picker = { path = "../picker" }
|
||||
postage.workspace = true
|
||||
project.workspace = true
|
||||
recent_projects.workspace = true
|
||||
rich_text.workspace = true
|
||||
rpc.workspace = true
|
||||
project = { path = "../project" }
|
||||
recent_projects = { path = "../recent_projects" }
|
||||
rich_text = { path = "../rich_text" }
|
||||
rpc = { path = "../rpc" }
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smallvec.workspace = true
|
||||
story = { workspace = true, optional = true }
|
||||
theme.workspace = true
|
||||
theme_selector.workspace = true
|
||||
story = { path = "../story", optional = true }
|
||||
theme = { path = "../theme" }
|
||||
theme_selector = { path = "../theme_selector" }
|
||||
time.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
vcs_menu.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
ui = { path = "../ui" }
|
||||
util = { path = "../util" }
|
||||
vcs_menu = { path = "../vcs_menu" }
|
||||
workspace = { path = "../workspace" }
|
||||
zed_actions = { path = "../zed_actions" }
|
||||
|
||||
[dev-dependencies]
|
||||
call = { workspace = true, features = ["test-support"] }
|
||||
client = { workspace = true, features = ["test-support"] }
|
||||
collections = { workspace = true, features = ["test-support"] }
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
notifications = { workspace = true, features = ["test-support"] }
|
||||
call = { path = "../call", features = ["test-support"] }
|
||||
client = { path = "../client", features = ["test-support"] }
|
||||
collections = { path = "../collections", features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
notifications = { path = "../notifications", features = ["test-support"] }
|
||||
pretty_assertions.workspace = true
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
rpc = { workspace = true, features = ["test-support"] }
|
||||
settings = { workspace = true, features = ["test-support"] }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
rpc = { path = "../rpc", features = ["test-support"] }
|
||||
settings = { path = "../settings", features = ["test-support"] }
|
||||
tree-sitter-markdown.workspace = true
|
||||
util = { workspace = true, features = ["test-support"] }
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
@@ -6,14 +6,11 @@ use client::{
|
||||
Collaborator, ParticipantIndex,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use editor::{
|
||||
display_map::ToDisplayPoint, scroll::Autoscroll, CollaborationHub, DisplayPoint, Editor,
|
||||
EditorEvent,
|
||||
};
|
||||
use editor::{CollaborationHub, Editor, EditorEvent};
|
||||
use gpui::{
|
||||
actions, AnyElement, AnyView, AppContext, ClipboardItem, Entity as _, EventEmitter,
|
||||
FocusableView, IntoElement as _, Model, Pixels, Point, Render, Subscription, Task, View,
|
||||
ViewContext, VisualContext as _, WeakView, WindowContext,
|
||||
actions, AnyElement, AnyView, AppContext, Entity as _, EventEmitter, FocusableView,
|
||||
IntoElement as _, Model, Pixels, Point, Render, Subscription, Task, View, ViewContext,
|
||||
VisualContext as _, WindowContext,
|
||||
};
|
||||
use project::Project;
|
||||
use std::{
|
||||
@@ -26,10 +23,10 @@ use workspace::{
|
||||
item::{FollowableItem, Item, ItemEvent, ItemHandle},
|
||||
register_followable_item,
|
||||
searchable::SearchableItemHandle,
|
||||
ItemNavHistory, Pane, SaveIntent, Toast, ViewId, Workspace, WorkspaceId,
|
||||
ItemNavHistory, Pane, SaveIntent, ViewId, Workspace, WorkspaceId,
|
||||
};
|
||||
|
||||
actions!(collab, [CopyLink]);
|
||||
actions!(collab, [Deploy]);
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
register_followable_item::<ChannelView>(cx)
|
||||
@@ -37,30 +34,21 @@ pub fn init(cx: &mut AppContext) {
|
||||
|
||||
pub struct ChannelView {
|
||||
pub editor: View<Editor>,
|
||||
workspace: WeakView<Workspace>,
|
||||
project: Model<Project>,
|
||||
channel_store: Model<ChannelStore>,
|
||||
channel_buffer: Model<ChannelBuffer>,
|
||||
remote_id: Option<ViewId>,
|
||||
_editor_event_subscription: Subscription,
|
||||
_reparse_subscription: Option<Subscription>,
|
||||
}
|
||||
|
||||
impl ChannelView {
|
||||
pub fn open(
|
||||
channel_id: ChannelId,
|
||||
link_position: Option<String>,
|
||||
workspace: View<Workspace>,
|
||||
cx: &mut WindowContext,
|
||||
) -> Task<Result<View<Self>>> {
|
||||
let pane = workspace.read(cx).active_pane().clone();
|
||||
let channel_view = Self::open_in_pane(
|
||||
channel_id,
|
||||
link_position,
|
||||
pane.clone(),
|
||||
workspace.clone(),
|
||||
cx,
|
||||
);
|
||||
let channel_view = Self::open_in_pane(channel_id, pane.clone(), workspace.clone(), cx);
|
||||
cx.spawn(|mut cx| async move {
|
||||
let channel_view = channel_view.await?;
|
||||
pane.update(&mut cx, |pane, cx| {
|
||||
@@ -78,12 +66,10 @@ impl ChannelView {
|
||||
|
||||
pub fn open_in_pane(
|
||||
channel_id: ChannelId,
|
||||
link_position: Option<String>,
|
||||
pane: View<Pane>,
|
||||
workspace: View<Workspace>,
|
||||
cx: &mut WindowContext,
|
||||
) -> Task<Result<View<Self>>> {
|
||||
let weak_workspace = workspace.downgrade();
|
||||
let workspace = workspace.read(cx);
|
||||
let project = workspace.project().to_owned();
|
||||
let channel_store = ChannelStore::global(cx);
|
||||
@@ -96,13 +82,12 @@ impl ChannelView {
|
||||
let channel_buffer = channel_buffer.await?;
|
||||
let markdown = markdown.await.log_err();
|
||||
|
||||
channel_buffer.update(&mut cx, |channel_buffer, cx| {
|
||||
channel_buffer.buffer().update(cx, |buffer, cx| {
|
||||
channel_buffer.update(&mut cx, |buffer, cx| {
|
||||
buffer.buffer().update(cx, |buffer, cx| {
|
||||
buffer.set_language_registry(language_registry);
|
||||
let Some(markdown) = markdown else {
|
||||
return;
|
||||
};
|
||||
buffer.set_language(Some(markdown), cx);
|
||||
if let Some(markdown) = markdown {
|
||||
buffer.set_language(Some(markdown), cx);
|
||||
}
|
||||
})
|
||||
})?;
|
||||
|
||||
@@ -116,18 +101,12 @@ impl ChannelView {
|
||||
// If this channel buffer is already open in this pane, just return it.
|
||||
if let Some(existing_view) = existing_view.clone() {
|
||||
if existing_view.read(cx).channel_buffer == channel_buffer {
|
||||
if let Some(link_position) = link_position {
|
||||
existing_view.update(cx, |channel_view, cx| {
|
||||
channel_view.focus_position_from_link(link_position, true, cx)
|
||||
});
|
||||
}
|
||||
return existing_view;
|
||||
}
|
||||
}
|
||||
|
||||
let view = cx.new_view(|cx| {
|
||||
let mut this =
|
||||
Self::new(project, weak_workspace, channel_store, channel_buffer, cx);
|
||||
let mut this = Self::new(project, channel_store, channel_buffer, cx);
|
||||
this.acknowledge_buffer_version(cx);
|
||||
this
|
||||
});
|
||||
@@ -142,12 +121,6 @@ impl ChannelView {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(link_position) = link_position {
|
||||
view.update(cx, |channel_view, cx| {
|
||||
channel_view.focus_position_from_link(link_position, true, cx)
|
||||
});
|
||||
}
|
||||
|
||||
view
|
||||
})
|
||||
})
|
||||
@@ -155,29 +128,16 @@ impl ChannelView {
|
||||
|
||||
pub fn new(
|
||||
project: Model<Project>,
|
||||
workspace: WeakView<Workspace>,
|
||||
channel_store: Model<ChannelStore>,
|
||||
channel_buffer: Model<ChannelBuffer>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let buffer = channel_buffer.read(cx).buffer();
|
||||
let this = cx.view().downgrade();
|
||||
let editor = cx.new_view(|cx| {
|
||||
let mut editor = Editor::for_buffer(buffer, None, cx);
|
||||
editor.set_collaboration_hub(Box::new(ChannelBufferCollaborationHub(
|
||||
channel_buffer.clone(),
|
||||
)));
|
||||
editor.set_custom_context_menu(move |_, position, cx| {
|
||||
let this = this.clone();
|
||||
Some(ui::ContextMenu::build(cx, move |menu, _| {
|
||||
menu.entry("Copy link to section", None, move |cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
this.copy_link_for_position(position.clone(), cx)
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
}))
|
||||
});
|
||||
editor
|
||||
});
|
||||
let _editor_event_subscription =
|
||||
@@ -188,94 +148,14 @@ impl ChannelView {
|
||||
|
||||
Self {
|
||||
editor,
|
||||
workspace,
|
||||
project,
|
||||
channel_store,
|
||||
channel_buffer,
|
||||
remote_id: None,
|
||||
_editor_event_subscription,
|
||||
_reparse_subscription: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_position_from_link(
|
||||
&mut self,
|
||||
position: String,
|
||||
first_attempt: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let position = Channel::slug(&position).to_lowercase();
|
||||
let snapshot = self.editor.update(cx, |editor, cx| editor.snapshot(cx));
|
||||
|
||||
if let Some(outline) = snapshot.buffer_snapshot.outline(None) {
|
||||
if let Some(item) = outline
|
||||
.items
|
||||
.iter()
|
||||
.find(|item| &Channel::slug(&item.text).to_lowercase() == &position)
|
||||
{
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.change_selections(Some(Autoscroll::focused()), cx, |s| {
|
||||
s.replace_cursors_with(|map| vec![item.range.start.to_display_point(&map)])
|
||||
})
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if !first_attempt {
|
||||
return;
|
||||
}
|
||||
self._reparse_subscription = Some(cx.subscribe(
|
||||
&self.editor,
|
||||
move |this, _, e: &EditorEvent, cx| {
|
||||
match e {
|
||||
EditorEvent::Reparsed => {
|
||||
this.focus_position_from_link(position.clone(), false, cx);
|
||||
this._reparse_subscription.take();
|
||||
}
|
||||
EditorEvent::Edited | EditorEvent::SelectionsChanged { local: true } => {
|
||||
this._reparse_subscription.take();
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
fn copy_link(&mut self, _: &CopyLink, cx: &mut ViewContext<Self>) {
|
||||
let position = self
|
||||
.editor
|
||||
.update(cx, |editor, cx| editor.selections.newest_display(cx).start);
|
||||
self.copy_link_for_position(position, cx)
|
||||
}
|
||||
|
||||
fn copy_link_for_position(&self, position: DisplayPoint, cx: &mut ViewContext<Self>) {
|
||||
let snapshot = self.editor.update(cx, |editor, cx| editor.snapshot(cx));
|
||||
|
||||
let mut closest_heading = None;
|
||||
|
||||
if let Some(outline) = snapshot.buffer_snapshot.outline(None) {
|
||||
for item in outline.items {
|
||||
if item.range.start.to_display_point(&snapshot) > position {
|
||||
break;
|
||||
}
|
||||
closest_heading = Some(item);
|
||||
}
|
||||
}
|
||||
|
||||
let Some(channel) = self.channel(cx) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let link = channel.notes_link(closest_heading.map(|heading| heading.text));
|
||||
cx.write_to_clipboard(ClipboardItem::new(link));
|
||||
self.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
workspace.show_toast(Toast::new(0, "Link copied to clipboard"), cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
pub fn channel(&self, cx: &AppContext) -> Option<Arc<Channel>> {
|
||||
self.channel_buffer.read(cx).channel(cx)
|
||||
}
|
||||
@@ -335,11 +215,8 @@ impl ChannelView {
|
||||
impl EventEmitter<EditorEvent> for ChannelView {}
|
||||
|
||||
impl Render for ChannelView {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.size_full()
|
||||
.on_action(cx.listener(Self::copy_link))
|
||||
.child(self.editor.clone())
|
||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
self.editor.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +274,6 @@ impl Item for ChannelView {
|
||||
Some(cx.new_view(|cx| {
|
||||
Self::new(
|
||||
self.project.clone(),
|
||||
self.workspace.clone(),
|
||||
self.channel_store.clone(),
|
||||
self.channel_buffer.clone(),
|
||||
cx,
|
||||
@@ -480,7 +356,7 @@ impl FollowableItem for ChannelView {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
let open = ChannelView::open_in_pane(state.channel_id, None, pane, workspace, cx);
|
||||
let open = ChannelView::open_in_pane(state.channel_id, pane, workspace, cx);
|
||||
|
||||
Some(cx.spawn(|mut cx| async move {
|
||||
let this = open.await?;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use crate::{collab_panel, ChatPanelSettings};
|
||||
use anyhow::Result;
|
||||
use call::{room, ActiveCall};
|
||||
use channel::{ChannelChat, ChannelChatEvent, ChannelMessage, ChannelMessageId, ChannelStore};
|
||||
use channel::{ChannelChat, ChannelChatEvent, ChannelMessageId, ChannelStore};
|
||||
use client::Client;
|
||||
use collections::HashMap;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::Editor;
|
||||
use gpui::{
|
||||
actions, div, list, prelude::*, px, Action, AppContext, AsyncWindowContext, CursorStyle,
|
||||
DismissEvent, ElementId, EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight,
|
||||
HighlightStyle, ListOffset, ListScrollEvent, ListState, Model, Render, StyledText,
|
||||
Subscription, Task, View, ViewContext, VisualContext, WeakView,
|
||||
actions, div, list, prelude::*, px, Action, AppContext, AsyncWindowContext, DismissEvent,
|
||||
ElementId, EventEmitter, Fill, FocusHandle, FocusableView, FontWeight, ListOffset,
|
||||
ListScrollEvent, ListState, Model, Render, Subscription, Task, View, ViewContext,
|
||||
VisualContext, WeakView,
|
||||
};
|
||||
use language::LanguageRegistry;
|
||||
use menu::Confirm;
|
||||
@@ -23,7 +23,7 @@ use std::{sync::Arc, time::Duration};
|
||||
use time::{OffsetDateTime, UtcOffset};
|
||||
use ui::{
|
||||
popover_menu, prelude::*, Avatar, Button, ContextMenu, IconButton, IconName, KeyBinding, Label,
|
||||
TabBar, Tooltip,
|
||||
TabBar,
|
||||
};
|
||||
use util::{ResultExt, TryFutureExt};
|
||||
use workspace::{
|
||||
@@ -62,7 +62,6 @@ pub struct ChatPanel {
|
||||
markdown_data: HashMap<ChannelMessageId, RichText>,
|
||||
focus_handle: FocusHandle,
|
||||
open_context_menu: Option<(u64, Subscription)>,
|
||||
highlighted_message: Option<(u64, Task<()>)>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@@ -125,7 +124,6 @@ impl ChatPanel {
|
||||
markdown_data: Default::default(),
|
||||
focus_handle: cx.focus_handle(),
|
||||
open_context_menu: None,
|
||||
highlighted_message: None,
|
||||
};
|
||||
|
||||
if let Some(channel_id) = ActiveCall::global(cx)
|
||||
@@ -238,7 +236,6 @@ impl ChatPanel {
|
||||
let channel_name = chat.channel(cx).map(|channel| channel.name.clone());
|
||||
self.message_editor.update(cx, |editor, cx| {
|
||||
editor.set_channel(channel_id, channel_name, cx);
|
||||
editor.clear_reply_to_message_id();
|
||||
});
|
||||
};
|
||||
let subscription = cx.subscribe(&chat, Self::channel_did_change);
|
||||
@@ -288,99 +285,6 @@ impl ChatPanel {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_replied_to_message(
|
||||
&mut self,
|
||||
message_id: Option<ChannelMessageId>,
|
||||
reply_to_message: &ChannelMessage,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> impl IntoElement {
|
||||
let body_element_id: ElementId = match message_id {
|
||||
Some(ChannelMessageId::Saved(id)) => ("reply-to-saved-message", id).into(),
|
||||
Some(ChannelMessageId::Pending(id)) => ("reply-to-pending-message", id).into(), // This should never happen
|
||||
None => ("composing-reply").into(),
|
||||
};
|
||||
|
||||
let message_element_id: ElementId = match message_id {
|
||||
Some(ChannelMessageId::Saved(id)) => ("reply-to-saved-message-container", id).into(),
|
||||
Some(ChannelMessageId::Pending(id)) => {
|
||||
("reply-to-pending-message-container", id).into()
|
||||
} // This should never happen
|
||||
None => ("composing-reply-container").into(),
|
||||
};
|
||||
|
||||
let current_channel_id = self.channel_id(cx);
|
||||
let reply_to_message_id = reply_to_message.id;
|
||||
|
||||
let reply_to_message_body = self
|
||||
.markdown_data
|
||||
.entry(reply_to_message.id)
|
||||
.or_insert_with(|| {
|
||||
Self::render_markdown_with_mentions(
|
||||
&self.languages,
|
||||
self.client.id(),
|
||||
reply_to_message,
|
||||
)
|
||||
});
|
||||
|
||||
const REPLY_TO_PREFIX: &str = "Reply to @";
|
||||
|
||||
div().flex_grow().child(
|
||||
v_flex()
|
||||
.id(message_element_id)
|
||||
.text_ui_xs()
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_x_1()
|
||||
.items_center()
|
||||
.justify_start()
|
||||
.overflow_x_hidden()
|
||||
.whitespace_nowrap()
|
||||
.child(
|
||||
StyledText::new(format!(
|
||||
"{}{}",
|
||||
REPLY_TO_PREFIX,
|
||||
reply_to_message.sender.github_login.clone()
|
||||
))
|
||||
.with_highlights(
|
||||
&cx.text_style(),
|
||||
vec![(
|
||||
(REPLY_TO_PREFIX.len() - 1)
|
||||
..(reply_to_message.sender.github_login.len()
|
||||
+ REPLY_TO_PREFIX.len()),
|
||||
HighlightStyle {
|
||||
font_weight: Some(FontWeight::BOLD),
|
||||
..Default::default()
|
||||
},
|
||||
)],
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.border_l_2()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.px_1()
|
||||
.py_0p5()
|
||||
.mb_1()
|
||||
.overflow_hidden()
|
||||
.child(
|
||||
div()
|
||||
.max_h_12()
|
||||
.child(reply_to_message_body.element(body_element_id, cx)),
|
||||
),
|
||||
)
|
||||
.cursor(CursorStyle::PointingHand)
|
||||
.tooltip(|cx| Tooltip::text("Go to message", cx))
|
||||
.on_click(cx.listener(move |chat_panel, _, cx| {
|
||||
if let Some(channel_id) = current_channel_id {
|
||||
chat_panel
|
||||
.select_channel(channel_id, reply_to_message_id.into(), cx)
|
||||
.detach_and_log_err(cx)
|
||||
}
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_message(&mut self, ix: usize, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let active_chat = &self.active_chat.as_ref().unwrap().0;
|
||||
let (message, is_continuation_from_previous, is_admin) =
|
||||
@@ -413,9 +317,18 @@ impl ChatPanel {
|
||||
});
|
||||
|
||||
let _is_pending = message.is_pending();
|
||||
let text = self.markdown_data.entry(message.id).or_insert_with(|| {
|
||||
Self::render_markdown_with_mentions(&self.languages, self.client.id(), &message)
|
||||
});
|
||||
|
||||
let belongs_to_user = Some(message.sender.id) == self.client.user_id();
|
||||
let can_delete_message = belongs_to_user || is_admin;
|
||||
let message_id_to_remove = if let (ChannelMessageId::Saved(id), true) =
|
||||
(message.id, belongs_to_user || is_admin)
|
||||
{
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let element_id: ElementId = match message.id {
|
||||
ChannelMessageId::Saved(id) => ("saved-message", id).into(),
|
||||
@@ -428,41 +341,19 @@ impl ChatPanel {
|
||||
.iter()
|
||||
.any(|m| Some(m.1) == self.client.user_id());
|
||||
|
||||
let message_id = match message.id {
|
||||
ChannelMessageId::Saved(id) => Some(id),
|
||||
ChannelMessageId::Pending(_) => None,
|
||||
};
|
||||
|
||||
let reply_to_message = message
|
||||
.reply_to_message_id
|
||||
.map(|id| active_chat.read(cx).find_loaded_message(id))
|
||||
.flatten()
|
||||
.cloned();
|
||||
|
||||
let replied_to_you =
|
||||
reply_to_message.as_ref().map(|m| m.sender.id) == self.client.user_id();
|
||||
|
||||
let is_highlighted_message = self
|
||||
.highlighted_message
|
||||
.as_ref()
|
||||
.is_some_and(|(id, _)| Some(id) == message_id.as_ref());
|
||||
let background = if is_highlighted_message {
|
||||
cx.theme().status().info_background
|
||||
} else if mentioning_you || replied_to_you {
|
||||
cx.theme().colors().background
|
||||
} else {
|
||||
cx.theme().colors().panel_background
|
||||
};
|
||||
|
||||
v_flex().w_full().relative().child(
|
||||
div()
|
||||
.bg(background)
|
||||
.bg(if mentioning_you {
|
||||
Fill::from(cx.theme().colors().background)
|
||||
} else {
|
||||
Fill::default()
|
||||
})
|
||||
.rounded_md()
|
||||
.overflow_hidden()
|
||||
.px_1()
|
||||
.py_0p5()
|
||||
.when(!is_continuation_from_previous, |this| {
|
||||
this.mt_2().child(
|
||||
this.mt_1().child(
|
||||
h_flex()
|
||||
.text_ui_sm()
|
||||
.child(div().absolute().child(
|
||||
@@ -486,86 +377,36 @@ impl ChatPanel {
|
||||
),
|
||||
)
|
||||
})
|
||||
.when(
|
||||
message.reply_to_message_id.is_some() && reply_to_message.is_none(),
|
||||
|this| {
|
||||
const MESSAGE_DELETED: &str = "Message has been deleted";
|
||||
|
||||
let body_text = StyledText::new(MESSAGE_DELETED).with_highlights(
|
||||
&cx.text_style(),
|
||||
vec![(
|
||||
0..MESSAGE_DELETED.len(),
|
||||
HighlightStyle {
|
||||
font_style: Some(FontStyle::Italic),
|
||||
..Default::default()
|
||||
},
|
||||
)],
|
||||
);
|
||||
|
||||
this.child(
|
||||
.when(mentioning_you, |this| this.mt_1())
|
||||
.child(
|
||||
v_flex()
|
||||
.w_full()
|
||||
.text_ui_sm()
|
||||
.id(element_id)
|
||||
.group("")
|
||||
.child(text.element("body".into(), cx))
|
||||
.child(
|
||||
div()
|
||||
.border_l_2()
|
||||
.text_ui_xs()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.px_1()
|
||||
.py_0p5()
|
||||
.child(body_text),
|
||||
)
|
||||
},
|
||||
)
|
||||
.when_some(reply_to_message, |el, reply_to_message| {
|
||||
el.child(self.render_replied_to_message(
|
||||
Some(message.id),
|
||||
&reply_to_message,
|
||||
cx,
|
||||
))
|
||||
})
|
||||
.when(mentioning_you || replied_to_you, |this| this.my_0p5())
|
||||
.map(|el| {
|
||||
let text = self.markdown_data.entry(message.id).or_insert_with(|| {
|
||||
Self::render_markdown_with_mentions(
|
||||
&self.languages,
|
||||
self.client.id(),
|
||||
&message,
|
||||
)
|
||||
});
|
||||
el.child(
|
||||
v_flex()
|
||||
.w_full()
|
||||
.text_ui_sm()
|
||||
.id(element_id)
|
||||
.group("")
|
||||
.child(text.element("body".into(), cx))
|
||||
.child(
|
||||
div()
|
||||
.absolute()
|
||||
.z_index(1)
|
||||
.right_0()
|
||||
.w_6()
|
||||
.bg(background)
|
||||
.when(!self.has_open_menu(message_id), |el| {
|
||||
el.visible_on_hover("")
|
||||
})
|
||||
.when_some(message_id, |el, message_id| {
|
||||
el.child(
|
||||
popover_menu(("menu", message_id))
|
||||
.trigger(IconButton::new(
|
||||
("trigger", message_id),
|
||||
IconName::Ellipsis,
|
||||
))
|
||||
.menu(move |cx| {
|
||||
Some(Self::render_message_menu(
|
||||
&this,
|
||||
message_id,
|
||||
can_delete_message,
|
||||
cx,
|
||||
))
|
||||
}),
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
}),
|
||||
.absolute()
|
||||
.z_index(1)
|
||||
.right_0()
|
||||
.w_6()
|
||||
.bg(cx.theme().colors().panel_background)
|
||||
.when(!self.has_open_menu(message_id_to_remove), |el| {
|
||||
el.visible_on_hover("")
|
||||
})
|
||||
.children(message_id_to_remove.map(|message_id| {
|
||||
popover_menu(("menu", message_id))
|
||||
.trigger(IconButton::new(
|
||||
("trigger", message_id),
|
||||
IconName::Ellipsis,
|
||||
))
|
||||
.menu(move |cx| {
|
||||
Some(Self::render_message_menu(&this, message_id, cx))
|
||||
})
|
||||
})),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -579,27 +420,13 @@ impl ChatPanel {
|
||||
fn render_message_menu(
|
||||
this: &View<Self>,
|
||||
message_id: u64,
|
||||
can_delete_message: bool,
|
||||
cx: &mut WindowContext,
|
||||
) -> View<ContextMenu> {
|
||||
let menu = {
|
||||
ContextMenu::build(cx, move |menu, cx| {
|
||||
menu.entry(
|
||||
"Reply to message",
|
||||
None,
|
||||
cx.handler_for(&this, move |this, cx| {
|
||||
this.message_editor.update(cx, |editor, cx| {
|
||||
editor.set_reply_to_message_id(message_id);
|
||||
editor.focus_handle(cx).focus(cx);
|
||||
})
|
||||
}),
|
||||
)
|
||||
.when(can_delete_message, move |menu| {
|
||||
menu.entry(
|
||||
"Delete message",
|
||||
None,
|
||||
cx.handler_for(&this, move |this, cx| this.remove_message(message_id, cx)),
|
||||
)
|
||||
let this = this.clone();
|
||||
ContextMenu::build(cx, move |menu, _| {
|
||||
menu.entry("Delete message", None, move |cx| {
|
||||
this.update(cx, |this, cx| this.remove_message(message_id, cx))
|
||||
})
|
||||
})
|
||||
};
|
||||
@@ -690,21 +517,7 @@ impl ChatPanel {
|
||||
ChannelChat::load_history_since_message(chat.clone(), message_id, (*cx).clone())
|
||||
.await
|
||||
{
|
||||
let task = cx.spawn({
|
||||
let this = this.clone();
|
||||
|
||||
|mut cx| async move {
|
||||
cx.background_executor().timer(Duration::from_secs(2)).await;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.highlighted_message.take();
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.highlighted_message = Some((message_id, task));
|
||||
if this.active_chat.as_ref().map_or(false, |(c, _)| *c == chat) {
|
||||
this.message_list.scroll_to(ListOffset {
|
||||
item_ix,
|
||||
@@ -723,8 +536,6 @@ impl ChatPanel {
|
||||
|
||||
impl Render for ChatPanel {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let reply_to_message_id = self.message_editor.read(cx).reply_to_message_id();
|
||||
|
||||
v_flex()
|
||||
.track_focus(&self.focus_handle)
|
||||
.full()
|
||||
@@ -747,7 +558,7 @@ impl Render for ChatPanel {
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(div().flex_grow().px_2().map(|this| {
|
||||
.child(div().flex_grow().px_2().pt_1().map(|this| {
|
||||
if self.active_chat.is_some() {
|
||||
this.child(list(self.message_list.clone()).full())
|
||||
} else {
|
||||
@@ -778,58 +589,25 @@ impl Render for ChatPanel {
|
||||
)
|
||||
}
|
||||
}))
|
||||
.when_some(reply_to_message_id, |el, reply_to_message_id| {
|
||||
let reply_message = self
|
||||
.active_chat()
|
||||
.map(|active_chat| {
|
||||
active_chat.read(cx).messages().iter().find_map(|m| {
|
||||
if m.id == ChannelMessageId::Saved(reply_to_message_id) {
|
||||
Some(m)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.child(
|
||||
h_flex()
|
||||
.when(!self.is_scrolled_to_bottom, |el| {
|
||||
el.border_t_1().border_color(cx.theme().colors().border)
|
||||
})
|
||||
.flatten()
|
||||
.cloned();
|
||||
|
||||
el.when_some(reply_message, |el, reply_message| {
|
||||
el.child(
|
||||
div()
|
||||
.when(!self.is_scrolled_to_bottom, |el| {
|
||||
el.border_t_1().border_color(cx.theme().colors().border)
|
||||
})
|
||||
.flex()
|
||||
.w_full()
|
||||
.items_start()
|
||||
.overflow_hidden()
|
||||
.py_1()
|
||||
.px_2()
|
||||
.bg(cx.theme().colors().background)
|
||||
.child(self.render_replied_to_message(None, &reply_message, cx))
|
||||
.child(
|
||||
IconButton::new("close-reply-preview", IconName::Close)
|
||||
.shape(ui::IconButtonShape::Square)
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.message_editor.update(cx, |editor, _| {
|
||||
editor.clear_reply_to_message_id()
|
||||
});
|
||||
})),
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
.children(
|
||||
Some(
|
||||
h_flex()
|
||||
.when(
|
||||
!self.is_scrolled_to_bottom && reply_to_message_id.is_none(),
|
||||
|el| el.border_t_1().border_color(cx.theme().colors().border),
|
||||
)
|
||||
.p_2()
|
||||
.map(|el| el.child(self.message_editor.clone())),
|
||||
)
|
||||
.filter(|_| self.active_chat.is_some()),
|
||||
.p_2()
|
||||
.map(|el| {
|
||||
if self.active_chat.is_some() {
|
||||
el.child(self.message_editor.clone())
|
||||
} else {
|
||||
el.child(
|
||||
div()
|
||||
.rounded_md()
|
||||
.h_6()
|
||||
.w_full()
|
||||
.bg(cx.theme().colors().editor_background),
|
||||
)
|
||||
}
|
||||
}),
|
||||
)
|
||||
.into_any()
|
||||
}
|
||||
@@ -969,7 +747,6 @@ mod tests {
|
||||
}),
|
||||
nonce: 5,
|
||||
mentions: vec![(ranges[0].clone(), 101), (ranges[1].clone(), 102)],
|
||||
reply_to_message_id: None,
|
||||
};
|
||||
|
||||
let message = ChatPanel::render_markdown_with_mentions(&language_registry, 102, &message);
|
||||
|
||||
@@ -34,7 +34,6 @@ pub struct MessageEditor {
|
||||
mentions: Vec<UserId>,
|
||||
mentions_task: Option<Task<()>>,
|
||||
channel_id: Option<ChannelId>,
|
||||
reply_to_message_id: Option<u64>,
|
||||
}
|
||||
|
||||
struct MessageEditorCompletionProvider(WeakView<MessageEditor>);
|
||||
@@ -113,22 +112,9 @@ impl MessageEditor {
|
||||
channel_id: None,
|
||||
mentions: Vec::new(),
|
||||
mentions_task: None,
|
||||
reply_to_message_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reply_to_message_id(&self) -> Option<u64> {
|
||||
self.reply_to_message_id
|
||||
}
|
||||
|
||||
pub fn set_reply_to_message_id(&mut self, reply_to_message_id: u64) {
|
||||
self.reply_to_message_id = Some(reply_to_message_id);
|
||||
}
|
||||
|
||||
pub fn clear_reply_to_message_id(&mut self) {
|
||||
self.reply_to_message_id = None;
|
||||
}
|
||||
|
||||
pub fn set_channel(
|
||||
&mut self,
|
||||
channel_id: u64,
|
||||
@@ -186,13 +172,8 @@ impl MessageEditor {
|
||||
|
||||
editor.clear(cx);
|
||||
self.mentions.clear();
|
||||
let reply_to_message_id = std::mem::take(&mut self.reply_to_message_id);
|
||||
|
||||
MessageParams {
|
||||
text,
|
||||
mentions,
|
||||
reply_to_message_id,
|
||||
}
|
||||
MessageParams { text, mentions }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -360,7 +341,6 @@ impl Render for MessageEditor {
|
||||
line_height: relative(1.3).into(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
};
|
||||
|
||||
@@ -444,7 +424,6 @@ mod tests {
|
||||
MessageParams {
|
||||
text,
|
||||
mentions: vec![(ranges[0].clone(), 101), (ranges[1].clone(), 102)],
|
||||
reply_to_message_id: None
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ use util::{maybe, ResultExt, TryFutureExt};
|
||||
use workspace::{
|
||||
dock::{DockPosition, Panel, PanelEvent},
|
||||
notifications::{DetachAndPromptErr, NotifyResultExt, NotifyTaskExt},
|
||||
OpenChannelNotes, Workspace,
|
||||
Workspace,
|
||||
};
|
||||
|
||||
actions!(
|
||||
@@ -69,19 +69,6 @@ pub fn init(cx: &mut AppContext) {
|
||||
workspace.register_action(|workspace, _: &ToggleFocus, cx| {
|
||||
workspace.toggle_panel_focus::<CollabPanel>(cx);
|
||||
});
|
||||
workspace.register_action(|_, _: &OpenChannelNotes, cx| {
|
||||
let channel_id = ActiveCall::global(cx)
|
||||
.read(cx)
|
||||
.room()
|
||||
.and_then(|room| room.read(cx).channel_id());
|
||||
|
||||
if let Some(channel_id) = channel_id {
|
||||
let workspace = cx.view().clone();
|
||||
cx.window_context().defer(move |cx| {
|
||||
ChannelView::open(channel_id, None, workspace, cx).detach_and_log_err(cx)
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
@@ -970,7 +957,7 @@ impl CollabPanel {
|
||||
.child(render_tree_branch(false, true, cx))
|
||||
.child(IconButton::new(0, IconName::File)),
|
||||
)
|
||||
.child(Label::new("notes"))
|
||||
.child(div().h_7().w_full().child(Label::new("notes")))
|
||||
.tooltip(move |cx| Tooltip::text("Open Channel Notes", cx))
|
||||
}
|
||||
|
||||
@@ -1691,7 +1678,7 @@ impl CollabPanel {
|
||||
|
||||
fn open_channel_notes(&mut self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||
if let Some(workspace) = self.workspace.upgrade() {
|
||||
ChannelView::open(channel_id, None, workspace, cx).detach();
|
||||
ChannelView::open(channel_id, workspace, cx).detach();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2068,7 +2055,6 @@ impl CollabPanel {
|
||||
line_height: relative(1.3).into(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
};
|
||||
|
||||
|
||||
@@ -562,23 +562,14 @@ impl CollabTitlebarItem {
|
||||
}
|
||||
|
||||
fn window_activation_changed(&mut self, cx: &mut ViewContext<Self>) {
|
||||
if cx.is_window_active() {
|
||||
ActiveCall::global(cx)
|
||||
.update(cx, |call, cx| call.set_location(Some(&self.project), cx))
|
||||
.detach_and_log_err(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
if cx.active_window().is_none() {
|
||||
ActiveCall::global(cx)
|
||||
.update(cx, |call, cx| call.set_location(None, cx))
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
self.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
workspace.update_active_view_for_followers(cx);
|
||||
})
|
||||
.ok();
|
||||
let project = if cx.is_window_active() {
|
||||
Some(self.project.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
ActiveCall::global(cx)
|
||||
.update(cx, |call, cx| call.set_location(project.as_ref(), cx))
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn active_call_changed(&mut self, cx: &mut ViewContext<Self>) {
|
||||
|
||||
@@ -16,4 +16,4 @@ doctest = true
|
||||
[dependencies]
|
||||
itertools = { version = "0.11.0", optional = true }
|
||||
palette = "0.7.3"
|
||||
story = { workspace = true, optional = true }
|
||||
story = { path = "../story", optional = true }
|
||||
|
||||
@@ -11,32 +11,32 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
client.workspace = true
|
||||
collections.workspace = true
|
||||
client = { path = "../client" }
|
||||
collections = { path = "../collections" }
|
||||
# HACK: We're only depending on `copilot` here for `CommandPaletteFilter`. See the attached comment on that type.
|
||||
copilot.workspace = true
|
||||
editor.workspace = true
|
||||
fuzzy.workspace = true
|
||||
gpui.workspace = true
|
||||
picker.workspace = true
|
||||
project.workspace = true
|
||||
release_channel.workspace = true
|
||||
copilot = { path = "../copilot" }
|
||||
editor = { path = "../editor" }
|
||||
fuzzy = { path = "../fuzzy" }
|
||||
gpui = { path = "../gpui" }
|
||||
picker = { path = "../picker" }
|
||||
project = { path = "../project" }
|
||||
release_channel = { path = "../release_channel" }
|
||||
serde.workspace = true
|
||||
settings.workspace = true
|
||||
theme.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
theme = { path = "../theme" }
|
||||
ui = { path = "../ui" }
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace" }
|
||||
zed_actions = { path = "../zed_actions" }
|
||||
|
||||
[dev-dependencies]
|
||||
ctor.workspace = true
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
env_logger.workspace = true
|
||||
go_to_line.workspace = true
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
menu.workspace = true
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
go_to_line = { path = "../go_to_line" }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
menu = { path = "../menu" }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
serde_json.workspace = true
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
@@ -23,28 +23,28 @@ test-support = [
|
||||
anyhow.workspace = true
|
||||
async-compression.workspace = true
|
||||
async-tar = "0.4.2"
|
||||
collections.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
language = { path = "../language" }
|
||||
log.workspace = true
|
||||
lsp.workspace = true
|
||||
node_runtime.workspace = true
|
||||
lsp = { path = "../lsp" }
|
||||
node_runtime = { path = "../node_runtime" }
|
||||
parking_lot.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smol.workspace = true
|
||||
theme.workspace = true
|
||||
util.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
util = { path = "../util" }
|
||||
|
||||
[dev-dependencies]
|
||||
clock.workspace = true
|
||||
collections = { workspace = true, features = ["test-support"] }
|
||||
fs = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
lsp = { workspace = true, features = ["test-support"] }
|
||||
rpc = { workspace = true, features = ["test-support"] }
|
||||
settings = { workspace = true, features = ["test-support"] }
|
||||
util = { workspace = true, features = ["test-support"] }
|
||||
clock = { path = "../clock" }
|
||||
collections = { path = "../collections", features = ["test-support"] }
|
||||
fs = { path = "../fs", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
lsp = { path = "../lsp", features = ["test-support"] }
|
||||
rpc = { path = "../rpc", features = ["test-support"] }
|
||||
settings = { path = "../settings", features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
|
||||
@@ -976,8 +976,7 @@ async fn get_copilot_lsp(http: Arc<dyn HttpClient>) -> anyhow::Result<PathBuf> {
|
||||
|
||||
///Check for the latest copilot language server and download it if we haven't already
|
||||
async fn fetch_latest(http: Arc<dyn HttpClient>) -> anyhow::Result<PathBuf> {
|
||||
let release =
|
||||
latest_github_release("zed-industries/copilot", true, false, http.clone()).await?;
|
||||
let release = latest_github_release("zed-industries/copilot", false, http.clone()).await?;
|
||||
|
||||
let version_dir = &*paths::COPILOT_DIR.join(format!("copilot-{}", release.name));
|
||||
|
||||
@@ -998,7 +997,7 @@ async fn get_copilot_lsp(http: Arc<dyn HttpClient>) -> anyhow::Result<PathBuf> {
|
||||
let mut response = http
|
||||
.get(url, Default::default(), true)
|
||||
.await
|
||||
.context("error downloading copilot release")?;
|
||||
.map_err(|err| anyhow!("error downloading copilot release: {}", err))?;
|
||||
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
|
||||
let archive = Archive::new(decompressed_bytes);
|
||||
archive.unpack(dist_dir).await?;
|
||||
|
||||
@@ -11,19 +11,19 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
copilot.workspace = true
|
||||
editor.workspace = true
|
||||
fs.workspace = true
|
||||
copilot = { path = "../copilot" }
|
||||
editor = { path = "../editor" }
|
||||
fs = { path = "../fs" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
settings.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
language = { path = "../language" }
|
||||
settings = { path = "../settings" }
|
||||
smol.workspace = true
|
||||
theme.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
ui = { path = "../ui" }
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace" }
|
||||
zed_actions = { path = "../zed_actions" }
|
||||
|
||||
[dev-dependencies]
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
|
||||
@@ -15,21 +15,21 @@ test-support = []
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
collections.workspace = true
|
||||
gpui.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
gpui = { path = "../gpui" }
|
||||
indoc.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
parking_lot.workspace = true
|
||||
release_channel.workspace = true
|
||||
release_channel = { path = "../release_channel" }
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
smol.workspace = true
|
||||
sqlez.workspace = true
|
||||
sqlez_macros.workspace = true
|
||||
util.workspace = true
|
||||
sqlez = { path = "../sqlez" }
|
||||
sqlez_macros = { path = "../sqlez_macros" }
|
||||
util = { path = "../util" }
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger.workspace = true
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
tempfile.workspace = true
|
||||
|
||||
@@ -11,32 +11,32 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
collections.workspace = true
|
||||
editor.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
editor = { path = "../editor" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
language = { path = "../language" }
|
||||
log.workspace = true
|
||||
lsp.workspace = true
|
||||
lsp = { path = "../lsp" }
|
||||
postage.workspace = true
|
||||
project.workspace = true
|
||||
project = { path = "../project" }
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smallvec.workspace = true
|
||||
theme.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
ui = { path = "../ui" }
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace" }
|
||||
|
||||
[dev-dependencies]
|
||||
client = { workspace = true, features = ["test-support"] }
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
lsp = { workspace = true, features = ["test-support"] }
|
||||
client = { path = "../client", features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
lsp = { path = "../lsp", features = ["test-support"] }
|
||||
serde_json.workspace = true
|
||||
theme = { workspace = true, features = ["test-support"] }
|
||||
theme = { path = "../theme", features = ["test-support"] }
|
||||
unindent.workspace = true
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
@@ -20,74 +20,73 @@ test-support = [
|
||||
"util/test-support",
|
||||
"workspace/test-support",
|
||||
"tree-sitter-rust",
|
||||
"tree-sitter-typescript",
|
||||
"tree-sitter-typescript"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
aho-corasick = "1.1"
|
||||
anyhow.workspace = true
|
||||
client.workspace = true
|
||||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
client = { path = "../client" }
|
||||
clock = { path = "../clock" }
|
||||
collections = { path = "../collections" }
|
||||
convert_case = "0.6.0"
|
||||
copilot.workspace = true
|
||||
db.workspace = true
|
||||
copilot = { path = "../copilot" }
|
||||
db = { path = "../db" }
|
||||
futures.workspace = true
|
||||
fuzzy.workspace = true
|
||||
git.workspace = true
|
||||
gpui.workspace = true
|
||||
fuzzy = { path = "../fuzzy" }
|
||||
git = { path = "../git" }
|
||||
gpui = { path = "../gpui" }
|
||||
indoc = "1.0.4"
|
||||
itertools = "0.10"
|
||||
language.workspace = true
|
||||
language = { path = "../language" }
|
||||
lazy_static.workspace = true
|
||||
linkify = "0.10.0"
|
||||
log.workspace = true
|
||||
lsp.workspace = true
|
||||
multi_buffer.workspace = true
|
||||
lsp = { path = "../lsp" }
|
||||
multi_buffer = { path = "../multi_buffer" }
|
||||
ordered-float.workspace = true
|
||||
parking_lot.workspace = true
|
||||
postage.workspace = true
|
||||
project.workspace = true
|
||||
project = { path = "../project" }
|
||||
rand.workspace = true
|
||||
rich_text.workspace = true
|
||||
rpc.workspace = true
|
||||
rich_text = { path = "../rich_text" }
|
||||
rpc = { path = "../rpc" }
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smallvec.workspace = true
|
||||
smol.workspace = true
|
||||
snippet.workspace = true
|
||||
sqlez.workspace = true
|
||||
sum_tree.workspace = true
|
||||
text.workspace = true
|
||||
theme.workspace = true
|
||||
snippet = { path = "../snippet" }
|
||||
sqlez = { path = "../sqlez" }
|
||||
sum_tree = { path = "../sum_tree" }
|
||||
text = { path = "../text" }
|
||||
theme = { path = "../theme" }
|
||||
tree-sitter-html = { workspace = true, optional = true }
|
||||
tree-sitter-rust = { workspace = true, optional = true }
|
||||
tree-sitter-typescript = { workspace = true, optional = true }
|
||||
ui.workspace = true
|
||||
ui = { path = "../ui" }
|
||||
url.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace" }
|
||||
|
||||
[dev-dependencies]
|
||||
copilot = { workspace = true, features = ["test-support"] }
|
||||
copilot = { path = "../copilot", features = ["test-support"] }
|
||||
ctor.workspace = true
|
||||
env_logger.workspace = true
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
lsp = { workspace = true, features = ["test-support"] }
|
||||
multi_buffer = { workspace = true, features = ["test-support"] }
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
release_channel.workspace = true
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
lsp = { path = "../lsp", features = ["test-support"] }
|
||||
multi_buffer = { path = "../multi_buffer", features = ["test-support"] }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
release_channel = { path = "../release_channel" }
|
||||
rand.workspace = true
|
||||
settings = { workspace = true, features = ["test-support"] }
|
||||
text = { workspace = true, features = ["test-support"] }
|
||||
settings = { path = "../settings", features = ["test-support"] }
|
||||
text = { path = "../text", features = ["test-support"] }
|
||||
tree-sitter-html.workspace = true
|
||||
tree-sitter-rust.workspace = true
|
||||
tree-sitter-typescript.workspace = true
|
||||
tree-sitter.workspace = true
|
||||
unindent.workspace = true
|
||||
util = { workspace = true, features = ["test-support"] }
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
@@ -70,30 +70,6 @@ pub struct FoldAt {
|
||||
pub struct UnfoldAt {
|
||||
pub buffer_row: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
pub struct MoveUpByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
pub struct MoveDownByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
pub struct SelectUpByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
pub struct SelectDownByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
impl_actions!(
|
||||
editor,
|
||||
[
|
||||
@@ -108,11 +84,7 @@ impl_actions!(
|
||||
ConfirmCodeAction,
|
||||
ToggleComments,
|
||||
FoldAt,
|
||||
UnfoldAt,
|
||||
MoveUpByLines,
|
||||
MoveDownByLines,
|
||||
SelectUpByLines,
|
||||
SelectDownByLines
|
||||
UnfoldAt
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ mod wrap_map;
|
||||
|
||||
use crate::EditorStyle;
|
||||
use crate::{
|
||||
hover_links::InlayHighlight, movement::TextLayoutDetails, Anchor, AnchorRangeExt, InlayId,
|
||||
MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint,
|
||||
link_go_to_definition::InlayHighlight, movement::TextLayoutDetails, Anchor, AnchorRangeExt,
|
||||
InlayId, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint,
|
||||
};
|
||||
pub use block_map::{BlockMap, BlockPoint};
|
||||
use collections::{BTreeMap, HashMap, HashSet};
|
||||
@@ -586,9 +586,8 @@ impl DisplaySnapshot {
|
||||
text_system,
|
||||
editor_style,
|
||||
rem_size,
|
||||
scroll_anchor: _,
|
||||
anchor: _,
|
||||
visible_rows: _,
|
||||
vertical_scroll_margin: _,
|
||||
}: &TextLayoutDetails,
|
||||
) -> Arc<LineLayout> {
|
||||
let mut runs = Vec::new();
|
||||
|
||||
@@ -1168,7 +1168,7 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
display_map::{InlayHighlights, TextHighlights},
|
||||
hover_links::InlayHighlight,
|
||||
link_go_to_definition::InlayHighlight,
|
||||
InlayId, MultiBuffer,
|
||||
};
|
||||
use gpui::AppContext;
|
||||
|
||||
@@ -22,9 +22,9 @@ mod inlay_hint_cache;
|
||||
mod debounced_delay;
|
||||
mod git;
|
||||
mod highlight_matching_bracket;
|
||||
mod hover_links;
|
||||
mod hover_popover;
|
||||
pub mod items;
|
||||
mod link_go_to_definition;
|
||||
mod mouse_context_menu;
|
||||
pub mod movement;
|
||||
mod persistence;
|
||||
@@ -61,8 +61,8 @@ use gpui::{
|
||||
DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView, FontId, FontStyle,
|
||||
FontWeight, HighlightStyle, Hsla, InteractiveText, KeyContext, Model, MouseButton,
|
||||
ParentElement, Pixels, Render, SharedString, Styled, StyledText, Subscription, Task, TextStyle,
|
||||
UnderlineStyle, UniformListScrollHandle, View, ViewContext, ViewInputHandler, VisualContext,
|
||||
WeakView, WhiteSpace, WindowContext,
|
||||
UniformListScrollHandle, View, ViewContext, ViewInputHandler, VisualContext, WeakView,
|
||||
WhiteSpace, WindowContext,
|
||||
};
|
||||
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
||||
use hover_popover::{hide_hover, HoverState};
|
||||
@@ -77,7 +77,7 @@ use language::{
|
||||
Language, OffsetRangeExt, Point, Selection, SelectionGoal, TransactionId,
|
||||
};
|
||||
|
||||
use hover_links::{HoverLink, HoveredLinkState, InlayHighlight};
|
||||
use link_go_to_definition::{GoToDefinitionLink, InlayHighlight, LinkGoToDefinitionState};
|
||||
use lsp::{DiagnosticSeverity, LanguageServerId};
|
||||
use mouse_context_menu::MouseContextMenu;
|
||||
use movement::TextLayoutDetails;
|
||||
@@ -120,7 +120,6 @@ use ui::{
|
||||
Tooltip,
|
||||
};
|
||||
use util::{maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
|
||||
use workspace::Toast;
|
||||
use workspace::{searchable::SearchEvent, ItemNavHistory, Pane, SplitDirection, ViewId, Workspace};
|
||||
|
||||
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
||||
@@ -375,7 +374,6 @@ pub struct Editor {
|
||||
hovered_cursors: HashMap<HoveredCursor, Task<()>>,
|
||||
pub show_local_selections: bool,
|
||||
mode: EditorMode,
|
||||
show_breadcrumbs: bool,
|
||||
show_gutter: bool,
|
||||
show_wrap_guides: Option<bool>,
|
||||
placeholder_text: Option<Arc<str>>,
|
||||
@@ -404,7 +402,7 @@ pub struct Editor {
|
||||
remote_id: Option<ViewId>,
|
||||
hover_state: HoverState,
|
||||
gutter_hovered: bool,
|
||||
hovered_link_state: Option<HoveredLinkState>,
|
||||
link_go_to_definition_state: LinkGoToDefinitionState,
|
||||
copilot_state: CopilotState,
|
||||
inlay_hint_cache: InlayHintCache,
|
||||
next_inlay_id: usize,
|
||||
@@ -415,12 +413,6 @@ pub struct Editor {
|
||||
editor_actions: Vec<Box<dyn Fn(&mut ViewContext<Self>)>>,
|
||||
show_copilot_suggestions: bool,
|
||||
use_autoclose: bool,
|
||||
custom_context_menu: Option<
|
||||
Box<
|
||||
dyn 'static
|
||||
+ Fn(&mut Self, DisplayPoint, &mut ViewContext<Self>) -> Option<View<ui::ContextMenu>>,
|
||||
>,
|
||||
>,
|
||||
}
|
||||
|
||||
pub struct EditorSnapshot {
|
||||
@@ -853,21 +845,15 @@ impl CompletionsMenu {
|
||||
let selected_item = self.selected_item;
|
||||
let style = style.clone();
|
||||
|
||||
let multiline_docs = if show_completion_documentation {
|
||||
let multiline_docs = {
|
||||
let mat = &self.matches[selected_item];
|
||||
let multiline_docs = match &self.completions.read()[mat.candidate_id].documentation {
|
||||
Some(Documentation::MultiLinePlainText(text)) => {
|
||||
Some(div().child(SharedString::from(text.clone())))
|
||||
}
|
||||
Some(Documentation::MultiLineMarkdown(parsed)) if !parsed.text.is_empty() => {
|
||||
Some(div().child(render_parsed_markdown(
|
||||
"completions_markdown",
|
||||
parsed,
|
||||
&style,
|
||||
workspace,
|
||||
cx,
|
||||
)))
|
||||
}
|
||||
Some(Documentation::MultiLineMarkdown(parsed)) => Some(div().child(
|
||||
render_parsed_markdown("completions_markdown", parsed, &style, workspace, cx),
|
||||
)),
|
||||
_ => None,
|
||||
};
|
||||
multiline_docs.map(|div| {
|
||||
@@ -884,8 +870,6 @@ impl CompletionsMenu {
|
||||
// because that would move the cursor.
|
||||
.on_mouse_down(MouseButton::Left, |_, cx| cx.stop_propagation())
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let list = uniform_list(
|
||||
@@ -1434,7 +1418,7 @@ impl Editor {
|
||||
buffer: buffer.clone(),
|
||||
display_map: display_map.clone(),
|
||||
selections,
|
||||
scroll_manager: ScrollManager::new(cx),
|
||||
scroll_manager: ScrollManager::new(),
|
||||
columnar_selection_tail: None,
|
||||
add_selections_state: None,
|
||||
select_next_state: None,
|
||||
@@ -1452,7 +1436,6 @@ impl Editor {
|
||||
blink_manager: blink_manager.clone(),
|
||||
show_local_selections: true,
|
||||
mode,
|
||||
show_breadcrumbs: EditorSettings::get_global(cx).toolbar.breadcrumbs,
|
||||
show_gutter: mode == EditorMode::Full,
|
||||
show_wrap_guides: None,
|
||||
placeholder_text: None,
|
||||
@@ -1482,7 +1465,7 @@ impl Editor {
|
||||
leader_peer_id: None,
|
||||
remote_id: None,
|
||||
hover_state: Default::default(),
|
||||
hovered_link_state: Default::default(),
|
||||
link_go_to_definition_state: Default::default(),
|
||||
copilot_state: Default::default(),
|
||||
inlay_hint_cache: InlayHintCache::new(inlay_hint_settings),
|
||||
gutter_hovered: false,
|
||||
@@ -1493,7 +1476,6 @@ impl Editor {
|
||||
hovered_cursors: Default::default(),
|
||||
editor_actions: Default::default(),
|
||||
show_copilot_suggestions: mode == EditorMode::Full,
|
||||
custom_context_menu: None,
|
||||
_subscriptions: vec![
|
||||
cx.observe(&buffer, Self::on_buffer_changed),
|
||||
cx.subscribe(&buffer, Self::on_buffer_event),
|
||||
@@ -1683,14 +1665,6 @@ impl Editor {
|
||||
self.collaboration_hub = Some(hub);
|
||||
}
|
||||
|
||||
pub fn set_custom_context_menu(
|
||||
&mut self,
|
||||
f: impl 'static
|
||||
+ Fn(&mut Self, DisplayPoint, &mut ViewContext<Self>) -> Option<View<ui::ContextMenu>>,
|
||||
) {
|
||||
self.custom_context_menu = Some(Box::new(f))
|
||||
}
|
||||
|
||||
pub fn set_completion_provider(&mut self, hub: Box<dyn CompletionProvider>) {
|
||||
self.completion_provider = Some(hub);
|
||||
}
|
||||
@@ -3091,9 +3065,8 @@ impl Editor {
|
||||
text_system: cx.text_system().clone(),
|
||||
editor_style: self.style.clone().unwrap(),
|
||||
rem_size: cx.rem_size(),
|
||||
scroll_anchor: self.scroll_manager.anchor(),
|
||||
anchor: self.scroll_manager.anchor().anchor,
|
||||
visible_rows: self.visible_line_count(),
|
||||
vertical_scroll_margin: self.scroll_manager.vertical_scroll_margin,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5385,86 +5358,6 @@ impl Editor {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn move_up_by_lines(&mut self, action: &MoveUpByLines, cx: &mut ViewContext<Self>) {
|
||||
if self.take_rename(true, cx).is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
||||
let text_layout_details = &self.text_layout_details(cx);
|
||||
|
||||
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
let line_mode = s.line_mode;
|
||||
s.move_with(|map, selection| {
|
||||
if !selection.is_empty() && !line_mode {
|
||||
selection.goal = SelectionGoal::None;
|
||||
}
|
||||
let (cursor, goal) = movement::up_by_rows(
|
||||
map,
|
||||
selection.start,
|
||||
action.lines,
|
||||
selection.goal,
|
||||
false,
|
||||
&text_layout_details,
|
||||
);
|
||||
selection.collapse_to(cursor, goal);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
pub fn move_down_by_lines(&mut self, action: &MoveDownByLines, cx: &mut ViewContext<Self>) {
|
||||
if self.take_rename(true, cx).is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
||||
let text_layout_details = &self.text_layout_details(cx);
|
||||
|
||||
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
let line_mode = s.line_mode;
|
||||
s.move_with(|map, selection| {
|
||||
if !selection.is_empty() && !line_mode {
|
||||
selection.goal = SelectionGoal::None;
|
||||
}
|
||||
let (cursor, goal) = movement::down_by_rows(
|
||||
map,
|
||||
selection.start,
|
||||
action.lines,
|
||||
selection.goal,
|
||||
false,
|
||||
&text_layout_details,
|
||||
);
|
||||
selection.collapse_to(cursor, goal);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
pub fn select_down_by_lines(&mut self, action: &SelectDownByLines, cx: &mut ViewContext<Self>) {
|
||||
let text_layout_details = &self.text_layout_details(cx);
|
||||
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.move_heads_with(|map, head, goal| {
|
||||
movement::down_by_rows(map, head, action.lines, goal, false, &text_layout_details)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn select_up_by_lines(&mut self, action: &SelectUpByLines, cx: &mut ViewContext<Self>) {
|
||||
let text_layout_details = &self.text_layout_details(cx);
|
||||
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.move_heads_with(|map, head, goal| {
|
||||
movement::up_by_rows(map, head, action.lines, goal, false, &text_layout_details)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn move_page_up(&mut self, action: &MovePageUp, cx: &mut ViewContext<Self>) {
|
||||
if self.take_rename(true, cx).is_some() {
|
||||
return;
|
||||
@@ -7248,8 +7141,11 @@ impl Editor {
|
||||
cx.spawn(|editor, mut cx| async move {
|
||||
let definitions = definitions.await?;
|
||||
editor.update(&mut cx, |editor, cx| {
|
||||
editor.navigate_to_hover_links(
|
||||
definitions.into_iter().map(HoverLink::Text).collect(),
|
||||
editor.navigate_to_definitions(
|
||||
definitions
|
||||
.into_iter()
|
||||
.map(GoToDefinitionLink::Text)
|
||||
.collect(),
|
||||
split,
|
||||
cx,
|
||||
);
|
||||
@@ -7259,34 +7155,29 @@ impl Editor {
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
pub fn navigate_to_hover_links(
|
||||
pub fn navigate_to_definitions(
|
||||
&mut self,
|
||||
mut definitions: Vec<HoverLink>,
|
||||
mut definitions: Vec<GoToDefinitionLink>,
|
||||
split: bool,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
let Some(workspace) = self.workspace() else {
|
||||
return;
|
||||
};
|
||||
let pane = workspace.read(cx).active_pane().clone();
|
||||
// If there is one definition, just open it directly
|
||||
if definitions.len() == 1 {
|
||||
let definition = definitions.pop().unwrap();
|
||||
let target_task = match definition {
|
||||
HoverLink::Text(link) => Task::Ready(Some(Ok(Some(link.target)))),
|
||||
HoverLink::InlayHint(lsp_location, server_id) => {
|
||||
GoToDefinitionLink::Text(link) => Task::Ready(Some(Ok(Some(link.target)))),
|
||||
GoToDefinitionLink::InlayHint(lsp_location, server_id) => {
|
||||
self.compute_target_location(lsp_location, server_id, cx)
|
||||
}
|
||||
HoverLink::Url(url) => {
|
||||
cx.open_url(&url);
|
||||
Task::ready(Ok(None))
|
||||
}
|
||||
};
|
||||
cx.spawn(|editor, mut cx| async move {
|
||||
let target = target_task.await.context("target resolution task")?;
|
||||
if let Some(target) = target {
|
||||
editor.update(&mut cx, |editor, cx| {
|
||||
let Some(workspace) = editor.workspace() else {
|
||||
return;
|
||||
};
|
||||
let pane = workspace.read(cx).active_pane().clone();
|
||||
|
||||
let range = target.range.to_offset(target.buffer.read(cx));
|
||||
let range = editor.range_for_match(&range);
|
||||
if Some(&target.buffer) == editor.buffer.read(cx).as_singleton().as_ref() {
|
||||
@@ -7327,35 +7218,37 @@ impl Editor {
|
||||
} else if !definitions.is_empty() {
|
||||
let replica_id = self.replica_id(cx);
|
||||
cx.spawn(|editor, mut cx| async move {
|
||||
let (title, location_tasks, workspace) = editor
|
||||
let (title, location_tasks) = editor
|
||||
.update(&mut cx, |editor, cx| {
|
||||
let title = definitions
|
||||
.iter()
|
||||
.find_map(|definition| match definition {
|
||||
HoverLink::Text(link) => link.origin.as_ref().map(|origin| {
|
||||
let buffer = origin.buffer.read(cx);
|
||||
format!(
|
||||
"Definitions for {}",
|
||||
buffer
|
||||
.text_for_range(origin.range.clone())
|
||||
.collect::<String>()
|
||||
)
|
||||
}),
|
||||
HoverLink::InlayHint(_, _) => None,
|
||||
HoverLink::Url(_) => None,
|
||||
GoToDefinitionLink::Text(link) => {
|
||||
link.origin.as_ref().map(|origin| {
|
||||
let buffer = origin.buffer.read(cx);
|
||||
format!(
|
||||
"Definitions for {}",
|
||||
buffer
|
||||
.text_for_range(origin.range.clone())
|
||||
.collect::<String>()
|
||||
)
|
||||
})
|
||||
}
|
||||
GoToDefinitionLink::InlayHint(_, _) => None,
|
||||
})
|
||||
.unwrap_or("Definitions".to_string());
|
||||
let location_tasks = definitions
|
||||
.into_iter()
|
||||
.map(|definition| match definition {
|
||||
HoverLink::Text(link) => Task::Ready(Some(Ok(Some(link.target)))),
|
||||
HoverLink::InlayHint(lsp_location, server_id) => {
|
||||
GoToDefinitionLink::Text(link) => {
|
||||
Task::Ready(Some(Ok(Some(link.target))))
|
||||
}
|
||||
GoToDefinitionLink::InlayHint(lsp_location, server_id) => {
|
||||
editor.compute_target_location(lsp_location, server_id, cx)
|
||||
}
|
||||
HoverLink::Url(_) => Task::ready(Ok(None)),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
(title, location_tasks, editor.workspace().clone())
|
||||
(title, location_tasks)
|
||||
})
|
||||
.context("location tasks preparation")?;
|
||||
|
||||
@@ -7365,10 +7258,6 @@ impl Editor {
|
||||
.filter_map(|location| location.transpose())
|
||||
.collect::<Result<_>>()
|
||||
.context("location tasks")?;
|
||||
|
||||
let Some(workspace) = workspace else {
|
||||
return Ok(());
|
||||
};
|
||||
workspace
|
||||
.update(&mut cx, |workspace, cx| {
|
||||
Self::open_locations_in_multibuffer(
|
||||
@@ -7907,7 +7796,7 @@ impl Editor {
|
||||
.insert_blocks(
|
||||
diagnostic_group.iter().map(|entry| {
|
||||
let diagnostic = entry.diagnostic.clone();
|
||||
let message_height = diagnostic.message.matches('\n').count() as u8 + 1;
|
||||
let message_height = diagnostic.message.lines().count() as u8;
|
||||
BlockProperties {
|
||||
style: BlockStyle::Fixed,
|
||||
position: buffer.anchor_after(entry.range.start),
|
||||
@@ -8355,37 +8244,21 @@ impl Editor {
|
||||
use git::permalink::{build_permalink, BuildPermalinkParams};
|
||||
|
||||
let permalink = maybe!({
|
||||
let project = self.project.clone().ok_or_else(|| anyhow!("no project"))?;
|
||||
let project = self.project.clone()?;
|
||||
let project = project.read(cx);
|
||||
|
||||
let worktree = project
|
||||
.visible_worktrees(cx)
|
||||
.next()
|
||||
.ok_or_else(|| anyhow!("no worktree"))?;
|
||||
let worktree = project.visible_worktrees(cx).next()?;
|
||||
|
||||
let mut cwd = worktree.read(cx).abs_path().to_path_buf();
|
||||
cwd.push(".git");
|
||||
|
||||
const REMOTE_NAME: &'static str = "origin";
|
||||
let repo = project
|
||||
.fs()
|
||||
.open_repo(&cwd)
|
||||
.ok_or_else(|| anyhow!("no Git repo"))?;
|
||||
let origin_url = repo
|
||||
.lock()
|
||||
.remote_url(REMOTE_NAME)
|
||||
.ok_or_else(|| anyhow!("remote \"{REMOTE_NAME}\" not found"))?;
|
||||
let sha = repo
|
||||
.lock()
|
||||
.head_sha()
|
||||
.ok_or_else(|| anyhow!("failed to read HEAD SHA"))?;
|
||||
let repo = project.fs().open_repo(&cwd)?;
|
||||
let origin_url = repo.lock().remote_url("origin")?;
|
||||
let sha = repo.lock().head_sha()?;
|
||||
|
||||
let path = maybe!({
|
||||
let buffer = self.buffer().read(cx).as_singleton()?;
|
||||
let file = buffer.read(cx).file().and_then(|f| f.as_local())?;
|
||||
file.path().to_str().map(|path| path.to_string())
|
||||
})
|
||||
.ok_or_else(|| anyhow!("failed to determine file path"))?;
|
||||
let buffer = self.buffer().read(cx).as_singleton()?;
|
||||
let file = buffer.read(cx).file().and_then(|f| f.as_local())?;
|
||||
let path = file.path().to_str().map(|path| path.to_string())?;
|
||||
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selection = selections.iter().peekable().next();
|
||||
@@ -8396,23 +8269,11 @@ impl Editor {
|
||||
path: &path,
|
||||
selection: selection.map(|selection| selection.range()),
|
||||
})
|
||||
.log_err()
|
||||
});
|
||||
|
||||
match permalink {
|
||||
Ok(permalink) => {
|
||||
cx.write_to_clipboard(ClipboardItem::new(permalink.to_string()));
|
||||
}
|
||||
Err(err) => {
|
||||
let message = format!("Failed to copy permalink: {err}");
|
||||
|
||||
Err::<(), anyhow::Error>(err).log_err();
|
||||
|
||||
if let Some(workspace) = self.workspace() {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.show_toast(Toast::new(0x156a5f9ee, message), cx)
|
||||
})
|
||||
}
|
||||
}
|
||||
if let Some(permalink) = permalink {
|
||||
cx.write_to_clipboard(ClipboardItem::new(permalink.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8800,9 +8661,6 @@ impl Editor {
|
||||
)),
|
||||
cx,
|
||||
);
|
||||
let editor_settings = EditorSettings::get_global(cx);
|
||||
self.scroll_manager.vertical_scroll_margin = editor_settings.vertical_scroll_margin;
|
||||
self.show_breadcrumbs = editor_settings.toolbar.breadcrumbs;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
@@ -9495,7 +9353,6 @@ impl Render for Editor {
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
},
|
||||
|
||||
@@ -9509,7 +9366,6 @@ impl Render for Editor {
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
},
|
||||
};
|
||||
@@ -9716,14 +9572,7 @@ impl ViewInputHandler for Editor {
|
||||
} else {
|
||||
this.highlight_text::<InputComposition>(
|
||||
marked_ranges.clone(),
|
||||
HighlightStyle {
|
||||
underline: Some(UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: None,
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
HighlightStyle::default(), // todo!() this.style(cx).composition_mark,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,7 @@ pub struct EditorSettings {
|
||||
pub show_completion_documentation: bool,
|
||||
pub completion_documentation_secondary_query_debounce: u64,
|
||||
pub use_on_type_format: bool,
|
||||
pub toolbar: Toolbar,
|
||||
pub scrollbar: Scrollbar,
|
||||
pub vertical_scroll_margin: f32,
|
||||
pub relative_line_numbers: bool,
|
||||
pub seed_search_query_from_cursor: SeedQuerySetting,
|
||||
pub redact_private_values: bool,
|
||||
@@ -30,19 +28,12 @@ pub enum SeedQuerySetting {
|
||||
Never,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
pub struct Toolbar {
|
||||
pub breadcrumbs: bool,
|
||||
pub quick_actions: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
pub struct Scrollbar {
|
||||
pub show: ShowScrollbar,
|
||||
pub git_diff: bool,
|
||||
pub selections: bool,
|
||||
pub symbols_selections: bool,
|
||||
pub diagnostics: bool,
|
||||
}
|
||||
|
||||
/// When to show the scrollbar in the editor.
|
||||
@@ -93,15 +84,8 @@ pub struct EditorSettingsContent {
|
||||
///
|
||||
/// Default: true
|
||||
pub use_on_type_format: Option<bool>,
|
||||
/// Toolbar related settings
|
||||
pub toolbar: Option<ToolbarContent>,
|
||||
/// Scrollbar related settings
|
||||
pub scrollbar: Option<ScrollbarContent>,
|
||||
|
||||
/// The number of lines to keep above/below the cursor when auto-scrolling.
|
||||
///
|
||||
/// Default: 3.
|
||||
pub vertical_scroll_margin: Option<f32>,
|
||||
/// Whether the line numbers on editors gutter are relative or not.
|
||||
///
|
||||
/// Default: false
|
||||
@@ -119,19 +103,6 @@ pub struct EditorSettingsContent {
|
||||
pub redact_private_values: Option<bool>,
|
||||
}
|
||||
|
||||
// Toolbar related settings
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
pub struct ToolbarContent {
|
||||
/// Whether to display breadcrumbs in the editor toolbar.
|
||||
///
|
||||
/// Default: true
|
||||
pub breadcrumbs: Option<bool>,
|
||||
/// Whether to display quik action buttons in the editor toolbar.
|
||||
///
|
||||
/// Default: true
|
||||
pub quick_actions: Option<bool>,
|
||||
}
|
||||
|
||||
/// Scrollbar related settings
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
pub struct ScrollbarContent {
|
||||
@@ -151,10 +122,6 @@ pub struct ScrollbarContent {
|
||||
///
|
||||
/// Default: true
|
||||
pub symbols_selections: Option<bool>,
|
||||
/// Whether to show diagnostic indicators in the scrollbar.
|
||||
///
|
||||
/// Default: true
|
||||
pub diagnostics: Option<bool>,
|
||||
}
|
||||
|
||||
impl Settings for EditorSettings {
|
||||
|
||||
@@ -9,6 +9,11 @@ use crate::{
|
||||
self, hover_at, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT,
|
||||
},
|
||||
items::BufferSearchHighlights,
|
||||
link_go_to_definition::{
|
||||
go_to_fetched_definition, go_to_fetched_type_definition, show_link_definition,
|
||||
update_go_to_definition_link, update_inlay_link_and_hover_points, GoToDefinitionTrigger,
|
||||
LinkGoToDefinitionState,
|
||||
},
|
||||
mouse_context_menu,
|
||||
scroll::scroll_amount::ScrollAmount,
|
||||
CursorShape, DisplayPoint, DocumentHighlightRead, DocumentHighlightWrite, Editor, EditorMode,
|
||||
@@ -30,7 +35,6 @@ use gpui::{
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::language_settings::ShowWhitespaceSetting;
|
||||
use lsp::DiagnosticSeverity;
|
||||
use multi_buffer::Anchor;
|
||||
use project::{
|
||||
project_settings::{GitGutterSetting, ProjectSettings},
|
||||
@@ -142,11 +146,7 @@ impl EditorElement {
|
||||
register_action(view, cx, Editor::move_left);
|
||||
register_action(view, cx, Editor::move_right);
|
||||
register_action(view, cx, Editor::move_down);
|
||||
register_action(view, cx, Editor::move_down_by_lines);
|
||||
register_action(view, cx, Editor::select_down_by_lines);
|
||||
register_action(view, cx, Editor::move_up);
|
||||
register_action(view, cx, Editor::move_up_by_lines);
|
||||
register_action(view, cx, Editor::select_up_by_lines);
|
||||
register_action(view, cx, Editor::cancel);
|
||||
register_action(view, cx, Editor::newline);
|
||||
register_action(view, cx, Editor::newline_above);
|
||||
@@ -332,14 +332,7 @@ impl EditorElement {
|
||||
register_action(view, cx, Editor::display_cursor_names);
|
||||
}
|
||||
|
||||
fn register_key_listeners(
|
||||
&self,
|
||||
cx: &mut ElementContext,
|
||||
text_bounds: Bounds<Pixels>,
|
||||
layout: &LayoutState,
|
||||
) {
|
||||
let position_map = layout.position_map.clone();
|
||||
let stacking_order = cx.stacking_order().clone();
|
||||
fn register_key_listeners(&self, cx: &mut ElementContext) {
|
||||
cx.on_key_event({
|
||||
let editor = self.editor.clone();
|
||||
move |event: &ModifiersChangedEvent, phase, cx| {
|
||||
@@ -347,41 +340,46 @@ impl EditorElement {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.update(cx, |editor, cx| {
|
||||
Self::modifiers_changed(
|
||||
editor,
|
||||
event,
|
||||
&position_map,
|
||||
text_bounds,
|
||||
&stacking_order,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
if editor.update(cx, |editor, cx| Self::modifiers_changed(editor, event, cx)) {
|
||||
cx.stop_propagation();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn modifiers_changed(
|
||||
pub(crate) fn modifiers_changed(
|
||||
editor: &mut Editor,
|
||||
event: &ModifiersChangedEvent,
|
||||
position_map: &PositionMap,
|
||||
text_bounds: Bounds<Pixels>,
|
||||
stacking_order: &StackingOrder,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
let mouse_position = cx.mouse_position();
|
||||
if !text_bounds.contains(&mouse_position)
|
||||
|| !cx.was_top_layer(&mouse_position, stacking_order)
|
||||
{
|
||||
return;
|
||||
) -> bool {
|
||||
let pending_selection = editor.has_pending_selection();
|
||||
|
||||
if let Some(point) = &editor.link_go_to_definition_state.last_trigger_point {
|
||||
if event.command && !pending_selection {
|
||||
let point = point.clone();
|
||||
let snapshot = editor.snapshot(cx);
|
||||
let kind = point.definition_kind(event.shift);
|
||||
|
||||
show_link_definition(kind, editor, point, snapshot, cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
editor.update_hovered_link(
|
||||
position_map.point_for_position(text_bounds, mouse_position),
|
||||
&position_map.snapshot,
|
||||
event.modifiers,
|
||||
cx,
|
||||
)
|
||||
{
|
||||
if editor.link_go_to_definition_state.symbol_range.is_some()
|
||||
|| !editor.link_go_to_definition_state.definitions.is_empty()
|
||||
{
|
||||
editor.link_go_to_definition_state.symbol_range.take();
|
||||
editor.link_go_to_definition_state.definitions.clear();
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
editor.link_go_to_definition_state.task = None;
|
||||
|
||||
editor.clear_highlights::<LinkGoToDefinitionState>(cx);
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn mouse_left_down(
|
||||
@@ -482,7 +480,13 @@ impl EditorElement {
|
||||
&& cx.was_top_layer(&event.position, stacking_order)
|
||||
{
|
||||
let point = position_map.point_for_position(text_bounds, event.position);
|
||||
editor.handle_click_hovered_link(point, event.modifiers, cx);
|
||||
let could_be_inlay = point.as_valid().is_none();
|
||||
let split = event.modifiers.alt;
|
||||
if event.modifiers.shift || could_be_inlay {
|
||||
go_to_fetched_type_definition(editor, point, split, cx);
|
||||
} else {
|
||||
go_to_fetched_definition(editor, point, split, cx);
|
||||
}
|
||||
|
||||
cx.stop_propagation();
|
||||
} else if end_selection {
|
||||
@@ -555,14 +559,31 @@ impl EditorElement {
|
||||
if text_hovered && was_top {
|
||||
let point_for_position = position_map.point_for_position(text_bounds, event.position);
|
||||
|
||||
editor.update_hovered_link(point_for_position, &position_map.snapshot, modifiers, cx);
|
||||
|
||||
if let Some(point) = point_for_position.as_valid() {
|
||||
hover_at(editor, Some(point), cx);
|
||||
Self::update_visible_cursor(editor, point, position_map, cx);
|
||||
match point_for_position.as_valid() {
|
||||
Some(point) => {
|
||||
update_go_to_definition_link(
|
||||
editor,
|
||||
Some(GoToDefinitionTrigger::Text(point)),
|
||||
modifiers.command,
|
||||
modifiers.shift,
|
||||
cx,
|
||||
);
|
||||
hover_at(editor, Some(point), cx);
|
||||
Self::update_visible_cursor(editor, point, position_map, cx);
|
||||
}
|
||||
None => {
|
||||
update_inlay_link_and_hover_points(
|
||||
&position_map.snapshot,
|
||||
point_for_position,
|
||||
editor,
|
||||
modifiers.command,
|
||||
modifiers.shift,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
editor.hide_hovered_link(cx);
|
||||
update_go_to_definition_link(editor, None, modifiers.command, modifiers.shift, cx);
|
||||
hover_at(editor, None, cx);
|
||||
if gutter_hovered && was_top {
|
||||
cx.stop_propagation();
|
||||
@@ -904,13 +925,13 @@ impl EditorElement {
|
||||
if self
|
||||
.editor
|
||||
.read(cx)
|
||||
.hovered_link_state
|
||||
.as_ref()
|
||||
.is_some_and(|hovered_link_state| !hovered_link_state.links.is_empty())
|
||||
.link_go_to_definition_state
|
||||
.definitions
|
||||
.is_empty()
|
||||
{
|
||||
cx.set_cursor_style(CursorStyle::PointingHand);
|
||||
} else {
|
||||
cx.set_cursor_style(CursorStyle::IBeam);
|
||||
} else {
|
||||
cx.set_cursor_style(CursorStyle::PointingHand);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1073,7 +1094,6 @@ impl EditorElement {
|
||||
font: self.style.text.font(),
|
||||
color: self.style.background,
|
||||
background_color: None,
|
||||
strikethrough: None,
|
||||
underline: None,
|
||||
}],
|
||||
)
|
||||
@@ -1457,64 +1477,6 @@ impl EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
if layout.is_singleton && scrollbar_settings.diagnostics {
|
||||
let max_point = layout
|
||||
.position_map
|
||||
.snapshot
|
||||
.display_snapshot
|
||||
.buffer_snapshot
|
||||
.max_point();
|
||||
|
||||
let diagnostics = layout
|
||||
.position_map
|
||||
.snapshot
|
||||
.buffer_snapshot
|
||||
.diagnostics_in_range::<_, Point>(Point::zero()..max_point, false)
|
||||
// We want to sort by severity, in order to paint the most severe diagnostics last.
|
||||
.sorted_by_key(|diagnostic| std::cmp::Reverse(diagnostic.diagnostic.severity));
|
||||
|
||||
for diagnostic in diagnostics {
|
||||
let start_display = diagnostic
|
||||
.range
|
||||
.start
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||
let end_display = diagnostic
|
||||
.range
|
||||
.end
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||
let start_y = y_for_row(start_display.row() as f32);
|
||||
let mut end_y = if diagnostic.range.start == diagnostic.range.end {
|
||||
y_for_row((end_display.row() + 1) as f32)
|
||||
} else {
|
||||
y_for_row((end_display.row()) as f32)
|
||||
};
|
||||
|
||||
if end_y - start_y < px(1.) {
|
||||
end_y = start_y + px(1.);
|
||||
}
|
||||
let bounds = Bounds::from_corners(point(left, start_y), point(right, end_y));
|
||||
|
||||
let color = match diagnostic.diagnostic.severity {
|
||||
DiagnosticSeverity::ERROR => cx.theme().status().error,
|
||||
DiagnosticSeverity::WARNING => cx.theme().status().warning,
|
||||
DiagnosticSeverity::INFORMATION => cx.theme().status().info,
|
||||
_ => cx.theme().status().hint,
|
||||
};
|
||||
cx.paint_quad(quad(
|
||||
bounds,
|
||||
Corners::default(),
|
||||
color,
|
||||
Edges {
|
||||
top: Pixels::ZERO,
|
||||
right: px(1.),
|
||||
bottom: Pixels::ZERO,
|
||||
left: px(1.),
|
||||
},
|
||||
cx.theme().colors().scrollbar_thumb_border,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
cx.paint_quad(quad(
|
||||
thumb_bounds,
|
||||
Corners::default(),
|
||||
@@ -1714,7 +1676,6 @@ impl EditorElement {
|
||||
color: Hsla::default(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
}],
|
||||
)
|
||||
.unwrap();
|
||||
@@ -1851,7 +1812,6 @@ impl EditorElement {
|
||||
color,
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
};
|
||||
let shaped_line = cx
|
||||
.text_system()
|
||||
@@ -1909,7 +1869,6 @@ impl EditorElement {
|
||||
color: placeholder_color,
|
||||
background_color: None,
|
||||
underline: Default::default(),
|
||||
strikethrough: None,
|
||||
};
|
||||
cx.text_system()
|
||||
.shape_line(line.to_string().into(), font_size, &[run])
|
||||
@@ -2147,9 +2106,6 @@ impl EditorElement {
|
||||
// Symbols Selections
|
||||
(is_singleton && scrollbar_settings.symbols_selections && (editor.has_background_highlights::<DocumentHighlightRead>() || editor.has_background_highlights::<DocumentHighlightWrite>()))
|
||||
||
|
||||
// Diagnostics
|
||||
(is_singleton && scrollbar_settings.diagnostics && snapshot.buffer_snapshot.has_diagnostics())
|
||||
||
|
||||
// Scrollmanager
|
||||
editor.scroll_manager.scrollbars_visible()
|
||||
}
|
||||
@@ -2325,7 +2281,6 @@ impl EditorElement {
|
||||
color: cx.theme().colors().editor_invisible,
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
}],
|
||||
)
|
||||
.unwrap();
|
||||
@@ -2340,7 +2295,6 @@ impl EditorElement {
|
||||
color: cx.theme().colors().editor_invisible,
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
}],
|
||||
)
|
||||
.unwrap();
|
||||
@@ -2874,7 +2828,6 @@ impl LineWithInvisibles {
|
||||
color: text_style.color,
|
||||
background_color: text_style.background_color,
|
||||
underline: text_style.underline,
|
||||
strikethrough: text_style.strikethrough,
|
||||
});
|
||||
|
||||
if editor_mode == EditorMode::Full {
|
||||
@@ -3086,9 +3039,9 @@ impl Element for EditorElement {
|
||||
let key_context = self.editor.read(cx).key_context(cx);
|
||||
cx.with_key_dispatch(Some(key_context), Some(focus_handle.clone()), |_, cx| {
|
||||
self.register_actions(cx);
|
||||
self.register_key_listeners(cx);
|
||||
|
||||
cx.with_content_mask(Some(ContentMask { bounds }), |cx| {
|
||||
self.register_key_listeners(cx, text_bounds, &layout);
|
||||
cx.handle_input(
|
||||
&focus_handle,
|
||||
ElementInputHandler::new(bounds, self.editor.clone()),
|
||||
@@ -3205,6 +3158,16 @@ pub struct PointForPosition {
|
||||
}
|
||||
|
||||
impl PointForPosition {
|
||||
#[cfg(test)]
|
||||
pub fn valid(valid: DisplayPoint) -> Self {
|
||||
Self {
|
||||
previous_valid: valid,
|
||||
next_valid: valid,
|
||||
exact_unclipped: valid,
|
||||
column_overshoot_after_line_end: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_valid(&self) -> Option<DisplayPoint> {
|
||||
if self.previous_valid == self.exact_unclipped && self.next_valid == self.exact_unclipped {
|
||||
Some(self.previous_valid)
|
||||
@@ -3288,7 +3251,6 @@ fn layout_line(
|
||||
color: Hsla::default(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
}],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
display_map::{InlayOffset, ToDisplayPoint},
|
||||
hover_links::{InlayHighlight, RangeInEditor},
|
||||
link_go_to_definition::{InlayHighlight, RangeInEditor},
|
||||
Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSettings, EditorSnapshot, EditorStyle,
|
||||
ExcerptId, Hover, RangeToAnchorExt,
|
||||
};
|
||||
@@ -605,8 +605,8 @@ mod tests {
|
||||
use crate::{
|
||||
editor_tests::init_test,
|
||||
element::PointForPosition,
|
||||
hover_links::update_inlay_link_and_hover_points,
|
||||
inlay_hint_cache::tests::{cached_hint_labels, visible_hint_labels},
|
||||
link_go_to_definition::update_inlay_link_and_hover_points,
|
||||
test::editor_lsp_test_context::EditorLspTestContext,
|
||||
InlayId,
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
editor_settings::SeedQuerySetting, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll,
|
||||
Editor, EditorEvent, EditorSettings, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot,
|
||||
NavigationData, ToPoint as _,
|
||||
editor_settings::SeedQuerySetting, link_go_to_definition::hide_link_definition,
|
||||
persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, EditorEvent, EditorSettings,
|
||||
ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _,
|
||||
};
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use collections::HashSet;
|
||||
@@ -682,7 +682,8 @@ impl Item for Editor {
|
||||
}
|
||||
|
||||
fn workspace_deactivated(&mut self, cx: &mut ViewContext<Self>) {
|
||||
self.hide_hovered_link(cx);
|
||||
hide_link_definition(self, cx);
|
||||
self.link_go_to_definition_state.last_trigger_point = None;
|
||||
}
|
||||
|
||||
fn is_dirty(&self, cx: &AppContext) -> bool {
|
||||
@@ -800,11 +801,7 @@ impl Item for Editor {
|
||||
}
|
||||
|
||||
fn breadcrumb_location(&self) -> ToolbarItemLocation {
|
||||
if self.show_breadcrumbs {
|
||||
ToolbarItemLocation::PrimaryLeft
|
||||
} else {
|
||||
ToolbarItemLocation::Hidden
|
||||
}
|
||||
ToolbarItemLocation::PrimaryLeft
|
||||
}
|
||||
|
||||
fn breadcrumbs(&self, variant: &Theme, cx: &AppContext) -> Option<Vec<BreadcrumbText>> {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,40 +25,31 @@ pub fn deploy_context_menu(
|
||||
return;
|
||||
}
|
||||
|
||||
let context_menu = if let Some(custom) = editor.custom_context_menu.take() {
|
||||
let menu = custom(editor, point, cx);
|
||||
editor.custom_context_menu = Some(custom);
|
||||
if menu.is_none() {
|
||||
return;
|
||||
}
|
||||
menu.unwrap()
|
||||
} else {
|
||||
// Don't show the context menu if there isn't a project associated with this editor
|
||||
if editor.project.is_none() {
|
||||
return;
|
||||
}
|
||||
// Don't show the context menu if there isn't a project associated with this editor
|
||||
if editor.project.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move the cursor to the clicked location so that dispatched actions make sense
|
||||
editor.change_selections(None, cx, |s| {
|
||||
s.clear_disjoint();
|
||||
s.set_pending_display_range(point..point, SelectMode::Character);
|
||||
});
|
||||
// Move the cursor to the clicked location so that dispatched actions make sense
|
||||
editor.change_selections(None, cx, |s| {
|
||||
s.clear_disjoint();
|
||||
s.set_pending_display_range(point..point, SelectMode::Character);
|
||||
});
|
||||
|
||||
ui::ContextMenu::build(cx, |menu, _cx| {
|
||||
menu.action("Rename Symbol", Box::new(Rename))
|
||||
.action("Go to Definition", Box::new(GoToDefinition))
|
||||
.action("Go to Type Definition", Box::new(GoToTypeDefinition))
|
||||
.action("Find All References", Box::new(FindAllReferences))
|
||||
.action(
|
||||
"Code Actions",
|
||||
Box::new(ToggleCodeActions {
|
||||
deployed_from_indicator: false,
|
||||
}),
|
||||
)
|
||||
.separator()
|
||||
.action("Reveal in Finder", Box::new(RevealInFinder))
|
||||
})
|
||||
};
|
||||
let context_menu = ui::ContextMenu::build(cx, |menu, _cx| {
|
||||
menu.action("Rename Symbol", Box::new(Rename))
|
||||
.action("Go to Definition", Box::new(GoToDefinition))
|
||||
.action("Go to Type Definition", Box::new(GoToTypeDefinition))
|
||||
.action("Find All References", Box::new(FindAllReferences))
|
||||
.action(
|
||||
"Code Actions",
|
||||
Box::new(ToggleCodeActions {
|
||||
deployed_from_indicator: false,
|
||||
}),
|
||||
)
|
||||
.separator()
|
||||
.action("Reveal in Finder", Box::new(RevealInFinder))
|
||||
});
|
||||
let context_menu_focus = context_menu.focus_handle(cx);
|
||||
cx.focus(&context_menu_focus);
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
//! in editor given a given motion (e.g. it handles converting a "move left" command into coordinates in editor). It is exposed mostly for use by vim crate.
|
||||
|
||||
use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint};
|
||||
use crate::{char_kind, scroll::ScrollAnchor, CharKind, EditorStyle, ToOffset, ToPoint};
|
||||
use gpui::{px, Pixels, WindowTextSystem};
|
||||
use crate::{char_kind, CharKind, EditorStyle, ToOffset, ToPoint};
|
||||
use gpui::{px, Pixels, TextSystem};
|
||||
use language::Point;
|
||||
|
||||
use std::{ops::Range, sync::Arc};
|
||||
|
||||
use multi_buffer::Anchor;
|
||||
|
||||
/// Defines search strategy for items in `movement` module.
|
||||
/// `FindRange::SingeLine` only looks for a match on a single line at a time, whereas
|
||||
/// `FindRange::MultiLine` keeps going until the end of a string.
|
||||
@@ -20,12 +22,11 @@ pub enum FindRange {
|
||||
/// TextLayoutDetails encompasses everything we need to move vertically
|
||||
/// taking into account variable width characters.
|
||||
pub struct TextLayoutDetails {
|
||||
pub(crate) text_system: Arc<WindowTextSystem>,
|
||||
pub(crate) text_system: Arc<TextSystem>,
|
||||
pub(crate) editor_style: EditorStyle,
|
||||
pub(crate) rem_size: Pixels,
|
||||
pub scroll_anchor: ScrollAnchor,
|
||||
pub anchor: Anchor,
|
||||
pub visible_rows: Option<f32>,
|
||||
pub vertical_scroll_margin: f32,
|
||||
}
|
||||
|
||||
/// Returns a column to the left of the current point, wrapping
|
||||
@@ -395,17 +396,14 @@ pub fn find_preceding_boundary(
|
||||
/// Scans for a boundary following the given start point until a boundary is found, indicated by the
|
||||
/// given predicate returning true. The predicate is called with the character to the left and right
|
||||
/// of the candidate boundary location, and will be called with `\n` characters indicating the start
|
||||
/// or end of a line. The function supports optionally returning the point just before the boundary
|
||||
/// is found via return_point_before_boundary.
|
||||
pub fn find_boundary_point(
|
||||
/// or end of a line.
|
||||
pub fn find_boundary(
|
||||
map: &DisplaySnapshot,
|
||||
from: DisplayPoint,
|
||||
find_range: FindRange,
|
||||
mut is_boundary: impl FnMut(char, char) -> bool,
|
||||
return_point_before_boundary: bool,
|
||||
) -> DisplayPoint {
|
||||
let mut offset = from.to_offset(&map, Bias::Right);
|
||||
let mut prev_offset = offset;
|
||||
let mut prev_ch = None;
|
||||
|
||||
for ch in map.buffer_snapshot.chars_at(offset) {
|
||||
@@ -414,38 +412,16 @@ pub fn find_boundary_point(
|
||||
}
|
||||
if let Some(prev_ch) = prev_ch {
|
||||
if is_boundary(prev_ch, ch) {
|
||||
if return_point_before_boundary {
|
||||
return map.clip_point(prev_offset.to_display_point(map), Bias::Right);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
prev_offset = offset;
|
||||
|
||||
offset += ch.len_utf8();
|
||||
prev_ch = Some(ch);
|
||||
}
|
||||
map.clip_point(offset.to_display_point(map), Bias::Right)
|
||||
}
|
||||
|
||||
pub fn find_boundary(
|
||||
map: &DisplaySnapshot,
|
||||
from: DisplayPoint,
|
||||
find_range: FindRange,
|
||||
is_boundary: impl FnMut(char, char) -> bool,
|
||||
) -> DisplayPoint {
|
||||
return find_boundary_point(map, from, find_range, is_boundary, false);
|
||||
}
|
||||
|
||||
pub fn find_boundary_exclusive(
|
||||
map: &DisplaySnapshot,
|
||||
from: DisplayPoint,
|
||||
find_range: FindRange,
|
||||
is_boundary: impl FnMut(char, char) -> bool,
|
||||
) -> DisplayPoint {
|
||||
return find_boundary_point(map, from, find_range, is_boundary, true);
|
||||
}
|
||||
|
||||
/// Returns an iterator over the characters following a given offset in the [`DisplaySnapshot`].
|
||||
/// The returned value also contains a range of the start/end of a returned character in
|
||||
/// the [`DisplaySnapshot`]. The offsets are relative to the start of a buffer.
|
||||
@@ -788,7 +764,7 @@ mod tests {
|
||||
&snapshot,
|
||||
display_points[0],
|
||||
FindRange::MultiLine,
|
||||
is_boundary,
|
||||
is_boundary
|
||||
),
|
||||
display_points[1]
|
||||
);
|
||||
|
||||
@@ -6,14 +6,13 @@ use crate::{
|
||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||
hover_popover::hide_hover,
|
||||
persistence::DB,
|
||||
Anchor, DisplayPoint, Editor, EditorEvent, EditorMode, EditorSettings, InlayHintRefreshReason,
|
||||
Anchor, DisplayPoint, Editor, EditorEvent, EditorMode, InlayHintRefreshReason,
|
||||
MultiBufferSnapshot, ToPoint,
|
||||
};
|
||||
pub use autoscroll::{Autoscroll, AutoscrollStrategy};
|
||||
use gpui::{point, px, AppContext, Entity, Global, Pixels, Task, ViewContext, WindowContext};
|
||||
use gpui::{point, px, AppContext, Entity, Global, Pixels, Task, ViewContext};
|
||||
use language::{Bias, Point};
|
||||
pub use scroll_amount::ScrollAmount;
|
||||
use settings::Settings;
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
time::{Duration, Instant},
|
||||
@@ -22,6 +21,7 @@ use util::ResultExt;
|
||||
use workspace::{ItemId, WorkspaceId};
|
||||
|
||||
pub const SCROLL_EVENT_SEPARATION: Duration = Duration::from_millis(28);
|
||||
pub const VERTICAL_SCROLL_MARGIN: f32 = 3.;
|
||||
const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -128,7 +128,7 @@ impl OngoingScroll {
|
||||
}
|
||||
|
||||
pub struct ScrollManager {
|
||||
pub(crate) vertical_scroll_margin: f32,
|
||||
vertical_scroll_margin: f32,
|
||||
anchor: ScrollAnchor,
|
||||
ongoing: OngoingScroll,
|
||||
autoscroll_request: Option<(Autoscroll, bool)>,
|
||||
@@ -140,9 +140,9 @@ pub struct ScrollManager {
|
||||
}
|
||||
|
||||
impl ScrollManager {
|
||||
pub fn new(cx: &mut WindowContext) -> Self {
|
||||
pub fn new() -> Self {
|
||||
ScrollManager {
|
||||
vertical_scroll_margin: EditorSettings::get_global(cx).vertical_scroll_margin,
|
||||
vertical_scroll_margin: VERTICAL_SCROLL_MARGIN,
|
||||
anchor: ScrollAnchor::new(),
|
||||
ongoing: OngoingScroll::new(),
|
||||
autoscroll_request: None,
|
||||
|
||||
@@ -12,26 +12,17 @@ pub enum Autoscroll {
|
||||
}
|
||||
|
||||
impl Autoscroll {
|
||||
/// scrolls the minimal amount to (try) and fit all cursors onscreen
|
||||
pub fn fit() -> Self {
|
||||
Self::Strategy(AutoscrollStrategy::Fit)
|
||||
}
|
||||
|
||||
/// scrolls the minimal amount to fit the newest cursor
|
||||
pub fn newest() -> Self {
|
||||
Self::Strategy(AutoscrollStrategy::Newest)
|
||||
}
|
||||
|
||||
/// scrolls so the newest cursor is vertically centered
|
||||
pub fn center() -> Self {
|
||||
Self::Strategy(AutoscrollStrategy::Center)
|
||||
}
|
||||
|
||||
/// scrolls so the neweset cursor is near the top
|
||||
/// (offset by vertical_scroll_margin)
|
||||
pub fn focused() -> Self {
|
||||
Self::Strategy(AutoscrollStrategy::Focused)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Default, Clone, Copy)]
|
||||
@@ -40,7 +31,6 @@ pub enum AutoscrollStrategy {
|
||||
Newest,
|
||||
#[default]
|
||||
Center,
|
||||
Focused,
|
||||
Top,
|
||||
Bottom,
|
||||
}
|
||||
@@ -165,11 +155,6 @@ impl Editor {
|
||||
scroll_position.y = (target_top - margin).max(0.0);
|
||||
self.set_scroll_position_internal(scroll_position, local, true, cx);
|
||||
}
|
||||
AutoscrollStrategy::Focused => {
|
||||
scroll_position.y =
|
||||
(target_top - self.scroll_manager.vertical_scroll_margin).max(0.0);
|
||||
self.set_scroll_position_internal(scroll_position, local, true, cx);
|
||||
}
|
||||
AutoscrollStrategy::Top => {
|
||||
scroll_position.y = (target_top).max(0.0);
|
||||
self.set_scroll_position_internal(scroll_position, local, true, cx);
|
||||
|
||||
@@ -4,8 +4,7 @@ use crate::{
|
||||
use collections::BTreeMap;
|
||||
use futures::Future;
|
||||
use gpui::{
|
||||
AnyWindowHandle, AppContext, Keystroke, ModelContext, Pixels, Point, View, ViewContext,
|
||||
VisualTestContext,
|
||||
AnyWindowHandle, AppContext, Keystroke, ModelContext, View, ViewContext, VisualTestContext,
|
||||
};
|
||||
use indoc::indoc;
|
||||
use itertools::Itertools;
|
||||
@@ -188,31 +187,6 @@ impl EditorTestContext {
|
||||
ranges[0].start.to_display_point(&snapshot)
|
||||
}
|
||||
|
||||
pub fn pixel_position(&mut self, marked_text: &str) -> Point<Pixels> {
|
||||
let display_point = self.display_point(marked_text);
|
||||
self.pixel_position_for(display_point)
|
||||
}
|
||||
|
||||
pub fn pixel_position_for(&mut self, display_point: DisplayPoint) -> Point<Pixels> {
|
||||
self.update_editor(|editor, cx| {
|
||||
let newest_point = editor.selections.newest_display(cx).head();
|
||||
let pixel_position = editor.pixel_position_of_newest_cursor.unwrap();
|
||||
let line_height = editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.text
|
||||
.line_height_in_pixels(cx.rem_size());
|
||||
let snapshot = editor.snapshot(cx);
|
||||
let details = editor.text_layout_details(cx);
|
||||
|
||||
let y = pixel_position.y
|
||||
+ line_height * (display_point.row() as f32 - newest_point.row() as f32);
|
||||
let x = pixel_position.x + snapshot.x_for_display_point(display_point, &details)
|
||||
- snapshot.x_for_display_point(newest_point, &details);
|
||||
Point::new(x, y)
|
||||
})
|
||||
}
|
||||
|
||||
// Returns anchors for the current buffer using `«` and `»`
|
||||
pub fn text_anchor_range(&mut self, marked_text: &str) -> Range<language::Anchor> {
|
||||
let ranges = self.ranges(marked_text);
|
||||
@@ -369,7 +343,7 @@ impl EditorTestContext {
|
||||
}
|
||||
|
||||
impl Deref for EditorTestContext {
|
||||
type Target = gpui::VisualTestContext;
|
||||
type Target = gpui::TestAppContext;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.cx
|
||||
|
||||
@@ -10,4 +10,4 @@ path = "src/feature_flags.rs"
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
|
||||
@@ -14,34 +14,34 @@ test-support = []
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
bitflags = "2.4.1"
|
||||
client.workspace = true
|
||||
db.workspace = true
|
||||
editor.workspace = true
|
||||
client = { path = "../client" }
|
||||
db = { path = "../db" }
|
||||
editor = { path = "../editor" }
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui = { path = "../gpui" }
|
||||
human_bytes = "0.4.1"
|
||||
isahc.workspace = true
|
||||
language.workspace = true
|
||||
language = { path = "../language" }
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
menu.workspace = true
|
||||
menu = { path = "../menu" }
|
||||
postage.workspace = true
|
||||
project.workspace = true
|
||||
project = { path = "../project" }
|
||||
regex.workspace = true
|
||||
release_channel.workspace = true
|
||||
release_channel = { path = "../release_channel" }
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
smallvec.workspace = true
|
||||
smol.workspace = true
|
||||
sysinfo.workspace = true
|
||||
theme.workspace = true
|
||||
theme = { path = "../theme" }
|
||||
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
|
||||
ui.workspace = true
|
||||
ui = { path = "../ui" }
|
||||
urlencoding = "2.1.2"
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace" }
|
||||
|
||||
[dev-dependencies]
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
|
||||
@@ -11,29 +11,29 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
collections.workspace = true
|
||||
editor.workspace = true
|
||||
fuzzy.workspace = true
|
||||
gpui.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
editor = { path = "../editor" }
|
||||
fuzzy = { path = "../fuzzy" }
|
||||
gpui = { path = "../gpui" }
|
||||
itertools = "0.11"
|
||||
menu.workspace = true
|
||||
picker.workspace = true
|
||||
menu = { path = "../menu" }
|
||||
picker = { path = "../picker" }
|
||||
postage.workspace = true
|
||||
project.workspace = true
|
||||
project = { path = "../project" }
|
||||
serde.workspace = true
|
||||
settings.workspace = true
|
||||
text.workspace = true
|
||||
theme.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
settings = { path = "../settings" }
|
||||
text = { path = "../text" }
|
||||
theme = { path = "../theme" }
|
||||
ui = { path = "../ui" }
|
||||
util = { path = "../util" }
|
||||
workspace = { path = "../workspace" }
|
||||
|
||||
[dev-dependencies]
|
||||
ctor.workspace = true
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
editor = { path = "../editor", features = ["test-support"] }
|
||||
env_logger.workspace = true
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
serde_json.workspace = true
|
||||
theme = { workspace = true, features = ["test-support"] }
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
theme = { path = "../theme", features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
@@ -566,7 +566,7 @@ impl FileFinderDelegate {
|
||||
let path = &path_match.path;
|
||||
let path_string = path.to_string_lossy();
|
||||
let full_path = [path_match.path_prefix.as_ref(), path_string.as_ref()].join("");
|
||||
let mut path_positions = path_match.positions.clone();
|
||||
let path_positions = path_match.positions.clone();
|
||||
|
||||
let file_name = path.file_name().map_or_else(
|
||||
|| path_match.path_prefix.to_string(),
|
||||
@@ -584,9 +584,6 @@ impl FileFinderDelegate {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let full_path = full_path.trim_end_matches(&file_name).to_string();
|
||||
path_positions.retain(|idx| *idx < full_path.len());
|
||||
|
||||
(file_name, file_name_positions, full_path, path_positions)
|
||||
}
|
||||
|
||||
@@ -871,14 +868,9 @@ impl PickerDelegate for FileFinderDelegate {
|
||||
.inset(true)
|
||||
.selected(selected)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
v_flex()
|
||||
.child(HighlightedLabel::new(file_name, file_name_positions))
|
||||
.child(
|
||||
HighlightedLabel::new(full_path, full_path_positions)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
.child(HighlightedLabel::new(full_path, full_path_positions)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -490,8 +490,8 @@ async fn test_single_file_worktrees(cx: &mut TestAppContext) {
|
||||
delegate.labels_for_path_match(&matches[0].0);
|
||||
assert_eq!(file_name, "the-file");
|
||||
assert_eq!(file_name_positions, &[0, 1, 4]);
|
||||
assert_eq!(full_path, "");
|
||||
assert_eq!(full_path_positions, &[0; 0]);
|
||||
assert_eq!(full_path, "the-file");
|
||||
assert_eq!(full_path_positions, &[0, 1, 4]);
|
||||
});
|
||||
|
||||
// Since the worktree root is a file, searching for its name followed by a slash does
|
||||
|
||||
@@ -9,11 +9,11 @@ license = "GPL-3.0-or-later"
|
||||
path = "src/fs.rs"
|
||||
|
||||
[dependencies]
|
||||
collections.workspace = true
|
||||
rope.workspace = true
|
||||
text.workspace = true
|
||||
util.workspace = true
|
||||
sum_tree.workspace = true
|
||||
collections = { path = "../collections" }
|
||||
rope = { path = "../rope" }
|
||||
text = { path = "../text" }
|
||||
util = { path = "../util" }
|
||||
sum_tree = { path = "../sum_tree" }
|
||||
|
||||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
@@ -31,16 +31,16 @@ log.workspace = true
|
||||
libc = "0.2"
|
||||
time.workspace = true
|
||||
|
||||
gpui = { workspace = true, optional = true}
|
||||
gpui = { path = "../gpui", optional = true}
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
fsevent.workspace = true
|
||||
fsevent = { path = "../fsevent" }
|
||||
|
||||
[target.'cfg(not(target_os = "macos"))'.dependencies]
|
||||
notify = "6.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
|
||||
[features]
|
||||
test-support = ["gpui/test-support"]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user