Compare commits
33 Commits
multi_sele
...
v0.174.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcd2996568 | ||
|
|
3f3d81f4c5 | ||
|
|
f6a4898435 | ||
|
|
47f9db931e | ||
|
|
c93b5d1146 | ||
|
|
e9c26810cb | ||
|
|
f33055dd92 | ||
|
|
bd778c86b8 | ||
|
|
e2b6acb790 | ||
|
|
d5fde6645a | ||
|
|
a8af92a573 | ||
|
|
4c2c5588aa | ||
|
|
fd8a12bbf4 | ||
|
|
2b7f957d70 | ||
|
|
f1af2a4a58 | ||
|
|
cf135b8767 | ||
|
|
fe6678f27d | ||
|
|
963cb2bbdf | ||
|
|
7c8f01af76 | ||
|
|
45223520d6 | ||
|
|
06efcd120c | ||
|
|
5430063f60 | ||
|
|
fd67830b0d | ||
|
|
de0fe2070f | ||
|
|
bef1ebb396 | ||
|
|
8e8e15b171 | ||
|
|
395cc58636 | ||
|
|
da3e89e676 | ||
|
|
0bd8923469 | ||
|
|
60621dc382 | ||
|
|
e94ed16159 | ||
|
|
788a2bc313 | ||
|
|
d090b04a69 |
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
@@ -109,8 +109,16 @@ jobs:
|
||||
- name: cargo clippy
|
||||
run: ./script/clippy
|
||||
|
||||
- name: Install cargo-machete
|
||||
uses: clechasseur/rs-cargo@v2
|
||||
with:
|
||||
command: install
|
||||
args: cargo-machete@0.7.0
|
||||
|
||||
- name: Check unused dependencies
|
||||
uses: bnjbvr/cargo-machete@main
|
||||
uses: clechasseur/rs-cargo@v2
|
||||
with:
|
||||
command: machete
|
||||
|
||||
- name: Check licenses
|
||||
run: |
|
||||
@@ -298,8 +306,9 @@ jobs:
|
||||
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 }}
|
||||
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
|
||||
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
|
||||
APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
|
||||
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
|
||||
@@ -482,6 +491,6 @@ jobs:
|
||||
- bundle
|
||||
steps:
|
||||
- name: gh release
|
||||
run: gh release edit $GITHUB_REF_NAME --draft=false
|
||||
run: gh release edit $GITHUB_REF_NAME --draft=true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
5
.github/workflows/release_nightly.yml
vendored
5
.github/workflows/release_nightly.yml
vendored
@@ -62,8 +62,9 @@ jobs:
|
||||
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 }}
|
||||
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
|
||||
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
|
||||
APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
|
||||
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 }}
|
||||
|
||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -4062,7 +4062,6 @@ dependencies = [
|
||||
"http_client",
|
||||
"indoc",
|
||||
"inline_completion",
|
||||
"inventory",
|
||||
"itertools 0.14.0",
|
||||
"language",
|
||||
"linkify",
|
||||
@@ -16626,7 +16625,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.174.0"
|
||||
version = "0.174.8"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"anyhow",
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
"shift-escape": "workspace::ToggleZoom",
|
||||
"open": "workspace::Open",
|
||||
"ctrl-o": "workspace::Open",
|
||||
"ctrl-=": "zed::IncreaseBufferFontSize",
|
||||
"ctrl-+": "zed::IncreaseBufferFontSize",
|
||||
"ctrl--": "zed::DecreaseBufferFontSize",
|
||||
"ctrl-0": "zed::ResetBufferFontSize",
|
||||
"ctrl-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"ctrl-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"ctrl--": ["zed::DecreaseBufferFontSize", { "persist": false }],
|
||||
"ctrl-0": ["zed::ResetBufferFontSize", { "persist": false }],
|
||||
"ctrl-,": "zed::OpenSettings",
|
||||
"ctrl-q": "zed::Quit",
|
||||
"f11": "zed::ToggleFullScreen",
|
||||
@@ -510,13 +510,14 @@
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
"alt-tab": "editor::AcceptEditPrediction",
|
||||
"alt-l": "editor::AcceptEditPrediction"
|
||||
"alt-l": "editor::AcceptEditPrediction",
|
||||
"tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && edit_prediction && !edit_prediction_requires_modifier",
|
||||
"context": "Editor && edit_prediction_conflict",
|
||||
"bindings": {
|
||||
"tab": "editor::AcceptEditPrediction",
|
||||
"alt-tab": "editor::AcceptEditPrediction",
|
||||
"alt-l": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
"cmd-shift-w": "workspace::CloseWindow",
|
||||
"shift-escape": "workspace::ToggleZoom",
|
||||
"cmd-o": "workspace::Open",
|
||||
"cmd-=": "zed::IncreaseBufferFontSize",
|
||||
"cmd-+": "zed::IncreaseBufferFontSize",
|
||||
"cmd--": "zed::DecreaseBufferFontSize",
|
||||
"cmd-0": "zed::ResetBufferFontSize",
|
||||
"cmd-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"cmd-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"cmd--": ["zed::DecreaseBufferFontSize", { "persist": false }],
|
||||
"cmd-0": ["zed::ResetBufferFontSize", { "persist": false }],
|
||||
"cmd-,": "zed::OpenSettings",
|
||||
"cmd-q": "zed::Quit",
|
||||
"cmd-h": "zed::Hide",
|
||||
@@ -583,14 +583,15 @@
|
||||
{
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
"alt-tab": "editor::AcceptEditPrediction"
|
||||
"alt-tab": "editor::AcceptEditPrediction",
|
||||
"tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && edit_prediction && !edit_prediction_requires_modifier",
|
||||
"context": "Editor && edit_prediction_conflict",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"tab": "editor::AcceptEditPrediction"
|
||||
"alt-tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"ctrl->": "zed::IncreaseBufferFontSize",
|
||||
"ctrl-<": "zed::DecreaseBufferFontSize",
|
||||
"ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-shift-j": "editor::JoinLines",
|
||||
"ctrl-d": "editor::DuplicateSelection",
|
||||
"ctrl-y": "editor::DeleteLine",
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"ctrl->": "zed::IncreaseBufferFontSize",
|
||||
"ctrl-<": "zed::DecreaseBufferFontSize",
|
||||
"ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-shift-j": "editor::JoinLines",
|
||||
"cmd-d": "editor::DuplicateSelection",
|
||||
"cmd-backspace": "editor::DeleteLine",
|
||||
|
||||
@@ -696,7 +696,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && edit_prediction && !edit_prediction_requires_modifier",
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
// This is identical to the binding in the base keymap, but the vim bindings above to
|
||||
// "vim::Tab" shadow it, so it needs to be bound again.
|
||||
@@ -704,7 +704,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "os != macos && Editor && edit_prediction",
|
||||
"context": "os != macos && Editor && edit_prediction_conflict",
|
||||
"bindings": {
|
||||
// alt-l is provided as an alternative to tab/alt-tab. and will be displayed in the UI. This
|
||||
// is because alt-tab may not be available, as it is often used for window switching on Linux
|
||||
|
||||
@@ -30,6 +30,8 @@ pub enum Model {
|
||||
#[default]
|
||||
#[serde(rename = "claude-3-5-sonnet", alias = "claude-3-5-sonnet-latest")]
|
||||
Claude3_5Sonnet,
|
||||
#[serde(rename = "claude-3-7-sonnet", alias = "claude-3-7-sonnet-latest")]
|
||||
Claude3_7Sonnet,
|
||||
#[serde(rename = "claude-3-5-haiku", alias = "claude-3-5-haiku-latest")]
|
||||
Claude3_5Haiku,
|
||||
#[serde(rename = "claude-3-opus", alias = "claude-3-opus-latest")]
|
||||
@@ -59,6 +61,8 @@ impl Model {
|
||||
pub fn from_id(id: &str) -> Result<Self> {
|
||||
if id.starts_with("claude-3-5-sonnet") {
|
||||
Ok(Self::Claude3_5Sonnet)
|
||||
} else if id.starts_with("claude-3-7-sonnet") {
|
||||
Ok(Self::Claude3_7Sonnet)
|
||||
} else if id.starts_with("claude-3-5-haiku") {
|
||||
Ok(Self::Claude3_5Haiku)
|
||||
} else if id.starts_with("claude-3-opus") {
|
||||
@@ -75,6 +79,7 @@ impl Model {
|
||||
pub fn id(&self) -> &str {
|
||||
match self {
|
||||
Model::Claude3_5Sonnet => "claude-3-5-sonnet-latest",
|
||||
Model::Claude3_7Sonnet => "claude-3-7-sonnet-latest",
|
||||
Model::Claude3_5Haiku => "claude-3-5-haiku-latest",
|
||||
Model::Claude3Opus => "claude-3-opus-latest",
|
||||
Model::Claude3Sonnet => "claude-3-sonnet-20240229",
|
||||
@@ -85,6 +90,7 @@ impl Model {
|
||||
|
||||
pub fn display_name(&self) -> &str {
|
||||
match self {
|
||||
Self::Claude3_7Sonnet => "Claude 3.7 Sonnet",
|
||||
Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
|
||||
Self::Claude3_5Haiku => "Claude 3.5 Haiku",
|
||||
Self::Claude3Opus => "Claude 3 Opus",
|
||||
@@ -98,13 +104,14 @@ impl Model {
|
||||
|
||||
pub fn cache_configuration(&self) -> Option<AnthropicModelCacheConfiguration> {
|
||||
match self {
|
||||
Self::Claude3_5Sonnet | Self::Claude3_5Haiku | Self::Claude3Haiku => {
|
||||
Some(AnthropicModelCacheConfiguration {
|
||||
min_total_token: 2_048,
|
||||
should_speculate: true,
|
||||
max_cache_anchors: 4,
|
||||
})
|
||||
}
|
||||
Self::Claude3_5Sonnet
|
||||
| Self::Claude3_5Haiku
|
||||
| Self::Claude3_7Sonnet
|
||||
| Self::Claude3Haiku => Some(AnthropicModelCacheConfiguration {
|
||||
min_total_token: 2_048,
|
||||
should_speculate: true,
|
||||
max_cache_anchors: 4,
|
||||
}),
|
||||
Self::Custom {
|
||||
cache_configuration,
|
||||
..
|
||||
@@ -117,6 +124,7 @@ impl Model {
|
||||
match self {
|
||||
Self::Claude3_5Sonnet
|
||||
| Self::Claude3_5Haiku
|
||||
| Self::Claude3_7Sonnet
|
||||
| Self::Claude3Opus
|
||||
| Self::Claude3Sonnet
|
||||
| Self::Claude3Haiku => 200_000,
|
||||
@@ -127,7 +135,7 @@ impl Model {
|
||||
pub fn max_output_tokens(&self) -> u32 {
|
||||
match self {
|
||||
Self::Claude3Opus | Self::Claude3Sonnet | Self::Claude3Haiku => 4_096,
|
||||
Self::Claude3_5Sonnet | Self::Claude3_5Haiku => 8_192,
|
||||
Self::Claude3_5Sonnet | Self::Claude3_7Sonnet | Self::Claude3_5Haiku => 8_192,
|
||||
Self::Custom {
|
||||
max_output_tokens, ..
|
||||
} => max_output_tokens.unwrap_or(4_096),
|
||||
@@ -137,6 +145,7 @@ impl Model {
|
||||
pub fn default_temperature(&self) -> f32 {
|
||||
match self {
|
||||
Self::Claude3_5Sonnet
|
||||
| Self::Claude3_7Sonnet
|
||||
| Self::Claude3_5Haiku
|
||||
| Self::Claude3Opus
|
||||
| Self::Claude3Sonnet
|
||||
|
||||
@@ -13,7 +13,7 @@ use rope::Point;
|
||||
use settings::Settings;
|
||||
use std::time::Duration;
|
||||
use text::Bias;
|
||||
use theme::ThemeSettings;
|
||||
use theme::{get_ui_font_size, ThemeSettings};
|
||||
use ui::{
|
||||
prelude::*, ButtonLike, KeyBinding, PopoverMenu, PopoverMenuHandle, Switch, TintColor, Tooltip,
|
||||
};
|
||||
@@ -369,11 +369,7 @@ impl Render for MessageEditor {
|
||||
.anchor(gpui::Corner::BottomLeft)
|
||||
.offset(gpui::Point {
|
||||
x: px(0.0),
|
||||
y: px(-ThemeSettings::clamp_font_size(
|
||||
ThemeSettings::get_global(cx).ui_font_size,
|
||||
)
|
||||
.0 * 2.0)
|
||||
- px(4.0),
|
||||
y: (-get_ui_font_size(cx) * 2) - px(4.0),
|
||||
})
|
||||
.with_handle(self.inline_context_picker_menu_handle.clone()),
|
||||
)
|
||||
|
||||
@@ -256,6 +256,7 @@ async fn perform_completion(
|
||||
// so that users can use the new version, without having to update Zed.
|
||||
request.model = match model.as_str() {
|
||||
"claude-3-5-sonnet" => anthropic::Model::Claude3_5Sonnet.id().to_string(),
|
||||
"claude-3-7-sonnet" => anthropic::Model::Claude3_7Sonnet.id().to_string(),
|
||||
"claude-3-opus" => anthropic::Model::Claude3Opus.id().to_string(),
|
||||
"claude-3-haiku" => anthropic::Model::Claude3Haiku.id().to_string(),
|
||||
"claude-3-sonnet" => anthropic::Model::Claude3Sonnet.id().to_string(),
|
||||
|
||||
@@ -40,13 +40,21 @@ pub enum Model {
|
||||
O3Mini,
|
||||
#[serde(alias = "claude-3-5-sonnet", rename = "claude-3.5-sonnet")]
|
||||
Claude3_5Sonnet,
|
||||
#[serde(alias = "claude-3-7-sonnet", rename = "claude-3.7-sonnet")]
|
||||
Claude3_7Sonnet,
|
||||
#[serde(alias = "gemini-2.0-flash", rename = "gemini-2.0-flash-001")]
|
||||
Gemini20Flash,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
pub fn uses_streaming(&self) -> bool {
|
||||
match self {
|
||||
Self::Gpt4o | Self::Gpt4 | Self::Gpt3_5Turbo | Self::Claude3_5Sonnet => true,
|
||||
Self::O3Mini | Self::O1 => false,
|
||||
Self::Gpt4o
|
||||
| Self::Gpt4
|
||||
| Self::Gpt3_5Turbo
|
||||
| Self::Claude3_5Sonnet
|
||||
| Self::Claude3_7Sonnet => true,
|
||||
Self::O3Mini | Self::O1 | Self::Gemini20Flash => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +66,8 @@ impl Model {
|
||||
"o1" => Ok(Self::O1),
|
||||
"o3-mini" => Ok(Self::O3Mini),
|
||||
"claude-3-5-sonnet" => Ok(Self::Claude3_5Sonnet),
|
||||
"claude-3-7-sonnet" => Ok(Self::Claude3_7Sonnet),
|
||||
"gemini-2.0-flash-001" => Ok(Self::Gemini20Flash),
|
||||
_ => Err(anyhow!("Invalid model id: {}", id)),
|
||||
}
|
||||
}
|
||||
@@ -70,6 +80,8 @@ impl Model {
|
||||
Self::O3Mini => "o3-mini",
|
||||
Self::O1 => "o1",
|
||||
Self::Claude3_5Sonnet => "claude-3-5-sonnet",
|
||||
Self::Claude3_7Sonnet => "claude-3-7-sonnet",
|
||||
Self::Gemini20Flash => "gemini-2.0-flash-001",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,17 +93,21 @@ impl Model {
|
||||
Self::O3Mini => "o3-mini",
|
||||
Self::O1 => "o1",
|
||||
Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
|
||||
Self::Claude3_7Sonnet => "Claude 3.7 Sonnet",
|
||||
Self::Gemini20Flash => "Gemini 2.0 Flash",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max_token_count(&self) -> usize {
|
||||
match self {
|
||||
Self::Gpt4o => 64000,
|
||||
Self::Gpt4 => 32768,
|
||||
Self::Gpt3_5Turbo => 12288,
|
||||
Self::O3Mini => 20000,
|
||||
Self::O1 => 20000,
|
||||
Self::Gpt4o => 64_000,
|
||||
Self::Gpt4 => 32_768,
|
||||
Self::Gpt3_5Turbo => 12_288,
|
||||
Self::O3Mini => 64_000,
|
||||
Self::O1 => 20_000,
|
||||
Self::Claude3_5Sonnet => 200_000,
|
||||
Self::Claude3_7Sonnet => 90_000,
|
||||
Model::Gemini20Flash => 128_000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
indoc.workspace = true
|
||||
inline_completion.workspace = true
|
||||
inventory.workspace = true
|
||||
itertools.workspace = true
|
||||
language.workspace = true
|
||||
linkify.workspace = true
|
||||
|
||||
@@ -159,12 +159,15 @@ use std::{
|
||||
pub use sum_tree::Bias;
|
||||
use sum_tree::TreeMap;
|
||||
use text::{BufferId, OffsetUtf16, Rope};
|
||||
use theme::{ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, ThemeColors, ThemeSettings};
|
||||
use theme::{
|
||||
observe_buffer_font_size_adjustment, ActiveTheme, PlayerColor, StatusColors, SyntaxTheme,
|
||||
ThemeColors, ThemeSettings,
|
||||
};
|
||||
use ui::{
|
||||
h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize, Key,
|
||||
Tooltip,
|
||||
};
|
||||
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TakeUntilExt, TryFutureExt};
|
||||
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
|
||||
use workspace::item::{ItemHandle, PreviewTabsSettings};
|
||||
use workspace::notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt};
|
||||
use workspace::{
|
||||
@@ -191,8 +194,7 @@ pub(crate) const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
||||
pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
|
||||
|
||||
pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction";
|
||||
pub(crate) const EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT: &str =
|
||||
"edit_prediction_requires_modifier";
|
||||
pub(crate) const EDIT_PREDICTION_CONFLICT_KEY_CONTEXT: &str = "edit_prediction_conflict";
|
||||
|
||||
pub fn render_parsed_markdown(
|
||||
element_id: impl Into<ElementId>,
|
||||
@@ -505,15 +507,6 @@ enum EditPredictionSettings {
|
||||
},
|
||||
}
|
||||
|
||||
impl EditPredictionSettings {
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
match self {
|
||||
EditPredictionSettings::Disabled => false,
|
||||
EditPredictionSettings::Enabled { .. } => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum InlineCompletionHighlight {}
|
||||
|
||||
pub enum MenuInlineCompletionsPolicy {
|
||||
@@ -1447,6 +1440,7 @@ impl Editor {
|
||||
cx.observe_in(&display_map, window, Self::on_display_map_changed),
|
||||
cx.observe(&blink_manager, |_, _, cx| cx.notify()),
|
||||
cx.observe_global_in::<SettingsStore>(window, Self::settings_changed),
|
||||
observe_buffer_font_size_adjustment(cx, |_, cx| cx.notify()),
|
||||
cx.observe_window_activation(window, |editor, window, cx| {
|
||||
let active = window.is_window_active();
|
||||
editor.blink_manager.update(cx, |blink_manager, cx| {
|
||||
@@ -1536,13 +1530,10 @@ impl Editor {
|
||||
key_context.add("renaming");
|
||||
}
|
||||
|
||||
let mut showing_completions = false;
|
||||
|
||||
match self.context_menu.borrow().as_ref() {
|
||||
Some(CodeContextMenu::Completions(_)) => {
|
||||
key_context.add("menu");
|
||||
key_context.add("showing_completions");
|
||||
showing_completions = true;
|
||||
}
|
||||
Some(CodeContextMenu::CodeActions(_)) => {
|
||||
key_context.add("menu");
|
||||
@@ -1570,15 +1561,11 @@ impl Editor {
|
||||
}
|
||||
|
||||
if has_active_edit_prediction {
|
||||
key_context.add("copilot_suggestion");
|
||||
key_context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
||||
if showing_completions
|
||||
|| self.edit_prediction_requires_modifier()
|
||||
// Require modifier key when the cursor is on leading whitespace, to allow `tab`
|
||||
// bindings to insert tab characters.
|
||||
|| (self.edit_prediction_requires_modifier_in_leading_space && self.edit_prediction_cursor_on_leading_whitespace)
|
||||
{
|
||||
key_context.add(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT);
|
||||
if self.edit_prediction_in_conflict() {
|
||||
key_context.add(EDIT_PREDICTION_CONFLICT_KEY_CONTEXT);
|
||||
} else {
|
||||
key_context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
||||
key_context.add("copilot_suggestion");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1589,18 +1576,52 @@ impl Editor {
|
||||
key_context
|
||||
}
|
||||
|
||||
pub fn edit_prediction_in_conflict(&self) -> bool {
|
||||
if !self.show_edit_predictions_in_menu() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let showing_completions = self
|
||||
.context_menu
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map_or(false, |context| {
|
||||
matches!(context, CodeContextMenu::Completions(_))
|
||||
});
|
||||
|
||||
showing_completions
|
||||
|| self.edit_prediction_requires_modifier()
|
||||
// Require modifier key when the cursor is on leading whitespace, to allow `tab`
|
||||
// bindings to insert tab characters.
|
||||
|| (self.edit_prediction_requires_modifier_in_leading_space && self.edit_prediction_cursor_on_leading_whitespace)
|
||||
}
|
||||
|
||||
pub fn accept_edit_prediction_keybind(
|
||||
&self,
|
||||
window: &Window,
|
||||
cx: &App,
|
||||
) -> AcceptEditPredictionBinding {
|
||||
let key_context = self.key_context_internal(true, window, cx);
|
||||
let in_conflict = self.edit_prediction_in_conflict();
|
||||
|
||||
AcceptEditPredictionBinding(
|
||||
window
|
||||
.bindings_for_action_in_context(&AcceptEditPrediction, key_context)
|
||||
.into_iter()
|
||||
.filter(|binding| {
|
||||
!in_conflict
|
||||
|| binding
|
||||
.keystrokes()
|
||||
.first()
|
||||
.map_or(false, |keystroke| keystroke.modifiers.modified())
|
||||
})
|
||||
.rev()
|
||||
.next(),
|
||||
.min_by_key(|binding| {
|
||||
binding
|
||||
.keystrokes()
|
||||
.first()
|
||||
.map_or(u8::MAX, |k| k.modifiers.number_of_modifiers())
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4965,6 +4986,7 @@ impl Editor {
|
||||
.contains(&target.to_display_point(&position_map.snapshot).row())
|
||||
|| !self.edit_prediction_requires_modifier()
|
||||
{
|
||||
self.unfold_ranges(&[target..target], true, false, cx);
|
||||
// Note that this is also done in vim's handler of the Tab action.
|
||||
self.change_selections(
|
||||
Some(Autoscroll::newest()),
|
||||
@@ -5288,11 +5310,6 @@ impl Editor {
|
||||
self.edit_prediction_settings =
|
||||
self.edit_prediction_settings_at_position(&buffer, cursor_buffer_position, cx);
|
||||
|
||||
if !self.edit_prediction_settings.is_enabled() {
|
||||
self.discard_inline_completion(false, cx);
|
||||
return None;
|
||||
}
|
||||
|
||||
self.edit_prediction_cursor_on_leading_whitespace =
|
||||
multibuffer.is_line_whitespace_upto(cursor);
|
||||
|
||||
@@ -5972,52 +5989,23 @@ impl Editor {
|
||||
} => {
|
||||
let first_edit_row = edits.first()?.0.start.text_anchor.to_point(&snapshot).row;
|
||||
|
||||
let highlighted_edits = crate::inline_completion_edit_text(
|
||||
let (highlighted_edits, has_more_lines) = crate::inline_completion_edit_text(
|
||||
&snapshot,
|
||||
&edits,
|
||||
edit_preview.as_ref()?,
|
||||
true,
|
||||
cx,
|
||||
);
|
||||
)
|
||||
.first_line_preview();
|
||||
|
||||
let len_total = highlighted_edits.text.len();
|
||||
let first_line = &highlighted_edits.text
|
||||
[..highlighted_edits.text.find('\n').unwrap_or(len_total)];
|
||||
let first_line_len = first_line.len();
|
||||
|
||||
let first_highlight_start = highlighted_edits
|
||||
.highlights
|
||||
.first()
|
||||
.map_or(0, |(range, _)| range.start);
|
||||
let drop_prefix_len = first_line
|
||||
.char_indices()
|
||||
.find(|(_, c)| !c.is_whitespace())
|
||||
.map_or(first_highlight_start, |(ix, _)| {
|
||||
ix.min(first_highlight_start)
|
||||
});
|
||||
|
||||
let preview_text = &first_line[drop_prefix_len..];
|
||||
let preview_len = preview_text.len();
|
||||
let highlights = highlighted_edits
|
||||
.highlights
|
||||
.into_iter()
|
||||
.take_until(|(range, _)| range.start > first_line_len)
|
||||
.map(|(range, style)| {
|
||||
(
|
||||
range.start - drop_prefix_len
|
||||
..(range.end - drop_prefix_len).min(preview_len),
|
||||
style,
|
||||
)
|
||||
});
|
||||
|
||||
let styled_text = gpui::StyledText::new(SharedString::new(preview_text))
|
||||
.with_highlights(&style.text, highlights);
|
||||
let styled_text = gpui::StyledText::new(highlighted_edits.text)
|
||||
.with_highlights(&style.text, highlighted_edits.highlights);
|
||||
|
||||
let preview = h_flex()
|
||||
.gap_1()
|
||||
.min_w_16()
|
||||
.child(styled_text)
|
||||
.when(len_total > first_line_len, |parent| parent.child("…"));
|
||||
.when(has_more_lines, |parent| parent.child("…"));
|
||||
|
||||
let left = if first_edit_row != cursor_point.row {
|
||||
render_relative_row_jump("", cursor_point.row, first_edit_row)
|
||||
@@ -16102,7 +16090,7 @@ impl Render for Editor {
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
font_features: settings.buffer_font.features.clone(),
|
||||
font_fallbacks: settings.buffer_font.fallbacks.clone(),
|
||||
font_size: settings.buffer_font_size().into(),
|
||||
font_size: settings.buffer_font_size(cx).into(),
|
||||
font_weight: settings.buffer_font.weight,
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
..Default::default()
|
||||
|
||||
@@ -15,14 +15,13 @@ use crate::{
|
||||
items::BufferSearchHighlights,
|
||||
mouse_context_menu::{self, MenuPosition, MouseContextMenu},
|
||||
scroll::{axis_pair, scroll_amount::ScrollAmount, AxisPair},
|
||||
AcceptEditPrediction, BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayPoint,
|
||||
DisplayRow, DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode,
|
||||
BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayPoint, DisplayRow,
|
||||
DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode,
|
||||
EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts, FocusedBlock, GoToHunk,
|
||||
GoToPrevHunk, GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor,
|
||||
InlineCompletion, JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point,
|
||||
RevertSelectedHunks, RowExt, RowRangeExt, SelectPhase, Selection, SoftWrap,
|
||||
StickyHeaderExcerpt, ToPoint, ToggleFold, CURSORS_VISIBLE_FOR,
|
||||
EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT, FILE_HEADER_HEIGHT,
|
||||
StickyHeaderExcerpt, ToPoint, ToggleFold, CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT,
|
||||
GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT,
|
||||
};
|
||||
use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus};
|
||||
@@ -35,11 +34,11 @@ use gpui::{
|
||||
point, px, quad, relative, size, svg, transparent_black, Action, AnyElement, App,
|
||||
AvailableSpace, Axis, Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners,
|
||||
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _,
|
||||
FontId, GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement,
|
||||
KeyBindingContextPredicate, Keystroke, Length, ModifiersChangedEvent, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta,
|
||||
ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled,
|
||||
Subscription, TextRun, TextStyleRefinement, WeakEntity, Window,
|
||||
FontId, GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, Keystroke, Length,
|
||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
|
||||
ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size,
|
||||
StatefulInteractiveElement, Style, Styled, Subscription, TextRun, TextStyleRefinement,
|
||||
WeakEntity, Window,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::{
|
||||
@@ -55,7 +54,7 @@ use multi_buffer::{
|
||||
RowInfo, ToOffset,
|
||||
};
|
||||
use project::project_settings::{GitGutterSetting, ProjectSettings};
|
||||
use settings::{KeyBindingValidator, KeyBindingValidatorRegistration, Settings};
|
||||
use settings::Settings;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::{
|
||||
any::TypeId,
|
||||
@@ -75,7 +74,7 @@ use ui::{
|
||||
POPOVER_Y_PADDING,
|
||||
};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use util::{markdown::MarkdownString, RangeExt, ResultExt};
|
||||
use util::{RangeExt, ResultExt};
|
||||
use workspace::{item::Item, notifications::NotifyTaskExt, Workspace};
|
||||
|
||||
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 7.;
|
||||
@@ -5834,50 +5833,6 @@ impl AcceptEditPredictionBinding {
|
||||
}
|
||||
}
|
||||
|
||||
struct AcceptEditPredictionsBindingValidator;
|
||||
|
||||
inventory::submit! { KeyBindingValidatorRegistration(|| Box::new(AcceptEditPredictionsBindingValidator)) }
|
||||
|
||||
impl KeyBindingValidator for AcceptEditPredictionsBindingValidator {
|
||||
fn action_type_id(&self) -> TypeId {
|
||||
TypeId::of::<AcceptEditPrediction>()
|
||||
}
|
||||
|
||||
fn validate(&self, binding: &gpui::KeyBinding) -> Result<(), MarkdownString> {
|
||||
use KeyBindingContextPredicate::*;
|
||||
|
||||
if binding.keystrokes().len() == 1 && binding.keystrokes()[0].modifiers.modified() {
|
||||
return Ok(());
|
||||
}
|
||||
let required_predicate =
|
||||
Not(Identifier(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT.into()).into());
|
||||
match binding.predicate() {
|
||||
Some(predicate) if required_predicate.is_superset(&predicate) => {
|
||||
return Ok(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let negated_requires_modifier_key_context = MarkdownString::inline_code(&format!(
|
||||
"!{}",
|
||||
EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT
|
||||
));
|
||||
Err(MarkdownString(format!(
|
||||
"{} can only be bound to a single keystroke with modifiers, so \
|
||||
that pressing these modifiers can be used for prediction \
|
||||
preview.\n\n\
|
||||
This restriction does not apply when the context requires {}, \
|
||||
since these bindings are not used for prediction preview. For \
|
||||
example, in the default keymap `tab` requires {}, and `alt-tab` \
|
||||
is used otherwise.\n\n\
|
||||
See [the documentation]({}) for more details.",
|
||||
MarkdownString::inline_code(AcceptEditPrediction.name()),
|
||||
negated_requires_modifier_key_context.clone(),
|
||||
negated_requires_modifier_key_context,
|
||||
"https://zed.dev/docs/completions#edit-predictions",
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn prepaint_gutter_button(
|
||||
button: IconButton,
|
||||
|
||||
@@ -371,7 +371,7 @@ impl GitRepository for RealGitRepository {
|
||||
"%(contents:subject)",
|
||||
]
|
||||
.join("%00");
|
||||
let args = vec!["for-each-ref", "refs/heads/*", "--format", &fields];
|
||||
let args = vec!["for-each-ref", "refs/heads/**/*", "--format", &fields];
|
||||
|
||||
let output = new_std_command(&self.git_binary_path)
|
||||
.current_dir(&working_directory)
|
||||
|
||||
@@ -622,6 +622,41 @@ impl HighlightedText {
|
||||
gpui::StyledText::new(self.text.clone())
|
||||
.with_highlights(default_style, self.highlights.iter().cloned())
|
||||
}
|
||||
|
||||
/// Returns the first line without leading whitespace unless highlighted
|
||||
/// and a boolean indicating if there are more lines after
|
||||
pub fn first_line_preview(self) -> (Self, bool) {
|
||||
let newline_ix = self.text.find('\n').unwrap_or(self.text.len());
|
||||
let first_line = &self.text[..newline_ix];
|
||||
|
||||
// Trim leading whitespace, unless an edit starts prior to it.
|
||||
let mut preview_start_ix = first_line.len() - first_line.trim_start().len();
|
||||
if let Some((first_highlight_range, _)) = self.highlights.first() {
|
||||
preview_start_ix = preview_start_ix.min(first_highlight_range.start);
|
||||
}
|
||||
|
||||
let preview_text = &first_line[preview_start_ix..];
|
||||
let preview_highlights = self
|
||||
.highlights
|
||||
.into_iter()
|
||||
.take_while(|(range, _)| range.start < newline_ix)
|
||||
.filter_map(|(mut range, highlight)| {
|
||||
range.start = range.start.saturating_sub(preview_start_ix);
|
||||
range.end = range.end.saturating_sub(preview_start_ix).min(newline_ix);
|
||||
if range.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some((range, highlight))
|
||||
}
|
||||
});
|
||||
|
||||
let preview = Self {
|
||||
text: SharedString::new(preview_text),
|
||||
highlights: preview_highlights.collect(),
|
||||
};
|
||||
|
||||
(preview, self.text.len() > newline_ix)
|
||||
}
|
||||
}
|
||||
|
||||
impl HighlightedTextBuilder {
|
||||
|
||||
@@ -62,7 +62,7 @@ impl CloudModel {
|
||||
pub fn availability(&self) -> LanguageModelAvailability {
|
||||
match self {
|
||||
Self::Anthropic(model) => match model {
|
||||
anthropic::Model::Claude3_5Sonnet => {
|
||||
anthropic::Model::Claude3_5Sonnet | anthropic::Model::Claude3_7Sonnet => {
|
||||
LanguageModelAvailability::RequiresPlan(Plan::Free)
|
||||
}
|
||||
anthropic::Model::Claude3Opus
|
||||
|
||||
@@ -295,6 +295,10 @@ impl LanguageModelProvider for CloudLanguageModelProvider {
|
||||
anthropic::Model::Claude3_5Sonnet.id().to_string(),
|
||||
CloudModel::Anthropic(anthropic::Model::Claude3_5Sonnet),
|
||||
);
|
||||
models.insert(
|
||||
anthropic::Model::Claude3_7Sonnet.id().to_string(),
|
||||
CloudModel::Anthropic(anthropic::Model::Claude3_7Sonnet),
|
||||
);
|
||||
}
|
||||
|
||||
let llm_closed_beta_models = if cx.has_flag::<LlmClosedBeta>() {
|
||||
|
||||
@@ -25,6 +25,7 @@ use strum::IntoEnumIterator;
|
||||
use ui::prelude::*;
|
||||
|
||||
use super::anthropic::count_anthropic_tokens;
|
||||
use super::google::count_google_tokens;
|
||||
use super::open_ai::count_open_ai_tokens;
|
||||
|
||||
const PROVIDER_ID: &str = "copilot_chat";
|
||||
@@ -174,13 +175,19 @@ impl LanguageModel for CopilotChatLanguageModel {
|
||||
) -> BoxFuture<'static, Result<usize>> {
|
||||
match self.model {
|
||||
CopilotChatModel::Claude3_5Sonnet => count_anthropic_tokens(request, cx),
|
||||
CopilotChatModel::Claude3_7Sonnet => count_anthropic_tokens(request, cx),
|
||||
CopilotChatModel::Gemini20Flash => count_google_tokens(request, cx),
|
||||
_ => {
|
||||
let model = match self.model {
|
||||
CopilotChatModel::Gpt4o => open_ai::Model::FourOmni,
|
||||
CopilotChatModel::Gpt4 => open_ai::Model::Four,
|
||||
CopilotChatModel::Gpt3_5Turbo => open_ai::Model::ThreePointFiveTurbo,
|
||||
CopilotChatModel::O1 | CopilotChatModel::O3Mini => open_ai::Model::Four,
|
||||
CopilotChatModel::Claude3_5Sonnet => unreachable!(),
|
||||
CopilotChatModel::Claude3_5Sonnet
|
||||
| CopilotChatModel::Claude3_7Sonnet
|
||||
| CopilotChatModel::Gemini20Flash => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
count_open_ai_tokens(request, model, cx)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use language_model::LanguageModelCompletionEvent;
|
||||
use language_model::{
|
||||
LanguageModel, LanguageModelId, LanguageModelName, LanguageModelProvider,
|
||||
LanguageModelProviderId, LanguageModelProviderName, LanguageModelProviderState,
|
||||
LanguageModelRequest, RateLimiter,
|
||||
LanguageModelRequest, RateLimiter, Role,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -324,6 +324,36 @@ impl LanguageModel for GoogleLanguageModel {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn count_google_tokens(
|
||||
request: LanguageModelRequest,
|
||||
cx: &App,
|
||||
) -> BoxFuture<'static, Result<usize>> {
|
||||
// We couldn't use the GoogleLanguageModelProvider to count tokens because the github copilot doesn't have the access to google_ai directly.
|
||||
// So we have to use tokenizer from tiktoken_rs to count tokens.
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let messages = request
|
||||
.messages
|
||||
.into_iter()
|
||||
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
||||
role: match message.role {
|
||||
Role::User => "user".into(),
|
||||
Role::Assistant => "assistant".into(),
|
||||
Role::System => "system".into(),
|
||||
},
|
||||
content: Some(message.string_contents()),
|
||||
name: None,
|
||||
function_call: None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Tiktoken doesn't yet support these models, so we manually use the
|
||||
// same tokenizer as GPT-4.
|
||||
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<Editor>,
|
||||
state: gpui::Entity<State>,
|
||||
|
||||
@@ -461,6 +461,17 @@ fn rename_context_key(
|
||||
}
|
||||
}
|
||||
|
||||
/// "context": "Editor && inline_completion && !showing_completions" -> "Editor && edit_prediction && !showing_completions"
|
||||
pub static CONTEXT_REPLACE: LazyLock<HashMap<&str, &str>> = LazyLock::new(|| {
|
||||
HashMap::from_iter([
|
||||
("inline_completion", "edit_prediction"),
|
||||
(
|
||||
"inline_completion_requires_modifier",
|
||||
"edit_prediction_requires_modifier",
|
||||
),
|
||||
])
|
||||
});
|
||||
|
||||
const ACTION_ARGUMENT_SNAKE_CASE_PATTERN: &str = r#"(document
|
||||
(array
|
||||
(object
|
||||
@@ -486,15 +497,10 @@ const ACTION_ARGUMENT_SNAKE_CASE_PATTERN: &str = r#"(document
|
||||
(#eq? @name "bindings")
|
||||
)"#;
|
||||
|
||||
fn is_snake_case(text: &str) -> bool {
|
||||
text == text.to_case(Case::Snake)
|
||||
}
|
||||
|
||||
fn to_snake_case(text: &str) -> String {
|
||||
text.to_case(Case::Snake)
|
||||
}
|
||||
|
||||
/// [ "editor::FoldAtLevel", { "SomeKey": "Value" } ] -> [ "editor::FoldAtLevel", { "some_key" : "value" } ]
|
||||
fn action_argument_snake_case(
|
||||
contents: &str,
|
||||
mat: &QueryMatch,
|
||||
@@ -510,34 +516,26 @@ fn action_argument_snake_case(
|
||||
.byte_range(),
|
||||
)?;
|
||||
|
||||
let replacement_key = ACTION_ARGUMENT_SNAKE_CASE_REPLACE.get(action_name)?;
|
||||
let argument_key = contents.get(
|
||||
mat.nodes_for_capture_index(argument_key_ix)
|
||||
.next()?
|
||||
.byte_range(),
|
||||
)?;
|
||||
|
||||
if argument_key != *replacement_key {
|
||||
return None;
|
||||
}
|
||||
|
||||
let argument_value_node = mat.nodes_for_capture_index(argument_value_ix).next()?;
|
||||
let argument_value = contents.get(argument_value_node.byte_range())?;
|
||||
|
||||
let mut needs_replacement = false;
|
||||
let mut new_key = argument_key.to_string();
|
||||
if !is_snake_case(argument_key) {
|
||||
new_key = to_snake_case(argument_key);
|
||||
needs_replacement = true;
|
||||
}
|
||||
|
||||
let mut new_value = argument_value.to_string();
|
||||
if argument_value_node.kind() == "string" {
|
||||
let inner_value = argument_value.trim_matches('"');
|
||||
if !is_snake_case(inner_value) {
|
||||
new_value = format!("\"{}\"", to_snake_case(inner_value));
|
||||
needs_replacement = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !needs_replacement {
|
||||
return None;
|
||||
}
|
||||
let new_key = to_snake_case(argument_key);
|
||||
let new_value = if argument_value_node.kind() == "string" {
|
||||
format!("\"{}\"", to_snake_case(argument_value.trim_matches('"')))
|
||||
} else {
|
||||
argument_value.to_string()
|
||||
};
|
||||
|
||||
let range_to_replace = mat.nodes_for_capture_index(array_ix).next()?.byte_range();
|
||||
let replacement = format!(
|
||||
@@ -548,16 +546,27 @@ fn action_argument_snake_case(
|
||||
Some((range_to_replace, replacement))
|
||||
}
|
||||
|
||||
/// "context": "Editor && inline_completion && !showing_completions" -> "Editor && edit_prediction && !showing_completions"
|
||||
pub static CONTEXT_REPLACE: LazyLock<HashMap<&str, &str>> = LazyLock::new(|| {
|
||||
HashMap::from_iter([
|
||||
("inline_completion", "edit_prediction"),
|
||||
(
|
||||
"inline_completion_requires_modifier",
|
||||
"edit_prediction_requires_modifier",
|
||||
),
|
||||
])
|
||||
});
|
||||
pub static ACTION_ARGUMENT_SNAKE_CASE_REPLACE: LazyLock<HashMap<&str, &str>> =
|
||||
LazyLock::new(|| {
|
||||
HashMap::from_iter([
|
||||
("vim::NextWordStart", "ignorePunctuation"),
|
||||
("vim::NextWordEnd", "ignorePunctuation"),
|
||||
("vim::PreviousWordStart", "ignorePunctuation"),
|
||||
("vim::PreviousWordEnd", "ignorePunctuation"),
|
||||
("vim::MoveToNext", "partialWord"),
|
||||
("vim::MoveToPrev", "partialWord"),
|
||||
("vim::Down", "displayLines"),
|
||||
("vim::Up", "displayLines"),
|
||||
("vim::EndOfLine", "displayLines"),
|
||||
("vim::StartOfLine", "displayLines"),
|
||||
("vim::FirstNonWhitespace", "displayLines"),
|
||||
("pane::CloseActiveItem", "saveIntent"),
|
||||
("vim::Paste", "preserveClipboard"),
|
||||
("vim::Word", "ignorePunctuation"),
|
||||
("vim::Subword", "ignorePunctuation"),
|
||||
("vim::IndentObj", "includeBelow"),
|
||||
])
|
||||
});
|
||||
|
||||
const SETTINGS_MIGRATION_PATTERNS: MigrationPatterns = &[
|
||||
(SETTINGS_STRING_REPLACE_QUERY, replace_setting_name),
|
||||
@@ -864,10 +873,10 @@ mod tests {
|
||||
[
|
||||
{
|
||||
"bindings": {
|
||||
"cmd-1": ["vim::PushOperator", { "Object": { "SomeKey": "Value" } }],
|
||||
"cmd-2": ["vim::SomeOtherAction", { "OtherKey": "Value" }],
|
||||
"cmd-3": ["vim::SomeDifferentAction", { "OtherKey": true }],
|
||||
"cmd-4": ["vim::OneMore", { "OtherKey": 4 }]
|
||||
"cmd-1": ["vim::PushOperator", { "Object": { "around": false } }],
|
||||
"cmd-3": ["pane::CloseActiveItem", { "saveIntent": "saveAll" }],
|
||||
"cmd-2": ["vim::NextWordStart", { "ignorePunctuation": true }],
|
||||
"cmd-4": ["task::Spawn", { "task_name": "a b" }] // should remain as it is
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -877,10 +886,10 @@ mod tests {
|
||||
[
|
||||
{
|
||||
"bindings": {
|
||||
"cmd-1": ["vim::PushObject", { "some_key": "value" }],
|
||||
"cmd-2": ["vim::SomeOtherAction", { "other_key": "value" }],
|
||||
"cmd-3": ["vim::SomeDifferentAction", { "other_key": true }],
|
||||
"cmd-4": ["vim::OneMore", { "other_key": 4 }]
|
||||
"cmd-1": ["vim::PushObject", { "around": false }],
|
||||
"cmd-3": ["pane::CloseActiveItem", { "save_intent": "save_all" }],
|
||||
"cmd-2": ["vim::NextWordStart", { "ignore_punctuation": true }],
|
||||
"cmd-4": ["task::Spawn", { "task_name": "a b" }] // should remain as it is
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -142,15 +142,15 @@ impl Model {
|
||||
|
||||
pub fn max_token_count(&self) -> usize {
|
||||
match self {
|
||||
Self::ThreePointFiveTurbo => 16385,
|
||||
Self::Four => 8192,
|
||||
Self::FourTurbo => 128000,
|
||||
Self::FourOmni => 128000,
|
||||
Self::FourOmniMini => 128000,
|
||||
Self::O1 => 200000,
|
||||
Self::O1Preview => 128000,
|
||||
Self::O1Mini => 128000,
|
||||
Self::O3Mini => 200000,
|
||||
Self::ThreePointFiveTurbo => 16_385,
|
||||
Self::Four => 8_192,
|
||||
Self::FourTurbo => 128_000,
|
||||
Self::FourOmni => 128_000,
|
||||
Self::FourOmniMini => 128_000,
|
||||
Self::O1 => 200_000,
|
||||
Self::O1Preview => 128_000,
|
||||
Self::O1Mini => 128_000,
|
||||
Self::O3Mini => 200_000,
|
||||
Self::Custom { max_tokens, .. } => *max_tokens,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ pub fn render_item<T>(
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
font_features: settings.buffer_font.features.clone(),
|
||||
font_fallbacks: settings.buffer_font.fallbacks.clone(),
|
||||
font_size: settings.buffer_font_size().into(),
|
||||
font_size: settings.buffer_font_size(cx).into(),
|
||||
font_weight: settings.buffer_font.weight,
|
||||
line_height: relative(1.),
|
||||
..Default::default()
|
||||
|
||||
@@ -1896,13 +1896,21 @@ impl LocalLspStore {
|
||||
|
||||
if let Some(version) = version {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let snapshots = self
|
||||
let snapshots = if let Some(snapshots) = self
|
||||
.buffer_snapshots
|
||||
.get_mut(&buffer_id)
|
||||
.and_then(|m| m.get_mut(&server_id))
|
||||
.ok_or_else(|| {
|
||||
anyhow!("no snapshots found for buffer {buffer_id} and server {server_id}")
|
||||
})?;
|
||||
{
|
||||
snapshots
|
||||
} else if version == 0 {
|
||||
// Some language servers report version 0 even if the buffer hasn't been opened yet.
|
||||
// We detect this case and treat it as if the version was `None`.
|
||||
return Ok(buffer.read(cx).text_snapshot());
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"no snapshots found for buffer {buffer_id} and server {server_id}"
|
||||
));
|
||||
};
|
||||
|
||||
let found_snapshot = snapshots
|
||||
.binary_search_by_key(&version, |e| e.version)
|
||||
@@ -8687,7 +8695,7 @@ fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
|
||||
}
|
||||
_ => {
|
||||
new_text.push(c);
|
||||
new_idx += 1;
|
||||
new_idx += c.len_utf8();
|
||||
last_char_was_space = false;
|
||||
}
|
||||
}
|
||||
@@ -8758,27 +8766,16 @@ fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[test]
|
||||
fn test_glob_literal_prefix() {
|
||||
assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("node_modules/**/*.js")),
|
||||
Path::new("node_modules")
|
||||
);
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
|
||||
Path::new("foo")
|
||||
);
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("foo/bar/baz.js")),
|
||||
Path::new("foo/bar/baz.js")
|
||||
);
|
||||
mod tests {
|
||||
use language::HighlightId;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_glob_literal_prefix() {
|
||||
assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("node_modules\\**/*.js")),
|
||||
glob_literal_prefix(Path::new("node_modules/**/*.js")),
|
||||
Path::new("node_modules")
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -8786,8 +8783,43 @@ fn test_glob_literal_prefix() {
|
||||
Path::new("foo")
|
||||
);
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
|
||||
glob_literal_prefix(Path::new("foo/bar/baz.js")),
|
||||
Path::new("foo/bar/baz.js")
|
||||
);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("node_modules\\**/*.js")),
|
||||
Path::new("node_modules")
|
||||
);
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
|
||||
Path::new("foo")
|
||||
);
|
||||
assert_eq!(
|
||||
glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
|
||||
Path::new("foo/bar/baz.js")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_len_chars_normalization() {
|
||||
let mut label = CodeLabel {
|
||||
text: "myElˇ (parameter) myElˇ: {\n foo: string;\n}".to_string(),
|
||||
runs: vec![(0..6, HighlightId(1))],
|
||||
filter_range: 0..6,
|
||||
};
|
||||
ensure_uniform_list_compatible_label(&mut label);
|
||||
assert_eq!(
|
||||
label,
|
||||
CodeLabel {
|
||||
text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
|
||||
runs: vec![(0..6, HighlightId(1))],
|
||||
filter_range: 0..6,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ const DEFAULT_NUM_COLUMNS: usize = 128;
|
||||
pub fn text_style(window: &mut Window, cx: &mut App) -> TextStyle {
|
||||
let settings = ThemeSettings::get_global(cx).clone();
|
||||
|
||||
let font_size = settings.buffer_font_size().into();
|
||||
let font_family = settings.buffer_font.family;
|
||||
let font_features = settings.buffer_font.features;
|
||||
let font_weight = settings.buffer_font.weight;
|
||||
@@ -72,7 +71,7 @@ pub fn text_style(window: &mut Window, cx: &mut App) -> TextStyle {
|
||||
font_features,
|
||||
font_weight,
|
||||
font_fallbacks,
|
||||
font_size,
|
||||
font_size: theme::get_buffer_font_size(cx).into(),
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: window.line_height().into(),
|
||||
background_color: Some(theme.colors().terminal_ansi_background),
|
||||
|
||||
@@ -555,7 +555,7 @@ impl TerminalElement {
|
||||
|
||||
fn rem_size(&self, cx: &mut App) -> Option<Pixels> {
|
||||
let settings = ThemeSettings::get_global(cx).clone();
|
||||
let buffer_font_size = settings.buffer_font_size();
|
||||
let buffer_font_size = settings.buffer_font_size(cx);
|
||||
let rem_size_scale = {
|
||||
// Our default UI font size is 14px on a 16px base scale.
|
||||
// This means the default UI font size is 0.875rems.
|
||||
@@ -619,7 +619,7 @@ impl Element for TerminalElement {
|
||||
let hitbox = hitbox.unwrap();
|
||||
let settings = ThemeSettings::get_global(cx).clone();
|
||||
|
||||
let buffer_font_size = settings.buffer_font_size();
|
||||
let buffer_font_size = settings.buffer_font_size(cx);
|
||||
|
||||
let terminal_settings = TerminalSettings::get_global(cx);
|
||||
|
||||
@@ -646,7 +646,8 @@ impl Element for TerminalElement {
|
||||
let line_height = terminal_settings.line_height.value();
|
||||
let font_size = terminal_settings.font_size;
|
||||
|
||||
let font_size = font_size.unwrap_or(buffer_font_size);
|
||||
let font_size =
|
||||
font_size.map_or(buffer_font_size, |size| theme::adjusted_font_size(size, cx));
|
||||
|
||||
let theme = cx.theme().clone();
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ use crate::{
|
||||
use anyhow::Result;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use gpui::{
|
||||
px, App, Font, FontFallbacks, FontFeatures, FontStyle, FontWeight, Global, Pixels, Window,
|
||||
px, App, Context, Font, FontFallbacks, FontFeatures, FontStyle, FontWeight, Global, Pixels,
|
||||
Subscription, Window,
|
||||
};
|
||||
use refineable::Refineable;
|
||||
use schemars::{
|
||||
@@ -234,6 +235,16 @@ impl SystemAppearance {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct AdjustedBufferFontSize(Pixels);
|
||||
|
||||
impl Global for AdjustedBufferFontSize {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct AdjustedUiFontSize(Pixels);
|
||||
|
||||
impl Global for AdjustedUiFontSize {}
|
||||
|
||||
/// Represents the selection of a theme, which can be either static or dynamic.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
@@ -463,7 +474,7 @@ impl ThemeSettingsContent {
|
||||
|
||||
*icon_theme_to_update = icon_theme_name.to_string();
|
||||
} else {
|
||||
self.theme = Some(ThemeSelection::Static(icon_theme_name.to_string()));
|
||||
self.icon_theme = Some(IconThemeSelection::Static(icon_theme_name.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,13 +556,11 @@ impl BufferLineHeight {
|
||||
|
||||
impl ThemeSettings {
|
||||
/// Returns the buffer font size.
|
||||
pub fn buffer_font_size(&self) -> Pixels {
|
||||
Self::clamp_font_size(self.buffer_font_size)
|
||||
}
|
||||
|
||||
/// Ensures that the font size is within the valid range.
|
||||
pub fn clamp_font_size(size: Pixels) -> Pixels {
|
||||
size.max(MIN_FONT_SIZE)
|
||||
pub fn buffer_font_size(&self, cx: &App) -> Pixels {
|
||||
let font_size = cx
|
||||
.try_global::<AdjustedBufferFontSize>()
|
||||
.map_or(self.buffer_font_size, |size| size.0);
|
||||
clamp_font_size(font_size)
|
||||
}
|
||||
|
||||
// TODO: Rename: `line_height` -> `buffer_line_height`
|
||||
@@ -626,19 +635,110 @@ impl ThemeSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Observe changes to the adjusted buffer font size.
|
||||
pub fn observe_buffer_font_size_adjustment<V: 'static>(
|
||||
cx: &mut Context<V>,
|
||||
f: impl 'static + Fn(&mut V, &mut Context<V>),
|
||||
) -> Subscription {
|
||||
cx.observe_global::<AdjustedBufferFontSize>(f)
|
||||
}
|
||||
|
||||
/// Sets the adjusted buffer font size.
|
||||
pub fn adjusted_font_size(size: Pixels, cx: &App) -> Pixels {
|
||||
let adjusted_font_size = if let Some(AdjustedBufferFontSize(adjusted_size)) =
|
||||
cx.try_global::<AdjustedBufferFontSize>()
|
||||
{
|
||||
let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
|
||||
let delta = *adjusted_size - buffer_font_size;
|
||||
size + delta
|
||||
} else {
|
||||
size
|
||||
};
|
||||
clamp_font_size(adjusted_font_size)
|
||||
}
|
||||
|
||||
/// Returns the adjusted buffer font size.
|
||||
pub fn get_buffer_font_size(cx: &App) -> Pixels {
|
||||
let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
|
||||
cx.try_global::<AdjustedBufferFontSize>()
|
||||
.map_or(buffer_font_size, |adjusted_size| adjusted_size.0)
|
||||
}
|
||||
|
||||
/// Adjusts the buffer font size.
|
||||
pub fn adjust_buffer_font_size(cx: &mut App, mut f: impl FnMut(&mut Pixels)) {
|
||||
let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
|
||||
let mut adjusted_size = cx
|
||||
.try_global::<AdjustedBufferFontSize>()
|
||||
.map_or(buffer_font_size, |adjusted_size| adjusted_size.0);
|
||||
|
||||
f(&mut adjusted_size);
|
||||
cx.set_global(AdjustedBufferFontSize(clamp_font_size(adjusted_size)));
|
||||
cx.refresh_windows();
|
||||
}
|
||||
|
||||
/// Returns whether the buffer font size has been adjusted.
|
||||
pub fn has_adjusted_buffer_font_size(cx: &App) -> bool {
|
||||
cx.has_global::<AdjustedBufferFontSize>()
|
||||
}
|
||||
|
||||
/// Resets the buffer font size to the default value.
|
||||
pub fn reset_buffer_font_size(cx: &mut App) {
|
||||
if cx.has_global::<AdjustedBufferFontSize>() {
|
||||
cx.remove_global::<AdjustedBufferFontSize>();
|
||||
cx.refresh_windows();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make private, change usages to use `get_ui_font_size` instead.
|
||||
#[allow(missing_docs)]
|
||||
pub fn setup_ui_font(window: &mut Window, cx: &mut App) -> gpui::Font {
|
||||
let (ui_font, ui_font_size) = {
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let font = theme_settings.ui_font.clone();
|
||||
(font, theme_settings.ui_font_size)
|
||||
(font, get_ui_font_size(cx))
|
||||
};
|
||||
|
||||
window.set_rem_size(ui_font_size);
|
||||
ui_font
|
||||
}
|
||||
|
||||
/// Gets the adjusted UI font size.
|
||||
pub fn get_ui_font_size(cx: &App) -> Pixels {
|
||||
let ui_font_size = ThemeSettings::get_global(cx).ui_font_size;
|
||||
cx.try_global::<AdjustedUiFontSize>()
|
||||
.map_or(ui_font_size, |adjusted_size| adjusted_size.0)
|
||||
}
|
||||
|
||||
/// Sets the adjusted UI font size.
|
||||
pub fn adjust_ui_font_size(cx: &mut App, mut f: impl FnMut(&mut Pixels)) {
|
||||
let ui_font_size = ThemeSettings::get_global(cx).ui_font_size;
|
||||
let mut adjusted_size = cx
|
||||
.try_global::<AdjustedUiFontSize>()
|
||||
.map_or(ui_font_size, |adjusted_size| adjusted_size.0);
|
||||
|
||||
f(&mut adjusted_size);
|
||||
cx.set_global(AdjustedUiFontSize(clamp_font_size(adjusted_size)));
|
||||
cx.refresh_windows();
|
||||
}
|
||||
|
||||
/// Returns whether the UI font size has been adjusted.
|
||||
pub fn has_adjusted_ui_font_size(cx: &App) -> bool {
|
||||
cx.has_global::<AdjustedUiFontSize>()
|
||||
}
|
||||
|
||||
/// Resets the UI font size to the default value.
|
||||
pub fn reset_ui_font_size(cx: &mut App) {
|
||||
if cx.has_global::<AdjustedUiFontSize>() {
|
||||
cx.remove_global::<AdjustedUiFontSize>();
|
||||
cx.refresh_windows();
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures font size is within the valid range.
|
||||
pub fn clamp_font_size(size: Pixels) -> Pixels {
|
||||
size.max(MIN_FONT_SIZE)
|
||||
}
|
||||
|
||||
fn clamp_font_weight(weight: f32) -> FontWeight {
|
||||
FontWeight(weight.clamp(100., 950.))
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use ::settings::Settings;
|
||||
use ::settings::SettingsStore;
|
||||
use anyhow::Result;
|
||||
use fallback_themes::apply_status_color_defaults;
|
||||
use fs::Fs;
|
||||
@@ -101,6 +102,16 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
|
||||
|
||||
ThemeSettings::register(cx);
|
||||
FontFamilyCache::init_global(cx);
|
||||
|
||||
let mut prev_buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
|
||||
cx.observe_global::<SettingsStore>(move |cx| {
|
||||
let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
|
||||
if buffer_font_size != prev_buffer_font_size {
|
||||
prev_buffer_font_size = buffer_font_size;
|
||||
reset_buffer_font_size(cx);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
/// Implementing this trait allows accessing the active theme.
|
||||
|
||||
@@ -83,7 +83,7 @@ pub trait StyledTypography: Styled + Sized {
|
||||
/// or other places that text needs to match the user's buffer font size.
|
||||
fn text_buffer(self, cx: &App) -> Self {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
self.text_size(settings.buffer_font_size())
|
||||
self.text_size(settings.buffer_font_size(cx))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ pub fn init(cx: &mut App) {
|
||||
};
|
||||
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
let height = theme.buffer_font_size() * theme.buffer_line_height.value();
|
||||
let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
|
||||
|
||||
let desired_size = if let Some(count) = Vim::take_count(cx) {
|
||||
height * count
|
||||
@@ -233,7 +233,7 @@ pub fn init(cx: &mut App) {
|
||||
};
|
||||
let Ok(width) = window
|
||||
.text_system()
|
||||
.advance(font_id, theme.buffer_font_size(), 'm')
|
||||
.advance(font_id, theme.buffer_font_size(cx), 'm')
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -248,7 +248,7 @@ pub fn init(cx: &mut App) {
|
||||
};
|
||||
let Ok(width) = window
|
||||
.text_system()
|
||||
.advance(font_id, theme.buffer_font_size(), 'm')
|
||||
.advance(font_id, theme.buffer_font_size(cx), 'm')
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -258,14 +258,14 @@ pub fn init(cx: &mut App) {
|
||||
workspace.register_action(|workspace, _: &ResizePaneUp, window, cx| {
|
||||
let count = Vim::take_count(cx).unwrap_or(1) as f32;
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
let height = theme.buffer_font_size() * theme.buffer_line_height.value();
|
||||
let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
|
||||
workspace.resize_pane(Axis::Vertical, height * count, window, cx);
|
||||
});
|
||||
|
||||
workspace.register_action(|workspace, _: &ResizePaneDown, window, cx| {
|
||||
let count = Vim::take_count(cx).unwrap_or(1) as f32;
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
let height = theme.buffer_font_size() * theme.buffer_line_height.value();
|
||||
let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
|
||||
workspace.resize_pane(Axis::Vertical, -height * count, window, cx);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "The fast, collaborative code editor."
|
||||
edition.workspace = true
|
||||
name = "zed"
|
||||
version = "0.174.0"
|
||||
version = "0.174.8"
|
||||
publish.workspace = true
|
||||
license = "GPL-3.0-or-later"
|
||||
authors = ["Zed Team <hi@zed.dev>"]
|
||||
|
||||
@@ -1 +1 @@
|
||||
dev
|
||||
stable
|
||||
@@ -540,65 +540,94 @@ fn register_actions(
|
||||
})
|
||||
.register_action({
|
||||
let fs = app_state.fs.clone();
|
||||
move |_, _: &zed_actions::IncreaseUiFontSize, _window, cx| {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let buffer_font_size = ThemeSettings::clamp_font_size(
|
||||
ThemeSettings::get_global(cx).ui_font_size + px(1.),
|
||||
);
|
||||
|
||||
let _ = settings.ui_font_size.insert(buffer_font_size.into());
|
||||
});
|
||||
move |_, action: &zed_actions::IncreaseUiFontSize, _window, cx| {
|
||||
if action.persist {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let ui_font_size = theme::get_ui_font_size(cx) + px(1.0);
|
||||
let _ = settings
|
||||
.ui_font_size
|
||||
.insert(theme::clamp_font_size(ui_font_size).0);
|
||||
});
|
||||
} else {
|
||||
theme::adjust_ui_font_size(cx, |size| {
|
||||
*size += px(1.0);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.register_action({
|
||||
let fs = app_state.fs.clone();
|
||||
move |_, _: &zed_actions::DecreaseUiFontSize, _window, cx| {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let buffer_font_size = ThemeSettings::clamp_font_size(
|
||||
ThemeSettings::get_global(cx).ui_font_size - px(1.),
|
||||
);
|
||||
|
||||
let _ = settings.ui_font_size.insert(buffer_font_size.into());
|
||||
});
|
||||
move |_, action: &zed_actions::DecreaseUiFontSize, _window, cx| {
|
||||
if action.persist {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let ui_font_size = theme::get_ui_font_size(cx) - px(1.0);
|
||||
let _ = settings
|
||||
.ui_font_size
|
||||
.insert(theme::clamp_font_size(ui_font_size).0);
|
||||
});
|
||||
} else {
|
||||
theme::adjust_ui_font_size(cx, |size| {
|
||||
*size -= px(1.0);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.register_action({
|
||||
let fs = app_state.fs.clone();
|
||||
move |_, _: &zed_actions::ResetUiFontSize, _window, cx| {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
|
||||
let _ = settings.ui_font_size.take();
|
||||
});
|
||||
move |_, action: &zed_actions::ResetUiFontSize, _window, cx| {
|
||||
if action.persist {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
|
||||
settings.ui_font_size = None;
|
||||
});
|
||||
} else {
|
||||
theme::reset_ui_font_size(cx);
|
||||
}
|
||||
}
|
||||
})
|
||||
.register_action({
|
||||
let fs = app_state.fs.clone();
|
||||
move |_, _: &zed_actions::IncreaseBufferFontSize, _window, cx| {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let buffer_font_size = ThemeSettings::clamp_font_size(
|
||||
ThemeSettings::get_global(cx).buffer_font_size() + px(1.),
|
||||
);
|
||||
|
||||
let _ = settings.buffer_font_size.insert(buffer_font_size.into());
|
||||
});
|
||||
move |_, action: &zed_actions::IncreaseBufferFontSize, _window, cx| {
|
||||
if action.persist {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let buffer_font_size = theme::get_buffer_font_size(cx) + px(1.0);
|
||||
let _ = settings
|
||||
.buffer_font_size
|
||||
.insert(theme::clamp_font_size(buffer_font_size).0);
|
||||
});
|
||||
} else {
|
||||
theme::adjust_buffer_font_size(cx, |size| {
|
||||
*size += px(1.0);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.register_action({
|
||||
let fs = app_state.fs.clone();
|
||||
move |_, _: &zed_actions::DecreaseBufferFontSize, _window, cx| {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let buffer_font_size = ThemeSettings::clamp_font_size(
|
||||
ThemeSettings::get_global(cx).buffer_font_size() - px(1.),
|
||||
);
|
||||
let _ = settings.buffer_font_size.insert(buffer_font_size.into());
|
||||
});
|
||||
move |_, action: &zed_actions::DecreaseBufferFontSize, _window, cx| {
|
||||
if action.persist {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
|
||||
let buffer_font_size = theme::get_buffer_font_size(cx) - px(1.0);
|
||||
let _ = settings
|
||||
.buffer_font_size
|
||||
.insert(theme::clamp_font_size(buffer_font_size).0);
|
||||
});
|
||||
} else {
|
||||
theme::adjust_buffer_font_size(cx, |size| {
|
||||
*size -= px(1.0);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.register_action({
|
||||
let fs = app_state.fs.clone();
|
||||
move |_, _: &zed_actions::ResetBufferFontSize, _window, cx| {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
|
||||
let _ = settings.buffer_font_size.take();
|
||||
});
|
||||
move |_, action: &zed_actions::ResetBufferFontSize, _window, cx| {
|
||||
if action.persist {
|
||||
update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
|
||||
settings.buffer_font_size = None;
|
||||
});
|
||||
} else {
|
||||
theme::reset_buffer_font_size(cx);
|
||||
}
|
||||
}
|
||||
})
|
||||
.register_action(install_cli)
|
||||
|
||||
@@ -131,9 +131,18 @@ pub fn app_menus() -> Vec<Menu> {
|
||||
Menu {
|
||||
name: "View".into(),
|
||||
items: vec![
|
||||
MenuItem::action("Zoom In", zed_actions::IncreaseBufferFontSize),
|
||||
MenuItem::action("Zoom Out", zed_actions::DecreaseBufferFontSize),
|
||||
MenuItem::action("Reset Zoom", zed_actions::ResetBufferFontSize),
|
||||
MenuItem::action(
|
||||
"Zoom In",
|
||||
zed_actions::IncreaseBufferFontSize { persist: true },
|
||||
),
|
||||
MenuItem::action(
|
||||
"Zoom Out",
|
||||
zed_actions::DecreaseBufferFontSize { persist: true },
|
||||
),
|
||||
MenuItem::action(
|
||||
"Reset Zoom",
|
||||
zed_actions::ResetBufferFontSize { persist: true },
|
||||
),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action("Toggle Left Dock", workspace::ToggleLeftDock),
|
||||
MenuItem::action("Toggle Right Dock", workspace::ToggleRightDock),
|
||||
|
||||
@@ -38,6 +38,48 @@ actions!(
|
||||
Extensions,
|
||||
OpenLicenses,
|
||||
OpenTelemetryLog,
|
||||
]
|
||||
);
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
pub struct DecreaseBufferFontSize {
|
||||
#[serde(default)]
|
||||
pub persist: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
pub struct IncreaseBufferFontSize {
|
||||
#[serde(default)]
|
||||
pub persist: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
pub struct ResetBufferFontSize {
|
||||
#[serde(default)]
|
||||
pub persist: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
pub struct DecreaseUiFontSize {
|
||||
#[serde(default)]
|
||||
pub persist: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
pub struct IncreaseUiFontSize {
|
||||
#[serde(default)]
|
||||
pub persist: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
pub struct ResetUiFontSize {
|
||||
#[serde(default)]
|
||||
pub persist: bool,
|
||||
}
|
||||
|
||||
impl_actions!(
|
||||
zed,
|
||||
[
|
||||
DecreaseBufferFontSize,
|
||||
IncreaseBufferFontSize,
|
||||
ResetBufferFontSize,
|
||||
|
||||
@@ -69,7 +69,7 @@ impl CompletionDiffElement {
|
||||
let settings = ThemeSettings::get_global(cx).clone();
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_size: settings.buffer_font_size().into(),
|
||||
font_size: settings.buffer_font_size(cx).into(),
|
||||
font_family: settings.buffer_font.family,
|
||||
font_features: settings.buffer_font.features,
|
||||
font_fallbacks: settings.buffer_font.fallbacks,
|
||||
|
||||
@@ -67,7 +67,7 @@ impl ZedPredictModal {
|
||||
}
|
||||
|
||||
fn view_blog(&mut self, _: &ClickEvent, _: &mut Window, cx: &mut Context<Self>) {
|
||||
cx.open_url("https://zed.dev/blog/edit-predictions");
|
||||
cx.open_url("https://zed.dev/blog/edit-prediction");
|
||||
cx.notify();
|
||||
|
||||
onboarding_event!("Blog Link clicked");
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
Zed supports two sources for completions:
|
||||
|
||||
1. "Code Completions" provided by Language Servers (LSPs) automatically installed by Zed or via [Zed Language Extensions](languages.md).
|
||||
2. "Edit Predictions" provided by external APIs like [GitHub Copilot](#github-copilot) or [Supermaven](#supermaven).
|
||||
2. "Edit Predictions" provided by Zed's own Zeta model or by external providers like [GitHub Copilot](#github-copilot) or [Supermaven](#supermaven).
|
||||
|
||||
## Code Completions
|
||||
## Language Server Code Completions {#code-completions}
|
||||
|
||||
When there is an appropriate language server available, Zed will by-default provide completions of variable names, functions, and other symbols in the current file. You can disable these by adding the following to your zed settings.json file:
|
||||
When there is an appropriate language server available, Zed will provide completions of variable names, functions, and other symbols in the current file. You can disable these by adding the following to your Zed `settings.json` file:
|
||||
|
||||
```json
|
||||
"show_completions_on_input": false
|
||||
@@ -20,51 +20,126 @@ For more information, see:
|
||||
- [Configuring Supported Languages](./configuring-languages.md)
|
||||
- [List of Zed Supported Languages](./languages.md).
|
||||
|
||||
## Configuring Edit Predictions
|
||||
## Edit Predictions {#edit-predictions}
|
||||
|
||||
### GitHub Copilot
|
||||
Zed has built-in support for predicting multiple edits at a time via its Zeta model. Clicking "Introducing: Edit Prediction" on the top right will open a brief prompt setting up this feature.
|
||||
|
||||
To use GitHub Copilot (enabled by default), add the following to your `settings.json`:
|
||||
Edit predictions appear as you type, and you can accept them by pressing `tab`. The `tab` key is already used for accepting language server completions and for indenting. In these cases, `alt-tab` is used instead to accept the prediction. When the completions menu is open, holding `alt` will cause it to temporarily disappear in order to view the prediction within the buffer.
|
||||
|
||||
On Linux, `alt-tab` is often used by the window manager for switching windows, so `alt-l` is provided as the default binding for accepting predictions. `tab` and `alt-tab` also work, but aren't displayed by default.
|
||||
|
||||
{#action editor::AcceptPartialEditPrediction} ({#kb editor::AcceptPartialEditPrediction}) can be used to accept the current edit prediction up to the next word boundary.
|
||||
|
||||
See the [Configuring GitHub Copilot](#github-copilot) and [Configuring Supermaven](#supermaven) sections below for configuration of other providers. Only text insertions at the current cursor are supported for these providers, whereas the Zeta model provides multiple predictions including deletions.
|
||||
|
||||
## Configuring Edit Prediction Keybindings
|
||||
|
||||
By default, `tab` is used to accept edit predictions. You can use another keybinding by inserting this in your keymap:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"edit_prediction_provider": "copilot"
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
// Here we also allow `alt-enter` to accept the prediction
|
||||
"alt-enter": "editor::AcceptEditPrediction"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should be able to sign-in to GitHub Copilot by clicking on the Copilot icon in the status bar and following the setup instructions.
|
||||
|
||||
### Supermaven
|
||||
|
||||
To use Supermaven, add the following to your `settings.json`:
|
||||
When you have both a language server completion and an edit prediction on screen at the same time, Zed uses a different context to accept keybindings (`edit_prediction_conflict`). If you want to use a different keybinding, you can insert this in your keymap:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"edit_prediction_provider": "supermaven"
|
||||
"context": "Editor && edit_prediction_conflict",
|
||||
"bindings": {
|
||||
"ctrl-enter": "editor::AcceptEditPrediction"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should be able to sign-in to Supermaven by clicking on the Supermaven icon in the status bar and following the setup instructions.
|
||||
If your keybinding contains a modifier (`ctrl` in the example), it will be used to preview the edit prediction and temporarily hide the language server completion menu.
|
||||
|
||||
## Using Edit Predictions
|
||||
You can also bind a keystroke without a modifier. In that case, Zed will use the default modifier (`alt`) to preview the edit prediction.
|
||||
|
||||
Once you have configured an Edit Prediction provider, you can start using edit predictions completions in your code. Edit predictions will appear as you type, and you can accept them by pressing `tab` or `enter` or hide them by pressing `esc`.
|
||||
```json
|
||||
{
|
||||
"context": "Editor && edit_prediction_conflict",
|
||||
"bindings": {
|
||||
// Here we bind tab to accept even when there's a language server completion
|
||||
"tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are a number of actions/shortcuts available to interact with edit predictions:
|
||||
### Keybinding Example: Always Use Alt-Tab
|
||||
|
||||
- `editor: accept edit prediction` (`tab`): To accept the current edit prediction
|
||||
- `editor: accept partial edit prediction` (`ctrl-cmd-right`): To accept the current edit prediction up to the next word boundary
|
||||
- `editor: show edit prediction` (`alt-tab`): Trigger an edit prediction request manually
|
||||
- `editor: next edit prediction` (`alt-tab`): To cycle to the next edit prediction
|
||||
- `editor: previous edit prediction` (`alt-shift-tab`): To cycle to the previous edit prediction
|
||||
The keybinding example below causes `alt-tab` to always be used instead of sometimes using `tab`. You might want this in order to have just one keybinding to use for accepting edit predictions, since the behavior of `tab` varies based on context.
|
||||
|
||||
### Disabling Edit Prediction
|
||||
```json
|
||||
{
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
"alt-tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
// Bind `tab` back to its original behavior.
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"tab": "editor::Tab"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && showing_completions",
|
||||
"bindings": {
|
||||
"tab": "editor::ComposeCompletion"
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
To disable predictions that appear automatically as you type, add the following to your `settings.json`:
|
||||
If `"vim_mode": true` is set within `settings.json`, then additional bindings are needed after the above to return `tab` to its original behavior:
|
||||
|
||||
```json
|
||||
{
|
||||
"context": "(VimControl && !menu) || vim_mode == replace || vim_mode == waiting",
|
||||
"bindings": {
|
||||
"tab": "vim::Tab"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_mode == literal",
|
||||
"bindings": {
|
||||
"tab": ["vim::Literal", ["tab", "\u0009"]]
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
### Keybinding Example: Displaying Tab and Alt-Tab on Linux
|
||||
|
||||
While `tab` and `alt-tab` are supported on Linux, `alt-l` is displayed instead. If your window manager does not reserve `alt-tab`, and you would prefer to use `tab` and `alt-tab`, include these bindings in `keymap.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
"tab": "editor::AcceptEditPrediction",
|
||||
// Optional: This makes the default `alt-l` binding do nothing.
|
||||
"alt-l": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && edit_prediction_conflict",
|
||||
"bindings": {
|
||||
"alt-tab": "editor::AcceptEditPrediction",
|
||||
// Optional: This makes the default `alt-l` binding do nothing.
|
||||
"alt-l": null
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
## Disabling Automatic Edit Prediction
|
||||
|
||||
To disable predictions that appear automatically as you type, set this within `settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -72,7 +147,7 @@ To disable predictions that appear automatically as you type, add the following
|
||||
}
|
||||
```
|
||||
|
||||
You can trigger edit predictions manually by executing `editor: show edit prediction` (`alt-tab`).
|
||||
You can trigger edit predictions manually by executing {#action editor::ShowEditPrediction} ({#kb editor::ShowEditPrediction}).
|
||||
|
||||
You can also add this as a language-specific setting in your `settings.json` to disable edit predictions for a specific language:
|
||||
|
||||
@@ -86,6 +161,39 @@ You can also add this as a language-specific setting in your `settings.json` to
|
||||
}
|
||||
```
|
||||
|
||||
## Configuring GitHub Copilot {#github-copilot}
|
||||
|
||||
To use GitHub Copilot, set this within `settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"edit_prediction_provider": "copilot"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should be able to sign-in to GitHub Copilot by clicking on the Copilot icon in the status bar and following the setup instructions.
|
||||
|
||||
Copilot can provide multiple completion alternatives, and these can be navigated with the following actions:
|
||||
|
||||
- {#action editor::NextEditPrediction} ({#kb editor::NextEditPrediction}): To cycle to the next edit prediction
|
||||
- {#action editor::PreviousEditPrediction} ({#kb editor::PreviousEditPrediction}): To cycle to the previous edit prediction
|
||||
|
||||
## Configuring Supermaven {#supermaven}
|
||||
|
||||
To use Supermaven, set this within `settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"edit_prediction_provider": "supermaven"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should be able to sign-in to Supermaven by clicking on the Supermaven icon in the status bar and following the setup instructions.
|
||||
|
||||
## See also
|
||||
|
||||
You may also use the Assistant Panel or the Inline Assistant to interact with language models, see the [assistant](assistant/assistant.md) documentation for more information.
|
||||
|
||||
@@ -5,19 +5,22 @@ slug: subprocessors
|
||||
|
||||
This page provides information about the Subprocessors Zed has engaged to provide processing activities on Customer Data as defined in the [Zed Terms of Use](https://zed.dev/terms).
|
||||
|
||||
| Subprocessor | Purpose | Location |
|
||||
| ------------ | -------------------- | ------------- |
|
||||
| Cloudflare | Cloud Infrastructure | Worldwide |
|
||||
| Vercel | Cloud Infrastructure | United States |
|
||||
| DigitalOcean | Cloud Infrastructure | United States |
|
||||
| AWS | Cloud Infrastructure | United States |
|
||||
| ConvertKit | Email Marketing | United States |
|
||||
| Axiom | Analytics | United States |
|
||||
| Snowflake | Analytics | United States |
|
||||
| Metabase | Analytics | United States |
|
||||
| GitHub | Authentication | United States |
|
||||
| LiveKit | Audio Conferencing | United States |
|
||||
| Anthropic | AI Services | United States |
|
||||
| OpenAI | AI Services | United States |
|
||||
| Subprocessor | Purpose | Location |
|
||||
| ------------------- | ------------------------ | ------------- |
|
||||
| Cloudflare | Cloud Infrastructure | Worldwide |
|
||||
| Amazon Web Services | Cloud Infrastructure | United States |
|
||||
| DigitalOcean | Cloud Infrastructure | United States |
|
||||
| Vercel | Cloud Infrastructure | United States |
|
||||
| ConvertKit | Email Marketing | United States |
|
||||
| Axiom | Analytics | United States |
|
||||
| Hex Technologies | Analytics | United States |
|
||||
| Snowflake | Analytics | United States |
|
||||
| LiveKit | Audio/Video Conferencing | United States |
|
||||
| GitHub | Authentication | United States |
|
||||
| Anthropic | AI Services | United States |
|
||||
| BaseTen | AI Services | United States |
|
||||
| Fireworks AI | AI Services | United States |
|
||||
| Google | AI Services | United States |
|
||||
| OpenAI | AI Services | United States |
|
||||
|
||||
**DATE: December 9, 2024**
|
||||
**DATE: February 13, 2025**
|
||||
|
||||
@@ -7,7 +7,7 @@ PLEASE READ THESE TERMS AND CONDITIONS CAREFULLY BEFORE USING THE SERVICE OR SOF
|
||||
|
||||
## 1. ACCESS TO AND USE OF THE SOLUTION
|
||||
|
||||
Subject to the terms and conditions in this Agreement, Zed will make available to You the Zed Editor Software (the "Editor"), and the Zed Collaboration Service (the "Zed Service"). The Zed Service may be used in conjunction with the Editor (the Zed Service and Editor, collectively the "Solution"). The Zed Service is designed to allow for collaboration, but the use of the Zed Service is not required to make use of the Editor; Your use of the Zed Service is optional.
|
||||
Subject to the terms and conditions of this Agreement, Zed hereby grants to You, and You hereby accept from Zed, a term-limited, non-exclusive, non-transferable, non-assignable and non-sublicensable license to make use of the Editor for Your internal use only, and subject to the use limitations in Section 2.2.
|
||||
|
||||
## 2. TERMS APPLICABLE TO THE EDITOR
|
||||
|
||||
@@ -35,7 +35,7 @@ You will use the Zed Service only in accordance with all applicable laws, includ
|
||||
|
||||
### 3.3. Customer Data
|
||||
|
||||
You are solely responsible for Customer Data including, but not limited to: (a) compliance with all applicable laws and this Agreement; (b) any claims relating to Customer Data; and (c) any claims that Customer Data infringes, misappropriates, or otherwise violates the rights of any third party. You agree and acknowledge that Customer Data may be irretrievably deleted if Your account is terminated. For purposes of this Agreement, "Customer Data" shall mean any data, information or other material provided, uploaded, or submitted by You to the Zed Service in the course of using the Zed Service.
|
||||
You are solely responsible for Customer Data including, but not limited to: (a) compliance with all applicable laws and this Agreement; (b) any claims relating to Customer Data; and (c) any claims that Customer Data infringes, misappropriates, or otherwise violates the rights of any third party. You agree and acknowledge that Customer Data may be irretrievably deleted if Your account is terminated. For purposes of this Agreement, "Customer Data" shall mean any data, information or other material provided, uploaded, or submitted by You to the Zed Service in the course of using the Zed Service. Notwithstanding anything to the contrary, You represent and warrant that You will not transfer or make available to Zed any personally identifiable information or related information subject to applicable data privacy laws or regulations, unless otherwise agreed to in writing by Zed.
|
||||
|
||||
#### 3.3.1. Customer Data Made Available to Zed
|
||||
|
||||
@@ -60,7 +60,41 @@ Customer Data consisting of data related to the behavior of the Solution prior t
|
||||
|
||||
#### 3.3.4. User Content
|
||||
|
||||
Customer Data consisting of User content created while using the Solution is classified as "User Content". User Content is transmitted from Your environment only if You collaborate with other Zed users by electing to share a project in the Editor. Once You share a project, Zed may transmit User Content consisting of file paths, file contents, and metadata regarding the code returned by language servers. Currently, Zed does not persist any User Content beyond the Your collaboration session. If You unshare a project or disconnect from the Solution, all information associated with such project will be deleted from Zed servers. In the future, Zed may save User Content regarding projects beyond the scope of a single collaboration session. We may share such User Content with those users You elected to grant access to. Zed's access to such User Content is limited to debugging and making improvements to the Solution.
|
||||
• You may access, modify or create certain data or information in connection with your access or use of the Zed Editor or the Solution. Such data and information may include, but is not limited to any of the following:
|
||||
|
||||
- (a) file contents and associated metadata (e.g., filename, paths, size, timestamps);
|
||||
- (b) source control history, comments and metadata (e.g., git history, commit messages);
|
||||
- (c) configuration data (e.g., settings, keymaps);
|
||||
- (d) anything typed, pasted and/or displayed on screen while using the Editor;
|
||||
- (e) derivative works of the above generated by the Editor (e.g., format conversions, summaries, indexes, caches);
|
||||
- (f) metadata, code and other derivative works of the above returned by language servers and other local tooling; and
|
||||
- (g) metadata, code and other derivative works of the above returned by services integrated with the Zed Editor
|
||||
|
||||
(a-g collectively, "User Content").
|
||||
|
||||
#### 3.3.5 Handling of User Content
|
||||
|
||||
Zed will make use of or transfer User Content only as specified in this Agreement, or as necessary to comply with applicable law.
|
||||
|
||||
#### 3.3.5.1 Zed Collaboration Services
|
||||
|
||||
When using Zed Collaboration Services, User Content is transmitted from Your environment only if You collaborate with other Zed users by electing to share a project in the Editor. Once You share a project, Zed may transmit User Content consisting of file paths, file contents, and metadata regarding the code returned by language servers. Currently, Zed does not persist any User Content beyond the Your collaboration session. If You unshare a project or disconnect from the Solution, all information associated with such project will be deleted from Zed servers. In the future, Zed may save User Content regarding projects beyond the scope of a single collaboration session. We may share such User Content with those users You elected to grant access to. Zed's access to such User Content is limited to debugging and making improvements to the Solution.
|
||||
|
||||
#### 3.3.5.2 Other Services
|
||||
|
||||
The Zed Editor supports integration with API-based services maintained and not operated by Zed (the "Other Services"). By way of example, Other Services includes those made available by GitHub, Anthropic, OpenAI, and similar providers, or those You host or manage directly. You may configure the Zed Editor to interoperate, communicate with, and exchange data (including User Content) directly with the Other Services. . Zed is not responsible or otherwise liable with respect to Your use of any Other Service, including but not limited to the exchange of data between the Other Service and the Zed Editor. The terms and conditions, including the applicable privacy policy, with respect to the Other Service are those made available by the applicable Other Service, not these Terms of Use.
|
||||
|
||||
#### 3.3.5.3 Zed AI Services
|
||||
|
||||
The Zed Editor supports integration with API-based services maintained and operated by Zed (the "Zed AI Services"). You may elect to use Zed AI Services as the provider for various Zed Editor features (e.g., AI Assistant Panel, Code Completions, Edit Predictions, and similar features). In connection with Your use of these features, the Zed Editor and Zed AI Services may make use of User Content to generate contextually relevant responses (the “Output”). Other than as specified in Section 3.3.5.4 of these Terms of Use, Zed will not use User Content for training of its models, or disclose User Content.
|
||||
|
||||
Output is provided "as is" without any warranties or guarantees of functionality, security, or fitness for a particular purpose. While efforts are made to ensure the accuracy and reliability, Output may include errors, vulnerabilities, and defects. You are responsible for reviewing, testing, and validating Output before use in any production or critical environment. Zed assumes no liability for any damages, losses, or liability arising from the use, modification, reliance on, or deployment of Output. Any such use is at Your own risk.
|
||||
|
||||
#### 3.3.5.4 Model Improvement Feedback
|
||||
|
||||
When using Zed AI Services to provide Edit Predictions in connection with certain open source software projects, You may elect to share requests, responses and feedback comments (collectively "Model Improvement Feedback") with Zed, and Zed may use the same to improve Zed Edit Predictions models. You may opt-out of sharing Model Improvement Feedback at any time.
|
||||
|
||||
For more information on Zed Edit Predictions please see: [https://zed.dev/docs/model-improvement](https://zed.dev/docs/model-improvement)
|
||||
|
||||
#### 3.3.5. Privacy Policy
|
||||
|
||||
@@ -138,4 +172,4 @@ Zed reserves the right to update this Agreement at any time. The terms and condi
|
||||
|
||||
This Agreement is the complete and exclusive statement of the mutual understanding of the parties and supersedes and cancels all previous written and oral agreements, communications, and other understandings relating to the subject matter of this Agreement, and all waivers and modifications must be in a writing signed by both parties, except as otherwise provided herein. Any term or provision of this Agreement held to be illegal or unenforceable shall be, to the fullest extent possible, interpreted so as to be construed as valid, but in any event the validity or enforceability of the remainder hereof shall not be affected.
|
||||
|
||||
**DATE: August 19, 2024**
|
||||
**DATE: February 13, 2025**
|
||||
|
||||
@@ -118,7 +118,7 @@ mv Cargo.toml.backup Cargo.toml
|
||||
popd
|
||||
echo "Bundled ${app_path}"
|
||||
|
||||
if [[ -n "${MACOS_CERTIFICATE:-}" && -n "${MACOS_CERTIFICATE_PASSWORD:-}" && -n "${APPLE_NOTARIZATION_USERNAME:-}" && -n "${APPLE_NOTARIZATION_PASSWORD:-}" ]]; then
|
||||
if [[ -n "${MACOS_CERTIFICATE:-}" && -n "${MACOS_CERTIFICATE_PASSWORD:-}" && -n "${APPLE_NOTARIZATION_KEY:-}" && -n "${APPLE_NOTARIZATION_KEY_ID:-}" && -n "${APPLE_NOTARIZATION_ISSUER_ID:-}" ]]; then
|
||||
can_code_sign=true
|
||||
|
||||
echo "Setting up keychain for code signing..."
|
||||
@@ -247,7 +247,7 @@ function sign_app_binaries() {
|
||||
/usr/bin/codesign --deep --force --timestamp --options runtime --entitlements crates/zed/resources/zed.entitlements --sign "$IDENTITY" "${app_path}/Contents/MacOS/zed" -v
|
||||
/usr/bin/codesign --force --timestamp --options runtime --entitlements crates/zed/resources/zed.entitlements --sign "$IDENTITY" "${app_path}" -v
|
||||
else
|
||||
echo "One or more of the following variables are missing: MACOS_CERTIFICATE, MACOS_CERTIFICATE_PASSWORD, APPLE_NOTARIZATION_USERNAME, APPLE_NOTARIZATION_PASSWORD"
|
||||
echo "One or more of the following variables are missing: MACOS_CERTIFICATE, MACOS_CERTIFICATE_PASSWORD, APPLE_NOTARIZATION_KEY, APPLE_NOTARIZATION_KEY_ID, APPLE_NOTARIZATION_ISSUER_ID"
|
||||
if [[ "$local_only" = false ]]; then
|
||||
echo "To create a self-signed local build use ./scripts/build.sh -ldf"
|
||||
exit 1
|
||||
@@ -311,6 +311,7 @@ function sign_app_binaries() {
|
||||
rm -rf ${dmg_source_directory}
|
||||
mkdir -p ${dmg_source_directory}
|
||||
mv "${app_path}" "${dmg_source_directory}"
|
||||
notarization_key_file=$(mktemp)
|
||||
|
||||
if [[ $can_code_sign = true ]]; then
|
||||
echo "Creating temporary DMG at ${dmg_file_path} using ${dmg_source_directory} to notarize app bundle"
|
||||
@@ -320,7 +321,8 @@ function sign_app_binaries() {
|
||||
/usr/bin/codesign --deep --force --timestamp --options runtime --sign "$IDENTITY" "$(pwd)/${dmg_file_path}" -v
|
||||
|
||||
echo "Notarizing DMG with Apple"
|
||||
"${xcode_bin_dir_path}/notarytool" submit --wait --apple-id "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" --team-id "$APPLE_NOTARIZATION_TEAM" "${dmg_file_path}"
|
||||
echo "$APPLE_NOTARIZATION_KEY" > "$notarization_key_file"
|
||||
"${xcode_bin_dir_path}/notarytool" submit --wait --key "$notarization_key_file" --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER_ID" "${dmg_file_path}"
|
||||
|
||||
echo "Removing temporary DMG (used only for notarization)"
|
||||
rm "${dmg_file_path}"
|
||||
@@ -347,8 +349,9 @@ function sign_app_binaries() {
|
||||
if [[ $can_code_sign = true ]]; then
|
||||
echo "Notarizing DMG with Apple"
|
||||
/usr/bin/codesign --deep --force --timestamp --options runtime --sign "$IDENTITY" "$(pwd)/${dmg_file_path}" -v
|
||||
"${xcode_bin_dir_path}/notarytool" submit --wait --apple-id "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" --team-id "$APPLE_NOTARIZATION_TEAM" "${dmg_file_path}"
|
||||
"${xcode_bin_dir_path}/notarytool" submit --wait --key "$notarization_key_file" --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER_ID" "${dmg_file_path}"
|
||||
"${xcode_bin_dir_path}/stapler" staple "${dmg_file_path}"
|
||||
rm "$notarization_key_file"
|
||||
fi
|
||||
|
||||
if [ "$open_result" = true ]; then
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2761
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2821
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\froman\fcharset0 Times-Roman;\f1\froman\fcharset0 Times-Bold;}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue233;}
|
||||
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;\cssrgb\c0\c0\c93333;}
|
||||
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{lower-alpha\}}{\leveltext\leveltemplateid2\'01\'01;}{\levelnumbers\'01;}\fi-360\li1440\lin1440 }{\listname ;}\listid1}}
|
||||
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
|
||||
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{lower-alpha\}}{\leveltext\leveltemplateid2\'01\'01;}{\levelnumbers\'01;}\fi-360\li1440\lin1440 }{\listname ;}\listid1}
|
||||
{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{lower-alpha\}}{\leveltext\leveltemplateid102\'01\'01;}{\levelnumbers\'01;}\fi-360\li1440\lin1440 }{\listname ;}\listid2}}
|
||||
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}
|
||||
\deftab720
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
@@ -14,7 +15,7 @@
|
||||
\f1\b\fs36 \cf0 1. ACCESS TO AND USE OF THE SOLUTION\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0\fs24 \cf0 Subject to the terms and conditions in this Agreement, Zed will make available to You the Zed Editor Software (the "Editor"), and the Zed Collaboration Service (the "Zed Service"). The Zed Service may be used in conjunction with the Editor (the Zed Service and Editor, collectively the "Solution"). The Zed Service is designed to allow for collaboration, but the use of the Zed Service is not required to make use of the Editor; Your use of the Zed Service is optional.\
|
||||
\f0\b0\fs24 \cf0 Subject to the terms and conditions of this Agreement, Zed hereby grants to You, and You hereby accept from Zed, a term-limited, non-exclusive, non-transferable, non-assignable and non-sublicensable license to make use of the Editor for Your internal use only, and subject to the use limitations in Section 2.2.\
|
||||
\pard\pardeftab720\sa298\partightenfactor0
|
||||
|
||||
\f1\b\fs36 \cf0 2. TERMS APPLICABLE TO THE EDITOR\
|
||||
@@ -56,7 +57,7 @@
|
||||
\f1\b\fs28 \cf0 3.3. Customer Data\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0\fs24 \cf0 You are solely responsible for Customer Data including, but not limited to: (a) compliance with all applicable laws and this Agreement; (b) any claims relating to Customer Data; and (c) any claims that Customer Data infringes, misappropriates, or otherwise violates the rights of any third party. You agree and acknowledge that Customer Data may be irretrievably deleted if Your account is terminated. For purposes of this Agreement, "Customer Data" shall mean any data, information or other material provided, uploaded, or submitted by You to the Zed Service in the course of using the Zed Service.\
|
||||
\f0\b0\fs24 \cf0 You are solely responsible for Customer Data including, but not limited to: (a) compliance with all applicable laws and this Agreement; (b) any claims relating to Customer Data; and (c) any claims that Customer Data infringes, misappropriates, or otherwise violates the rights of any third party. You agree and acknowledge that Customer Data may be irretrievably deleted if Your account is terminated. For purposes of this Agreement, "Customer Data" shall mean any data, information or other material provided, uploaded, or submitted by You to the Zed Service in the course of using the Zed Service. Notwithstanding anything to the contrary, You represent and warrant that You will not transfer or make available to Zed any personally identifiable information or related information subject to applicable data privacy laws or regulations, unless otherwise agreed to in writing by Zed.\
|
||||
\pard\pardeftab720\sa319\partightenfactor0
|
||||
|
||||
\f1\b \cf0 3.3.1. Customer Data Made Available to Zed\
|
||||
@@ -95,7 +96,62 @@ Usage Data is associated with a secure random telemetry ID which may be linked t
|
||||
\f1\b \cf0 3.3.4. User Content\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0 \cf0 Customer Data consisting of User content created while using the Solution is classified as "User Content". User Content is transmitted from Your environment only if You collaborate with other Zed users by electing to share a project in the Editor. Once You share a project, Zed may transmit User Content consisting of file paths, file contents, and metadata regarding the code returned by language servers. Currently, Zed does not persist any User Content beyond the Your collaboration session. If You unshare a project or disconnect from the Solution, all information associated with such project will be deleted from Zed servers. In the future, Zed may save User Content regarding projects beyond the scope of a single collaboration session. We may share such User Content with those users You elected to grant access to. Zed's access to such User Content is limited to debugging and making improvements to the Solution.\
|
||||
\f0\b0 \cf0 \'e2\'80\'a2 You may access, modify or create certain data or information in connection with your access or use of the Zed Editor or the Solution. Such data and information may include, but is not limited to any of the following:\
|
||||
\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\partightenfactor0
|
||||
\ls2\ilvl1\cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 {\listtext a }\expnd0\expndtw0\kerning0
|
||||
\outl0\strokewidth0 \strokec2 file contents and associated metadata (e.g., filename, paths, size, timestamps);\
|
||||
\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\partightenfactor0
|
||||
\ls2\ilvl1\cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 {\listtext b }\expnd0\expndtw0\kerning0
|
||||
\outl0\strokewidth0 \strokec2 source control history, comments and metadata (e.g., git history, commit messages);\
|
||||
\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\partightenfactor0
|
||||
\ls2\ilvl1\cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 {\listtext c }\expnd0\expndtw0\kerning0
|
||||
\outl0\strokewidth0 \strokec2 configuration data (e.g., settings, keymaps);\
|
||||
\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\partightenfactor0
|
||||
\ls2\ilvl1\cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 {\listtext d }\expnd0\expndtw0\kerning0
|
||||
\outl0\strokewidth0 \strokec2 anything typed, pasted and/or displayed on screen while using the Editor;\
|
||||
\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\partightenfactor0
|
||||
\ls2\ilvl1\cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 {\listtext e }\expnd0\expndtw0\kerning0
|
||||
\outl0\strokewidth0 \strokec2 derivative works of the above generated by the Editor (e.g., format conversions, summaries, indexes, caches);\
|
||||
\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\partightenfactor0
|
||||
\ls2\ilvl1\cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 {\listtext f }\expnd0\expndtw0\kerning0
|
||||
\outl0\strokewidth0 \strokec2 metadata, code and other derivative works of the above returned by language servers and other local tooling; and\
|
||||
\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\partightenfactor0
|
||||
\ls2\ilvl1\cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 {\listtext g }\expnd0\expndtw0\kerning0
|
||||
\outl0\strokewidth0 \strokec2 metadata, code and other derivative works of the above returned by services integrated with the Zed Editor\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
\cf0 (a-g collectively, "User Content").\
|
||||
\pard\pardeftab720\sa319\partightenfactor0
|
||||
|
||||
\f1\b \cf0 3.3.5 Handling of User Content\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0 \cf0 Zed will make use of or transfer User Content only as specified in this Agreement, or as necessary to comply with applicable law.\
|
||||
\pard\pardeftab720\sa319\partightenfactor0
|
||||
|
||||
\f1\b \cf0 3.3.5.1 Zed Collaboration Services\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0 \cf0 When using Zed Collaboration Services, User Content is transmitted from Your environment only if You collaborate with other Zed users by electing to share a project in the Editor. Once You share a project, Zed may transmit User Content consisting of file paths, file contents, and metadata regarding the code returned by language servers. Currently, Zed does not persist any User Content beyond the Your collaboration session. If You unshare a project or disconnect from the Solution, all information associated with such project will be deleted from Zed servers. In the future, Zed may save User Content regarding projects beyond the scope of a single collaboration session. We may share such User Content with those users You elected to grant access to. Zed's access to such User Content is limited to debugging and making improvements to the Solution.\
|
||||
\pard\pardeftab720\sa319\partightenfactor0
|
||||
|
||||
\f1\b \cf0 3.3.5.2 Other Services\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0 \cf0 The Zed Editor supports integration with API-based services maintained and not operated by Zed (the "Other Services"). By way of example, Other Services includes those made available by GitHub, Anthropic, OpenAI, and similar providers, or those You host or manage directly. You may configure the Zed Editor to interoperate, communicate with, and exchange data (including User Content) directly with the Other Services. . Zed is not responsible or otherwise liable with respect to Your use of any Other Service, including but not limited to the exchange of data between the Other Service and the Zed Editor. The terms and conditions, including the applicable privacy policy, with respect to the Other Service are those made available by the applicable Other Service, not these Terms of Use.\
|
||||
\pard\pardeftab720\sa319\partightenfactor0
|
||||
|
||||
\f1\b \cf0 3.3.5.3 Zed AI Services\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0 \cf0 The Zed Editor supports integration with API-based services maintained and operated by Zed (the "Zed AI Services"). You may elect to use Zed AI Services as the provider for various Zed Editor features (e.g., AI Assistant Panel, Code Completions, Edit Predictions, and similar features). In connection with Your use of these features, the Zed Editor and Zed AI Services may make use of User Content to generate contextually relevant responses (the \'e2\'80\'9cOutput\'e2\'80\uc0\u157 ). Other than as specified in Section 3.3.5.4 of these Terms of Use, Zed will not use User Content for training of its models, or disclose User Content.\
|
||||
Output is provided "as is" without any warranties or guarantees of functionality, security, or fitness for a particular purpose. While efforts are made to ensure the accuracy and reliability, Output may include errors, vulnerabilities, and defects. You are responsible for reviewing, testing, and validating Output before use in any production or critical environment. Zed assumes no liability for any damages, losses, or liability arising from the use, modification, reliance on, or deployment of Output. Any such use is at Your own risk.\
|
||||
\pard\pardeftab720\sa319\partightenfactor0
|
||||
|
||||
\f1\b \cf0 3.3.5.4 Model Improvement Feedback\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f0\b0 \cf0 When using Zed AI Services to provide Edit Predictions in connection with certain open source software projects, You may elect to share requests, responses and feedback comments (collectively "Model Improvement Feedback") with Zed, and Zed may use the same to improve Zed Edit Predictions models. You may opt-out of sharing Model Improvement Feedback at any time.\
|
||||
For more information on Zed Edit Predictions please see: {\field{\*\fldinst{HYPERLINK "https://zed.dev/docs/model-improvement"}}{\fldrslt \cf3 \ul \ulc3 \strokec3 https://zed.dev/docs/model-improvement}}\
|
||||
\pard\pardeftab720\sa319\partightenfactor0
|
||||
|
||||
\f1\b \cf0 3.3.5. Privacy Policy\
|
||||
@@ -212,6 +268,6 @@ Usage Data is associated with a secure random telemetry ID which may be linked t
|
||||
\f0\b0\fs24 \cf0 This Agreement is the complete and exclusive statement of the mutual understanding of the parties and supersedes and cancels all previous written and oral agreements, communications, and other understandings relating to the subject matter of this Agreement, and all waivers and modifications must be in a writing signed by both parties, except as otherwise provided herein. Any term or provision of this Agreement held to be illegal or unenforceable shall be, to the fullest extent possible, interpreted so as to be construed as valid, but in any event the validity or enforceability of the remainder hereof shall not be affected.\
|
||||
\pard\pardeftab720\sa240\partightenfactor0
|
||||
|
||||
\f1\b \cf0 DATE: August 19, 2024
|
||||
\f1\b \cf0 DATE: February 13, 2025
|
||||
\f0\b0 \
|
||||
}
|
||||
Reference in New Issue
Block a user