Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8b363f4b0 | ||
|
|
47df9d22a0 | ||
|
|
93ebd240d4 | ||
|
|
c7d55b243b | ||
|
|
d49a8e04e6 | ||
|
|
1f34525634 | ||
|
|
da6c2a172c | ||
|
|
f2409f2605 | ||
|
|
ce1c228e6e | ||
|
|
96ddbd4e13 | ||
|
|
f224d2a923 |
882
Cargo.toml
882
Cargo.toml
@@ -1,723 +1,11 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"crates/acp_tools",
|
||||
"crates/acp_thread",
|
||||
"crates/action_log",
|
||||
"crates/activity_indicator",
|
||||
"crates/agent",
|
||||
"crates/agent_servers",
|
||||
"crates/agent_settings",
|
||||
"crates/agent_ui",
|
||||
"crates/agent_ui_v2",
|
||||
"crates/ai_onboarding",
|
||||
"crates/anthropic",
|
||||
"crates/askpass",
|
||||
"crates/assets",
|
||||
"crates/assistant_text_thread",
|
||||
"crates/assistant_slash_command",
|
||||
"crates/assistant_slash_commands",
|
||||
"crates/audio",
|
||||
"crates/auto_update",
|
||||
"crates/auto_update_helper",
|
||||
"crates/auto_update_ui",
|
||||
"crates/aws_http_client",
|
||||
"crates/bedrock",
|
||||
"crates/breadcrumbs",
|
||||
"crates/buffer_diff",
|
||||
"crates/call",
|
||||
"crates/channel",
|
||||
"crates/cli",
|
||||
"crates/client",
|
||||
"crates/clock",
|
||||
"crates/cloud_api_client",
|
||||
"crates/cloud_api_types",
|
||||
"crates/cloud_llm_client",
|
||||
"crates/collab",
|
||||
"crates/collab_ui",
|
||||
"crates/collections",
|
||||
"crates/command_palette",
|
||||
"crates/command_palette_hooks",
|
||||
"crates/component",
|
||||
"crates/context_server",
|
||||
"crates/copilot",
|
||||
"crates/crashes",
|
||||
"crates/credentials_provider",
|
||||
"crates/dap",
|
||||
"crates/dap_adapters",
|
||||
"crates/db",
|
||||
"crates/debug_adapter_extension",
|
||||
"crates/debugger_tools",
|
||||
"crates/debugger_ui",
|
||||
"crates/deepseek",
|
||||
"crates/denoise",
|
||||
"crates/diagnostics",
|
||||
"crates/docs_preprocessor",
|
||||
"crates/edit_prediction",
|
||||
"crates/edit_prediction_types",
|
||||
"crates/edit_prediction_ui",
|
||||
"crates/edit_prediction_context",
|
||||
"crates/editor",
|
||||
"crates/eval",
|
||||
"crates/eval_utils",
|
||||
"crates/explorer_command_injector",
|
||||
"crates/extension",
|
||||
"crates/extension_api",
|
||||
"crates/extension_cli",
|
||||
"crates/extension_host",
|
||||
"crates/extensions_ui",
|
||||
"crates/feature_flags",
|
||||
"crates/feedback",
|
||||
"crates/file_finder",
|
||||
"crates/file_icons",
|
||||
"crates/fs",
|
||||
"crates/fs_benchmarks",
|
||||
"crates/fsevent",
|
||||
"crates/fuzzy",
|
||||
"crates/git",
|
||||
"crates/git_hosting_providers",
|
||||
"crates/git_ui",
|
||||
"crates/go_to_line",
|
||||
"crates/google_ai",
|
||||
"crates/gpui",
|
||||
"crates/gpui_macros",
|
||||
"crates/gpui_tokio",
|
||||
"crates/html_to_markdown",
|
||||
"crates/http_client",
|
||||
"crates/http_client_tls",
|
||||
"crates/icons",
|
||||
"crates/image_viewer",
|
||||
"crates/inspector_ui",
|
||||
"crates/install_cli",
|
||||
"crates/journal",
|
||||
"crates/json_schema_store",
|
||||
"crates/keymap_editor",
|
||||
"crates/language",
|
||||
"crates/language_extension",
|
||||
"crates/language_model",
|
||||
"crates/language_models",
|
||||
"crates/language_onboarding",
|
||||
"crates/language_selector",
|
||||
"crates/language_tools",
|
||||
"crates/languages",
|
||||
"crates/line_ending_selector",
|
||||
"crates/livekit_api",
|
||||
"crates/livekit_client",
|
||||
"crates/lmstudio",
|
||||
"crates/lsp",
|
||||
"crates/markdown",
|
||||
"crates/markdown_preview",
|
||||
"crates/media",
|
||||
"crates/menu",
|
||||
"crates/migrator",
|
||||
"crates/mistral",
|
||||
"crates/miniprofiler_ui",
|
||||
"crates/multi_buffer",
|
||||
"crates/nc",
|
||||
"crates/net",
|
||||
"crates/node_runtime",
|
||||
"crates/notifications",
|
||||
"crates/ollama",
|
||||
"crates/onboarding",
|
||||
"crates/open_ai",
|
||||
"crates/open_router",
|
||||
"crates/outline",
|
||||
"crates/outline_panel",
|
||||
"crates/panel",
|
||||
"crates/paths",
|
||||
"crates/picker",
|
||||
"crates/prettier",
|
||||
"crates/project",
|
||||
"crates/project_benchmarks",
|
||||
"crates/project_panel",
|
||||
"crates/project_symbols",
|
||||
"crates/prompt_store",
|
||||
"crates/proto",
|
||||
"crates/recent_projects",
|
||||
"crates/refineable",
|
||||
"crates/refineable/derive_refineable",
|
||||
"crates/release_channel",
|
||||
"crates/scheduler",
|
||||
"crates/remote",
|
||||
"crates/remote_server",
|
||||
"crates/repl",
|
||||
"crates/reqwest_client",
|
||||
"crates/rich_text",
|
||||
"crates/rope",
|
||||
"crates/rpc",
|
||||
"crates/rules_library",
|
||||
"crates/schema_generator",
|
||||
"crates/search",
|
||||
"crates/session",
|
||||
"crates/settings",
|
||||
"crates/settings_json",
|
||||
"crates/settings_macros",
|
||||
"crates/settings_profile_selector",
|
||||
"crates/settings_ui",
|
||||
"crates/snippet",
|
||||
"crates/snippet_provider",
|
||||
"crates/snippets_ui",
|
||||
"crates/sqlez",
|
||||
"crates/sqlez_macros",
|
||||
"crates/story",
|
||||
"crates/storybook",
|
||||
"crates/streaming_diff",
|
||||
"crates/sum_tree",
|
||||
"crates/supermaven",
|
||||
"crates/supermaven_api",
|
||||
"crates/codestral",
|
||||
"crates/svg_preview",
|
||||
"crates/system_specs",
|
||||
"crates/tab_switcher",
|
||||
"crates/task",
|
||||
"crates/tasks_ui",
|
||||
"crates/telemetry",
|
||||
"crates/telemetry_events",
|
||||
"crates/terminal",
|
||||
"crates/terminal_view",
|
||||
"crates/text",
|
||||
"crates/theme",
|
||||
"crates/theme_extension",
|
||||
"crates/theme_importer",
|
||||
"crates/theme_selector",
|
||||
"crates/time_format",
|
||||
"crates/title_bar",
|
||||
"crates/toolchain_selector",
|
||||
"crates/ui",
|
||||
"crates/ui_input",
|
||||
"crates/ui_macros",
|
||||
"crates/ui_prompt",
|
||||
"crates/util",
|
||||
"crates/util_macros",
|
||||
"crates/vercel",
|
||||
"crates/vim",
|
||||
"crates/vim_mode_setting",
|
||||
"crates/which_key",
|
||||
"crates/watch",
|
||||
"crates/web_search",
|
||||
"crates/web_search_providers",
|
||||
"crates/workspace",
|
||||
"crates/worktree",
|
||||
"crates/x_ai",
|
||||
"crates/zed",
|
||||
"crates/zed_actions",
|
||||
"crates/zed_env_vars",
|
||||
"crates/edit_prediction_cli",
|
||||
"crates/zeta_prompt",
|
||||
"crates/zlog",
|
||||
"crates/zlog_settings",
|
||||
"crates/ztracing",
|
||||
"crates/ztracing_macro",
|
||||
|
||||
#
|
||||
# Extensions
|
||||
#
|
||||
|
||||
"extensions/glsl",
|
||||
"extensions/html",
|
||||
"extensions/proto",
|
||||
"extensions/slash-commands-example",
|
||||
"extensions/test-extension",
|
||||
|
||||
#
|
||||
# Tooling
|
||||
#
|
||||
|
||||
"tooling/perf",
|
||||
"tooling/xtask",
|
||||
]
|
||||
default-members = ["crates/zed"]
|
||||
members = ["crates/askpass", "crates/assets", "crates/clock", "crates/collections", "crates/fs", "crates/fsevent", "crates/git", "crates/gpui", "crates/gpui_macros", "crates/http_client", "crates/http_client_tls", "crates/icons", "crates/media", "crates/migrator", "crates/net", "crates/paths", "crates/proto", "crates/refineable", "crates/release_channel", "crates/reqwest_client", "crates/rope", "crates/scheduler", "crates/settings", "crates/settings_json", "crates/settings_macros", "crates/sum_tree", "crates/text", "crates/theme", "crates/util", "crates/util_macros", "crates/zlog", "crates/ztracing", "crates/ztracing_macro", "tooling/perf"]
|
||||
|
||||
[workspace.package]
|
||||
publish = false
|
||||
edition = "2024"
|
||||
|
||||
[workspace.dependencies]
|
||||
|
||||
#
|
||||
# Workspace member crates
|
||||
#
|
||||
|
||||
acp_tools = { path = "crates/acp_tools" }
|
||||
acp_thread = { path = "crates/acp_thread" }
|
||||
action_log = { path = "crates/action_log" }
|
||||
agent = { path = "crates/agent" }
|
||||
activity_indicator = { path = "crates/activity_indicator" }
|
||||
agent_ui = { path = "crates/agent_ui" }
|
||||
agent_ui_v2 = { path = "crates/agent_ui_v2" }
|
||||
agent_settings = { path = "crates/agent_settings" }
|
||||
agent_servers = { path = "crates/agent_servers" }
|
||||
ai_onboarding = { path = "crates/ai_onboarding" }
|
||||
anthropic = { path = "crates/anthropic" }
|
||||
askpass = { path = "crates/askpass" }
|
||||
assets = { path = "crates/assets" }
|
||||
assistant_text_thread = { path = "crates/assistant_text_thread" }
|
||||
assistant_slash_command = { path = "crates/assistant_slash_command" }
|
||||
assistant_slash_commands = { path = "crates/assistant_slash_commands" }
|
||||
audio = { path = "crates/audio" }
|
||||
auto_update = { path = "crates/auto_update" }
|
||||
auto_update_ui = { path = "crates/auto_update_ui" }
|
||||
aws_http_client = { path = "crates/aws_http_client" }
|
||||
bedrock = { path = "crates/bedrock" }
|
||||
breadcrumbs = { path = "crates/breadcrumbs" }
|
||||
buffer_diff = { path = "crates/buffer_diff" }
|
||||
call = { path = "crates/call" }
|
||||
channel = { path = "crates/channel" }
|
||||
cli = { path = "crates/cli" }
|
||||
client = { path = "crates/client" }
|
||||
clock = { path = "crates/clock" }
|
||||
cloud_api_client = { path = "crates/cloud_api_client" }
|
||||
cloud_api_types = { path = "crates/cloud_api_types" }
|
||||
cloud_llm_client = { path = "crates/cloud_llm_client" }
|
||||
collab_ui = { path = "crates/collab_ui" }
|
||||
collections = { path = "crates/collections", version = "0.1.0" }
|
||||
command_palette = { path = "crates/command_palette" }
|
||||
command_palette_hooks = { path = "crates/command_palette_hooks" }
|
||||
component = { path = "crates/component" }
|
||||
context_server = { path = "crates/context_server" }
|
||||
copilot = { path = "crates/copilot" }
|
||||
crashes = { path = "crates/crashes" }
|
||||
credentials_provider = { path = "crates/credentials_provider" }
|
||||
crossbeam = "0.8.4"
|
||||
dap = { path = "crates/dap" }
|
||||
dap_adapters = { path = "crates/dap_adapters" }
|
||||
db = { path = "crates/db" }
|
||||
debug_adapter_extension = { path = "crates/debug_adapter_extension" }
|
||||
debugger_tools = { path = "crates/debugger_tools" }
|
||||
debugger_ui = { path = "crates/debugger_ui" }
|
||||
deepseek = { path = "crates/deepseek" }
|
||||
derive_refineable = { path = "crates/refineable/derive_refineable" }
|
||||
diagnostics = { path = "crates/diagnostics" }
|
||||
editor = { path = "crates/editor" }
|
||||
eval_utils = { path = "crates/eval_utils" }
|
||||
extension = { path = "crates/extension" }
|
||||
extension_host = { path = "crates/extension_host" }
|
||||
extensions_ui = { path = "crates/extensions_ui" }
|
||||
feature_flags = { path = "crates/feature_flags" }
|
||||
feedback = { path = "crates/feedback" }
|
||||
file_finder = { path = "crates/file_finder" }
|
||||
file_icons = { path = "crates/file_icons" }
|
||||
fs = { path = "crates/fs" }
|
||||
fsevent = { path = "crates/fsevent" }
|
||||
fuzzy = { path = "crates/fuzzy" }
|
||||
git = { path = "crates/git" }
|
||||
git_hosting_providers = { path = "crates/git_hosting_providers" }
|
||||
git_ui = { path = "crates/git_ui" }
|
||||
go_to_line = { path = "crates/go_to_line" }
|
||||
google_ai = { path = "crates/google_ai" }
|
||||
gpui = { path = "crates/gpui", default-features = false }
|
||||
gpui_macros = { path = "crates/gpui_macros" }
|
||||
gpui_tokio = { path = "crates/gpui_tokio" }
|
||||
html_to_markdown = { path = "crates/html_to_markdown" }
|
||||
http_client = { path = "crates/http_client" }
|
||||
http_client_tls = { path = "crates/http_client_tls" }
|
||||
icons = { path = "crates/icons" }
|
||||
image_viewer = { path = "crates/image_viewer" }
|
||||
edit_prediction_types = { path = "crates/edit_prediction_types" }
|
||||
edit_prediction_ui = { path = "crates/edit_prediction_ui" }
|
||||
edit_prediction_context = { path = "crates/edit_prediction_context" }
|
||||
inspector_ui = { path = "crates/inspector_ui" }
|
||||
install_cli = { path = "crates/install_cli" }
|
||||
journal = { path = "crates/journal" }
|
||||
json_schema_store = { path = "crates/json_schema_store" }
|
||||
keymap_editor = { path = "crates/keymap_editor" }
|
||||
language = { path = "crates/language" }
|
||||
language_extension = { path = "crates/language_extension" }
|
||||
language_model = { path = "crates/language_model" }
|
||||
language_models = { path = "crates/language_models" }
|
||||
language_onboarding = { path = "crates/language_onboarding" }
|
||||
language_selector = { path = "crates/language_selector" }
|
||||
language_tools = { path = "crates/language_tools" }
|
||||
languages = { path = "crates/languages" }
|
||||
line_ending_selector = { path = "crates/line_ending_selector" }
|
||||
livekit_api = { path = "crates/livekit_api" }
|
||||
livekit_client = { path = "crates/livekit_client" }
|
||||
lmstudio = { path = "crates/lmstudio" }
|
||||
lsp = { path = "crates/lsp" }
|
||||
markdown = { path = "crates/markdown" }
|
||||
markdown_preview = { path = "crates/markdown_preview" }
|
||||
svg_preview = { path = "crates/svg_preview" }
|
||||
media = { path = "crates/media" }
|
||||
menu = { path = "crates/menu" }
|
||||
migrator = { path = "crates/migrator" }
|
||||
mistral = { path = "crates/mistral" }
|
||||
multi_buffer = { path = "crates/multi_buffer" }
|
||||
miniprofiler_ui = { path = "crates/miniprofiler_ui" }
|
||||
nc = { path = "crates/nc" }
|
||||
net = { path = "crates/net" }
|
||||
node_runtime = { path = "crates/node_runtime" }
|
||||
notifications = { path = "crates/notifications" }
|
||||
ollama = { path = "crates/ollama" }
|
||||
onboarding = { path = "crates/onboarding" }
|
||||
open_ai = { path = "crates/open_ai" }
|
||||
open_router = { path = "crates/open_router", features = ["schemars"] }
|
||||
outline = { path = "crates/outline" }
|
||||
outline_panel = { path = "crates/outline_panel" }
|
||||
panel = { path = "crates/panel" }
|
||||
paths = { path = "crates/paths" }
|
||||
perf = { path = "tooling/perf" }
|
||||
picker = { path = "crates/picker" }
|
||||
prettier = { path = "crates/prettier" }
|
||||
settings_profile_selector = { path = "crates/settings_profile_selector" }
|
||||
project = { path = "crates/project" }
|
||||
project_panel = { path = "crates/project_panel" }
|
||||
project_symbols = { path = "crates/project_symbols" }
|
||||
prompt_store = { path = "crates/prompt_store" }
|
||||
proto = { path = "crates/proto" }
|
||||
recent_projects = { path = "crates/recent_projects" }
|
||||
refineable = { path = "crates/refineable" }
|
||||
release_channel = { path = "crates/release_channel" }
|
||||
remote = { path = "crates/remote" }
|
||||
remote_server = { path = "crates/remote_server" }
|
||||
repl = { path = "crates/repl" }
|
||||
reqwest_client = { path = "crates/reqwest_client" }
|
||||
rodio = { git = "https://github.com/RustAudio/rodio", rev ="e2074c6c2acf07b57cf717e076bdda7a9ac6e70b", features = ["wav", "playback", "wav_output", "recording"] }
|
||||
rope = { path = "crates/rope" }
|
||||
rpc = { path = "crates/rpc" }
|
||||
rules_library = { path = "crates/rules_library" }
|
||||
search = { path = "crates/search" }
|
||||
session = { path = "crates/session" }
|
||||
settings = { path = "crates/settings" }
|
||||
settings_json = { path = "crates/settings_json" }
|
||||
settings_macros = { path = "crates/settings_macros" }
|
||||
settings_ui = { path = "crates/settings_ui" }
|
||||
snippet = { path = "crates/snippet" }
|
||||
snippet_provider = { path = "crates/snippet_provider" }
|
||||
snippets_ui = { path = "crates/snippets_ui" }
|
||||
sqlez = { path = "crates/sqlez" }
|
||||
sqlez_macros = { path = "crates/sqlez_macros" }
|
||||
story = { path = "crates/story" }
|
||||
streaming_diff = { path = "crates/streaming_diff" }
|
||||
sum_tree = { path = "crates/sum_tree" }
|
||||
supermaven = { path = "crates/supermaven" }
|
||||
supermaven_api = { path = "crates/supermaven_api" }
|
||||
codestral = { path = "crates/codestral" }
|
||||
system_specs = { path = "crates/system_specs" }
|
||||
tab_switcher = { path = "crates/tab_switcher" }
|
||||
task = { path = "crates/task" }
|
||||
tasks_ui = { path = "crates/tasks_ui" }
|
||||
telemetry = { path = "crates/telemetry" }
|
||||
telemetry_events = { path = "crates/telemetry_events" }
|
||||
terminal = { path = "crates/terminal" }
|
||||
terminal_view = { path = "crates/terminal_view" }
|
||||
text = { path = "crates/text" }
|
||||
theme = { path = "crates/theme" }
|
||||
theme_extension = { path = "crates/theme_extension" }
|
||||
theme_selector = { path = "crates/theme_selector" }
|
||||
time_format = { path = "crates/time_format" }
|
||||
title_bar = { path = "crates/title_bar" }
|
||||
toolchain_selector = { path = "crates/toolchain_selector" }
|
||||
ui = { path = "crates/ui" }
|
||||
ui_input = { path = "crates/ui_input" }
|
||||
ui_macros = { path = "crates/ui_macros" }
|
||||
ui_prompt = { path = "crates/ui_prompt" }
|
||||
util = { path = "crates/util" }
|
||||
util_macros = { path = "crates/util_macros" }
|
||||
vercel = { path = "crates/vercel" }
|
||||
vim = { path = "crates/vim" }
|
||||
vim_mode_setting = { path = "crates/vim_mode_setting" }
|
||||
which_key = { path = "crates/which_key" }
|
||||
|
||||
watch = { path = "crates/watch" }
|
||||
web_search = { path = "crates/web_search" }
|
||||
web_search_providers = { path = "crates/web_search_providers" }
|
||||
workspace = { path = "crates/workspace" }
|
||||
worktree = { path = "crates/worktree" }
|
||||
x_ai = { path = "crates/x_ai" }
|
||||
zed = { path = "crates/zed" }
|
||||
zed_actions = { path = "crates/zed_actions" }
|
||||
zed_env_vars = { path = "crates/zed_env_vars" }
|
||||
edit_prediction = { path = "crates/edit_prediction" }
|
||||
zeta_prompt = { path = "crates/zeta_prompt" }
|
||||
zlog = { path = "crates/zlog" }
|
||||
zlog_settings = { path = "crates/zlog_settings" }
|
||||
ztracing = { path = "crates/ztracing" }
|
||||
ztracing_macro = { path = "crates/ztracing_macro" }
|
||||
|
||||
#
|
||||
# External crates
|
||||
#
|
||||
|
||||
agent-client-protocol = { version = "=0.9.2", features = ["unstable"] }
|
||||
aho-corasick = "1.1"
|
||||
alacritty_terminal = "0.25.1-rc1"
|
||||
any_vec = "0.14"
|
||||
anyhow = "1.0.86"
|
||||
arrayvec = { version = "0.7.4", features = ["serde"] }
|
||||
ashpd = { version = "0.11", default-features = false, features = ["async-std"] }
|
||||
async-compat = "0.2.1"
|
||||
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
||||
async-dispatcher = "0.1"
|
||||
async-fs = "2.1"
|
||||
async-lock = "2.1"
|
||||
async-pipe = { git = "https://github.com/zed-industries/async-pipe-rs", rev = "82d00a04211cf4e1236029aa03e6b6ce2a74c553" }
|
||||
async-recursion = "1.0.0"
|
||||
async-tar = "0.5.1"
|
||||
async-task = "4.7"
|
||||
async-trait = "0.1"
|
||||
async-tungstenite = "0.31.0"
|
||||
async_zip = { version = "0.0.18", features = ["deflate", "deflate64"] }
|
||||
aws-config = { version = "1.8.10", features = ["behavior-version-latest"] }
|
||||
aws-credential-types = { version = "1.2.8", features = [
|
||||
"hardcoded-credentials",
|
||||
] }
|
||||
aws-sdk-bedrockruntime = { version = "1.112.0", features = [
|
||||
"behavior-version-latest",
|
||||
] }
|
||||
aws-smithy-runtime-api = { version = "1.9.2", features = ["http-1x", "client"] }
|
||||
aws-smithy-types = { version = "1.3.4", features = ["http-body-1-x"] }
|
||||
backtrace = "0.3"
|
||||
base64 = "0.22"
|
||||
bincode = "1.2.1"
|
||||
bitflags = "2.6.0"
|
||||
blade-graphics = { version = "0.7.0" }
|
||||
blade-macros = { version = "0.3.0" }
|
||||
blade-util = { version = "0.3.0" }
|
||||
brotli = "8.0.2"
|
||||
bytes = "1.0"
|
||||
cargo_metadata = "0.19"
|
||||
cargo_toml = "0.21"
|
||||
cfg-if = "1.0.3"
|
||||
chardetng = "0.1"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
ciborium = "0.2"
|
||||
circular-buffer = "1.0"
|
||||
clap = { version = "4.4", features = ["derive", "wrap_help"] }
|
||||
cocoa = "=0.26.0"
|
||||
cocoa-foundation = "=0.2.0"
|
||||
convert_case = "0.8.0"
|
||||
core-foundation = "=0.10.0"
|
||||
core-foundation-sys = "0.8.6"
|
||||
core-video = { version = "0.4.3", features = ["metal"] }
|
||||
cpal = "0.16"
|
||||
crash-handler = "0.6"
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
ctor = "0.4.0"
|
||||
dap-types = { git = "https://github.com/zed-industries/dap-types", rev = "1b461b310481d01e02b2603c16d7144b926339f8" }
|
||||
dashmap = "6.0"
|
||||
derive_more = "0.99.17"
|
||||
dirs = "4.0"
|
||||
documented = "0.9.1"
|
||||
dotenvy = "0.15.0"
|
||||
ec4rs = "1.1"
|
||||
emojis = "0.6.1"
|
||||
env_logger = "0.11"
|
||||
encoding_rs = "0.8"
|
||||
exec = "0.3.1"
|
||||
fancy-regex = "0.16.0"
|
||||
fork = "0.4.0"
|
||||
futures = "0.3"
|
||||
futures-lite = "1.13"
|
||||
gh-workflow = { git = "https://github.com/zed-industries/gh-workflow", rev = "09acfdf2bd5c1d6254abefd609c808ff73547b2c" }
|
||||
git2 = { version = "0.20.1", default-features = false }
|
||||
globset = "0.4"
|
||||
handlebars = "4.3"
|
||||
heck = "0.5"
|
||||
heed = { version = "0.21.0", features = ["read-txn-no-tls"] }
|
||||
hex = "0.4.3"
|
||||
human_bytes = "0.4.1"
|
||||
html5ever = "0.27.0"
|
||||
http = "1.1"
|
||||
http-body = "1.0"
|
||||
hyper = "0.14"
|
||||
ignore = "0.4.22"
|
||||
image = "0.25.1"
|
||||
imara-diff = "0.1.8"
|
||||
indexmap = { version = "2.7.0", features = ["serde"] }
|
||||
indoc = "2"
|
||||
inventory = "0.3.19"
|
||||
itertools = "0.14.0"
|
||||
json_dotpath = "1.1"
|
||||
jsonschema = "0.37.0"
|
||||
jsonwebtoken = "9.3"
|
||||
jupyter-protocol = "0.10.0"
|
||||
jupyter-websocket-client = "0.15.0"
|
||||
libc = "0.2"
|
||||
libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
|
||||
linkify = "0.10.0"
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
|
||||
lsp-types = { git = "https://github.com/zed-industries/lsp-types", rev = "b71ab4eeb27d9758be8092020a46fe33fbca4e33" }
|
||||
mach2 = "0.5"
|
||||
markup5ever_rcdom = "0.3.0"
|
||||
metal = "0.29"
|
||||
minidumper = "0.8"
|
||||
moka = { version = "0.12.10", features = ["sync"] }
|
||||
naga = { version = "25.0", features = ["wgsl-in"] }
|
||||
nanoid = "0.4"
|
||||
nbformat = "0.15.0"
|
||||
nix = "0.29"
|
||||
num-format = "0.4.4"
|
||||
objc = "0.2"
|
||||
objc2-foundation = { version = "=0.3.1", default-features = false, features = [
|
||||
"NSArray",
|
||||
"NSAttributedString",
|
||||
"NSBundle",
|
||||
"NSCoder",
|
||||
"NSData",
|
||||
"NSDate",
|
||||
"NSDictionary",
|
||||
"NSEnumerator",
|
||||
"NSError",
|
||||
"NSGeometry",
|
||||
"NSNotification",
|
||||
"NSNull",
|
||||
"NSObjCRuntime",
|
||||
"NSObject",
|
||||
"NSProcessInfo",
|
||||
"NSRange",
|
||||
"NSRunLoop",
|
||||
"NSString",
|
||||
"NSURL",
|
||||
"NSUndoManager",
|
||||
"NSValue",
|
||||
"objc2-core-foundation",
|
||||
"std"
|
||||
] }
|
||||
open = "5.0.0"
|
||||
ordered-float = "2.1.1"
|
||||
palette = { version = "0.7.5", default-features = false, features = ["std"] }
|
||||
parking_lot = "0.12.1"
|
||||
partial-json-fixer = "0.5.3"
|
||||
parse_int = "0.9"
|
||||
pciid-parser = "0.8.0"
|
||||
pathdiff = "0.2"
|
||||
pet = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-conda = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-core = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-fs = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-virtualenv = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
portable-pty = "0.9.0"
|
||||
postage = { version = "0.5", features = ["futures-traits"] }
|
||||
pretty_assertions = { version = "1.3.0", features = ["unstable"] }
|
||||
proc-macro2 = "1.0.93"
|
||||
profiling = "1"
|
||||
prost = "0.9"
|
||||
prost-build = "0.9"
|
||||
prost-types = "0.9"
|
||||
pulldown-cmark = { version = "0.12.0", default-features = false }
|
||||
quote = "1.0.9"
|
||||
rand = "0.9"
|
||||
rayon = "1.8"
|
||||
regex = "1.5"
|
||||
# WARNING: If you change this, you must also publish a new version of zed-reqwest to crates.io
|
||||
reqwest = { git = "https://github.com/zed-industries/reqwest.git", rev = "c15662463bda39148ba154100dd44d3fba5873a4", default-features = false, features = [
|
||||
"charset",
|
||||
"http2",
|
||||
"macos-system-configuration",
|
||||
"multipart",
|
||||
"rustls-tls-native-roots",
|
||||
"socks",
|
||||
"stream",
|
||||
], package = "zed-reqwest", version = "0.12.15-zed" }
|
||||
rsa = "0.9.6"
|
||||
runtimelib = { version = "0.30.0", default-features = false, features = [
|
||||
"async-dispatcher-runtime", "aws-lc-rs"
|
||||
] }
|
||||
rust-embed = { version = "8.4", features = ["include-exclude"] }
|
||||
rustc-hash = "2.1.0"
|
||||
rustls = { version = "0.23.26" }
|
||||
rustls-platform-verifier = "0.5.0"
|
||||
# WARNING: If you change this, you must also publish a new version of zed-scap to crates.io
|
||||
scap = { git = "https://github.com/zed-industries/scap", rev = "4afea48c3b002197176fb19cd0f9b180dd36eaac", default-features = false, package = "zed-scap", version = "0.0.8-zed" }
|
||||
schemars = { version = "1.0", features = ["indexmap2"] }
|
||||
semver = { version = "1.0", features = ["serde"] }
|
||||
serde = { version = "1.0.221", features = ["derive", "rc"] }
|
||||
serde_json = { version = "1.0.144", features = ["preserve_order", "raw_value"] }
|
||||
serde_json_lenient = { version = "0.2", features = [
|
||||
"preserve_order",
|
||||
"raw_value",
|
||||
] }
|
||||
serde_path_to_error = "0.1.17"
|
||||
serde_repr = "0.1"
|
||||
serde_urlencoded = "0.7"
|
||||
sha2 = "0.10"
|
||||
shellexpand = "2.1.0"
|
||||
shlex = "1.3.0"
|
||||
simplelog = "0.12.2"
|
||||
slotmap = "1.0.6"
|
||||
smallvec = { version = "1.6", features = ["union", "const_new"] }
|
||||
smol = "2.0"
|
||||
sqlformat = "0.2"
|
||||
stacksafe = "0.1"
|
||||
streaming-iterator = "0.1"
|
||||
strsim = "0.11"
|
||||
strum = { version = "0.27.2", features = ["derive"] }
|
||||
subtle = "2.5.0"
|
||||
syn = { version = "2.0.101", features = ["full", "extra-traits", "visit-mut"] }
|
||||
sys-locale = "0.3.1"
|
||||
sysinfo = "0.37.0"
|
||||
take-until = "0.2.0"
|
||||
tempfile = "3.20.0"
|
||||
thiserror = "2.0.12"
|
||||
tiktoken-rs = { git = "https://github.com/zed-industries/tiktoken-rs", rev = "2570c4387a8505fb8f1d3f3557454b474f1e8271" }
|
||||
time = { version = "0.3", features = [
|
||||
"macros",
|
||||
"parsing",
|
||||
"serde",
|
||||
"serde-well-known",
|
||||
"formatting",
|
||||
"local-offset",
|
||||
] }
|
||||
tiny_http = "0.8"
|
||||
tokio = { version = "1" }
|
||||
tokio-tungstenite = { version = "0.26", features = ["__rustls-tls"] }
|
||||
tokio-socks = { version = "0.5.2", default-features = false, features = ["futures-io", "tokio"] }
|
||||
toml = "0.8"
|
||||
toml_edit = { version = "0.22", default-features = false, features = ["display", "parse", "serde"] }
|
||||
tower-http = "0.4.4"
|
||||
tree-sitter = { version = "0.26", features = ["wasm"] }
|
||||
tree-sitter-bash = "0.25.1"
|
||||
tree-sitter-c = "0.23"
|
||||
tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev = "5cb9b693cfd7bfacab1d9ff4acac1a4150700609" }
|
||||
tree-sitter-css = "0.23"
|
||||
tree-sitter-diff = "0.1.0"
|
||||
tree-sitter-elixir = "0.3"
|
||||
tree-sitter-embedded-template = "0.23.0"
|
||||
tree-sitter-gitcommit = { git = "https://github.com/zed-industries/tree-sitter-git-commit", rev = "88309716a69dd13ab83443721ba6e0b491d37ee9" }
|
||||
tree-sitter-go = "0.23"
|
||||
tree-sitter-go-mod = { git = "https://github.com/camdencheek/tree-sitter-go-mod", rev = "2e886870578eeba1927a2dc4bd2e2b3f598c5f9a", package = "tree-sitter-gomod" }
|
||||
tree-sitter-gowork = { git = "https://github.com/zed-industries/tree-sitter-go-work", rev = "acb0617bf7f4fda02c6217676cc64acb89536dc7" }
|
||||
tree-sitter-heex = { git = "https://github.com/zed-industries/tree-sitter-heex", rev = "1dd45142fbb05562e35b2040c6129c9bca346592" }
|
||||
tree-sitter-html = "0.23"
|
||||
tree-sitter-jsdoc = "0.23"
|
||||
tree-sitter-json = "0.24"
|
||||
tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", rev = "9a23c1a96c0513d8fc6520972beedd419a973539" }
|
||||
tree-sitter-python = "0.25"
|
||||
tree-sitter-regex = "0.24"
|
||||
tree-sitter-ruby = "0.23"
|
||||
tree-sitter-rust = "0.24"
|
||||
tree-sitter-typescript = { git = "https://github.com/zed-industries/tree-sitter-typescript", rev = "e2c53597d6a5d9cf7bbe8dccde576fe1e46c5899" } # https://github.com/tree-sitter/tree-sitter-typescript/pull/347
|
||||
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "baff0b51c64ef6a1fb1f8390f3ad6015b83ec13a" }
|
||||
tracing = "0.1.40"
|
||||
unicase = "2.6"
|
||||
unicode-script = "0.5.7"
|
||||
unicode-segmentation = "1.10"
|
||||
unindent = "0.2.0"
|
||||
url = "2.2"
|
||||
urlencoding = "2.1.2"
|
||||
uuid = { version = "1.1.2", features = ["v4", "v5", "v7", "serde"] }
|
||||
walkdir = "2.5"
|
||||
wasm-encoder = "0.221"
|
||||
wasmparser = "0.221"
|
||||
wasmtime = { version = "33", default-features = false, features = [
|
||||
"async",
|
||||
"demangle",
|
||||
"runtime",
|
||||
"cranelift",
|
||||
"component-model",
|
||||
"incremental-cache",
|
||||
"parallel-compilation",
|
||||
] }
|
||||
wasmtime-wasi = "33"
|
||||
wax = "0.6"
|
||||
which = "6.0.0"
|
||||
windows-core = "0.61"
|
||||
yawc = "0.2.5"
|
||||
zeroize = "1.8"
|
||||
zstd = "0.11"
|
||||
|
||||
|
||||
[workspace.dependencies.windows]
|
||||
version = "0.61"
|
||||
@@ -770,12 +58,6 @@ features = [
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
notify = { git = "https://github.com/zed-industries/notify.git", rev = "b4588b2e5aee68f4c0e100f140e808cbce7b1419" }
|
||||
notify-types = { git = "https://github.com/zed-industries/notify.git", rev = "b4588b2e5aee68f4c0e100f140e808cbce7b1419" }
|
||||
windows-capture = { git = "https://github.com/zed-industries/windows-capture.git", rev = "f0d6c1b6691db75461b732f6d5ff56eed002eeb9" }
|
||||
calloop = { git = "https://github.com/zed-industries/calloop" }
|
||||
|
||||
[profile.dev]
|
||||
split-debuginfo = "unpacked"
|
||||
# https://github.com/rust-lang/cargo/issues/16104
|
||||
@@ -897,13 +179,157 @@ large_enum_variant = "allow"
|
||||
# Boolean expressions can be hard to read, requiring only the minimal form gets in the way
|
||||
nonminimal_bool = "allow"
|
||||
|
||||
[workspace.metadata.cargo-machete]
|
||||
ignored = [
|
||||
"bindgen",
|
||||
"cbindgen",
|
||||
"prost_build",
|
||||
[workspace.dependencies]
|
||||
anyhow = "1.0.86"
|
||||
ashpd = { version = "0.11", default-features = false, features = ["async-std"] }
|
||||
askpass = { path = "crates/askpass" }
|
||||
assets = { path = "crates/assets" }
|
||||
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
||||
async-fs = "2.1"
|
||||
async-tar = "0.5.1"
|
||||
async-task = "4.7"
|
||||
async-trait = "0.1"
|
||||
async_zip = { version = "0.0.18", features = ["deflate", "deflate64"] }
|
||||
backtrace = "0.3"
|
||||
bitflags = "2.6.0"
|
||||
blade-graphics = { version = "0.7.0" }
|
||||
blade-macros = { version = "0.3.0" }
|
||||
blade-util = { version = "0.3.0" }
|
||||
bytes = "1.0"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
circular-buffer = "1.0"
|
||||
clock = { path = "crates/clock" }
|
||||
cocoa = "=0.26.0"
|
||||
cocoa-foundation = "=0.2.0"
|
||||
collections = { path = "crates/collections", version = "0.1.0" }
|
||||
convert_case = "0.8.0"
|
||||
core-foundation = "=0.10.0"
|
||||
core-foundation-sys = "0.8.6"
|
||||
core-video = { version = "0.4.3", features = ["metal"] }
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
ctor = "0.4.0"
|
||||
derive_more = "0.99.17"
|
||||
derive_refineable = { path = "crates/refineable/derive_refineable" }
|
||||
dirs = "4.0"
|
||||
ec4rs = "1.1"
|
||||
env_logger = "0.11"
|
||||
fs = { path = "crates/fs" }
|
||||
fsevent = { path = "crates/fsevent" }
|
||||
futures = "0.3"
|
||||
futures-lite = "1.13"
|
||||
git = { path = "crates/git" }
|
||||
git2 = { version = "0.20.1", default-features = false }
|
||||
globset = "0.4"
|
||||
gpui = { path = "crates/gpui", default-features = false }
|
||||
gpui_macros = { path = "crates/gpui_macros" }
|
||||
heck = "0.5"
|
||||
http = "1.1"
|
||||
http-body = "1.0"
|
||||
http_client = { path = "crates/http_client" }
|
||||
http_client_tls = { path = "crates/http_client_tls" }
|
||||
icons = { path = "crates/icons" }
|
||||
ignore = "0.4.22"
|
||||
image = "0.25.1"
|
||||
indexmap = { version = "2.7.0", features = ["serde"] }
|
||||
indoc = "2"
|
||||
inventory = "0.3.19"
|
||||
itertools = "0.14.0"
|
||||
libc = "0.2"
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
|
||||
mach2 = "0.5"
|
||||
media = { path = "crates/media" }
|
||||
metal = "0.29"
|
||||
migrator = { path = "crates/migrator" }
|
||||
naga = { version = "25.0", features = ["wgsl-in"] }
|
||||
net = { path = "crates/net" }
|
||||
nix = "0.29"
|
||||
objc = "0.2"
|
||||
palette = { version = "0.7.5", default-features = false, features = ["std"] }
|
||||
parking_lot = "0.12.1"
|
||||
paths = { path = "crates/paths" }
|
||||
perf = { path = "tooling/perf" }
|
||||
postage = { version = "0.5", features = ["futures-traits"] }
|
||||
pretty_assertions = { version = "1.3.0", features = ["unstable"] }
|
||||
proc-macro2 = "1.0.93"
|
||||
profiling = "1"
|
||||
prost = "0.9"
|
||||
prost-build = "0.9"
|
||||
proto = { path = "crates/proto" }
|
||||
quote = "1.0.9"
|
||||
rand = "0.9"
|
||||
rayon = "1.8"
|
||||
refineable = { path = "crates/refineable" }
|
||||
regex = "1.5"
|
||||
release_channel = { path = "crates/release_channel" }
|
||||
reqwest = { git = "https://github.com/zed-industries/reqwest.git", rev = "c15662463bda39148ba154100dd44d3fba5873a4", default-features = false, features = [
|
||||
"charset",
|
||||
"http2",
|
||||
"macos-system-configuration",
|
||||
"multipart",
|
||||
"rustls-tls-native-roots",
|
||||
"socks",
|
||||
"stream",
|
||||
], package = "zed-reqwest", version = "0.12.15-zed" }
|
||||
reqwest_client = { path = "crates/reqwest_client" }
|
||||
rope = { path = "crates/rope" }
|
||||
rust-embed = { version = "8.4", features = ["include-exclude"] }
|
||||
rustc-hash = "2.1.0"
|
||||
rustls = { version = "0.23.26" }
|
||||
rustls-platform-verifier = "0.5.0"
|
||||
scap = { git = "https://github.com/zed-industries/scap", rev = "4afea48c3b002197176fb19cd0f9b180dd36eaac", default-features = false, package = "zed-scap", version = "0.0.8-zed" }
|
||||
schemars = { version = "1.0", features = ["indexmap2"] }
|
||||
semver = { version = "1.0", features = ["serde"] }
|
||||
serde = { version = "1.0.221", features = ["derive", "rc"] }
|
||||
serde_json = { version = "1.0.144", features = ["preserve_order", "raw_value"] }
|
||||
serde_json_lenient = { version = "0.2", features = [
|
||||
"preserve_order",
|
||||
"raw_value",
|
||||
] }
|
||||
serde_path_to_error = "0.1.17"
|
||||
serde_repr = "0.1"
|
||||
serde_urlencoded = "0.7"
|
||||
settings = { path = "crates/settings" }
|
||||
settings_json = { path = "crates/settings_json" }
|
||||
settings_macros = { path = "crates/settings_macros" }
|
||||
sha2 = "0.10"
|
||||
shlex = "1.3.0"
|
||||
slotmap = "1.0.6"
|
||||
smallvec = { version = "1.6", features = ["union", "const_new"] }
|
||||
smol = "2.0"
|
||||
stacksafe = "0.1"
|
||||
streaming-iterator = "0.1"
|
||||
strum = { version = "0.27.2", features = ["derive"] }
|
||||
sum_tree = { path = "crates/sum_tree" }
|
||||
syn = { version = "2.0.101", features = ["full", "extra-traits", "visit-mut"] }
|
||||
take-until = "0.2.0"
|
||||
tempfile = "3.20.0"
|
||||
text = { path = "crates/text" }
|
||||
theme = { path = "crates/theme" }
|
||||
thiserror = "2.0.12"
|
||||
time = { version = "0.3", features = [
|
||||
"macros",
|
||||
"parsing",
|
||||
"serde",
|
||||
"component",
|
||||
"documented",
|
||||
"sea-orm-macros",
|
||||
]
|
||||
"serde-well-known",
|
||||
"formatting",
|
||||
"local-offset",
|
||||
] }
|
||||
tokio = { version = "1" }
|
||||
tracing = "0.1.40"
|
||||
tree-sitter = { version = "0.26", features = ["wasm"] }
|
||||
tree-sitter-json = "0.24"
|
||||
unicase = "2.6"
|
||||
unicode-segmentation = "1.10"
|
||||
unindent = "0.2.0"
|
||||
url = "2.2"
|
||||
urlencoding = "2.1.2"
|
||||
util = { path = "crates/util" }
|
||||
util_macros = { path = "crates/util_macros" }
|
||||
uuid = { version = "1.1.2", features = ["v4", "v5", "v7", "serde"] }
|
||||
walkdir = "2.5"
|
||||
which = "6.0.0"
|
||||
windows-core = "0.61"
|
||||
zeroize = "1.8"
|
||||
zlog = { path = "crates/zlog" }
|
||||
ztracing = { path = "crates/ztracing" }
|
||||
ztracing_macro = { path = "crates/ztracing_macro" }
|
||||
|
||||
909
Cargo.toml.full
Normal file
909
Cargo.toml.full
Normal file
@@ -0,0 +1,909 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"crates/acp_tools",
|
||||
"crates/acp_thread",
|
||||
"crates/action_log",
|
||||
"crates/activity_indicator",
|
||||
"crates/agent",
|
||||
"crates/agent_servers",
|
||||
"crates/agent_settings",
|
||||
"crates/agent_ui",
|
||||
"crates/agent_ui_v2",
|
||||
"crates/ai_onboarding",
|
||||
"crates/anthropic",
|
||||
"crates/askpass",
|
||||
"crates/assets",
|
||||
"crates/assistant_text_thread",
|
||||
"crates/assistant_slash_command",
|
||||
"crates/assistant_slash_commands",
|
||||
"crates/audio",
|
||||
"crates/auto_update",
|
||||
"crates/auto_update_helper",
|
||||
"crates/auto_update_ui",
|
||||
"crates/aws_http_client",
|
||||
"crates/bedrock",
|
||||
"crates/breadcrumbs",
|
||||
"crates/buffer_diff",
|
||||
"crates/call",
|
||||
"crates/channel",
|
||||
"crates/cli",
|
||||
"crates/client",
|
||||
"crates/clock",
|
||||
"crates/cloud_api_client",
|
||||
"crates/cloud_api_types",
|
||||
"crates/cloud_llm_client",
|
||||
"crates/collab",
|
||||
"crates/collab_ui",
|
||||
"crates/collections",
|
||||
"crates/command_palette",
|
||||
"crates/command_palette_hooks",
|
||||
"crates/component",
|
||||
"crates/context_server",
|
||||
"crates/copilot",
|
||||
"crates/crashes",
|
||||
"crates/credentials_provider",
|
||||
"crates/dap",
|
||||
"crates/dap_adapters",
|
||||
"crates/db",
|
||||
"crates/debug_adapter_extension",
|
||||
"crates/debugger_tools",
|
||||
"crates/debugger_ui",
|
||||
"crates/deepseek",
|
||||
"crates/denoise",
|
||||
"crates/diagnostics",
|
||||
"crates/docs_preprocessor",
|
||||
"crates/edit_prediction",
|
||||
"crates/edit_prediction_types",
|
||||
"crates/edit_prediction_ui",
|
||||
"crates/edit_prediction_context",
|
||||
"crates/editor",
|
||||
"crates/eval",
|
||||
"crates/eval_utils",
|
||||
"crates/explorer_command_injector",
|
||||
"crates/extension",
|
||||
"crates/extension_api",
|
||||
"crates/extension_cli",
|
||||
"crates/extension_host",
|
||||
"crates/extensions_ui",
|
||||
"crates/feature_flags",
|
||||
"crates/feedback",
|
||||
"crates/file_finder",
|
||||
"crates/file_icons",
|
||||
"crates/fs",
|
||||
"crates/fs_benchmarks",
|
||||
"crates/fsevent",
|
||||
"crates/fuzzy",
|
||||
"crates/git",
|
||||
"crates/git_hosting_providers",
|
||||
"crates/git_ui",
|
||||
"crates/go_to_line",
|
||||
"crates/google_ai",
|
||||
"crates/gpui",
|
||||
"crates/gpui_macros",
|
||||
"crates/gpui_tokio",
|
||||
"crates/html_to_markdown",
|
||||
"crates/http_client",
|
||||
"crates/http_client_tls",
|
||||
"crates/icons",
|
||||
"crates/image_viewer",
|
||||
"crates/inspector_ui",
|
||||
"crates/install_cli",
|
||||
"crates/journal",
|
||||
"crates/json_schema_store",
|
||||
"crates/keymap_editor",
|
||||
"crates/language",
|
||||
"crates/language_extension",
|
||||
"crates/language_model",
|
||||
"crates/language_models",
|
||||
"crates/language_onboarding",
|
||||
"crates/language_selector",
|
||||
"crates/language_tools",
|
||||
"crates/languages",
|
||||
"crates/line_ending_selector",
|
||||
"crates/livekit_api",
|
||||
"crates/livekit_client",
|
||||
"crates/lmstudio",
|
||||
"crates/lsp",
|
||||
"crates/markdown",
|
||||
"crates/markdown_preview",
|
||||
"crates/media",
|
||||
"crates/menu",
|
||||
"crates/migrator",
|
||||
"crates/mistral",
|
||||
"crates/miniprofiler_ui",
|
||||
"crates/multi_buffer",
|
||||
"crates/nc",
|
||||
"crates/net",
|
||||
"crates/node_runtime",
|
||||
"crates/notifications",
|
||||
"crates/ollama",
|
||||
"crates/onboarding",
|
||||
"crates/open_ai",
|
||||
"crates/open_router",
|
||||
"crates/outline",
|
||||
"crates/outline_panel",
|
||||
"crates/panel",
|
||||
"crates/paths",
|
||||
"crates/picker",
|
||||
"crates/prettier",
|
||||
"crates/project",
|
||||
"crates/project_benchmarks",
|
||||
"crates/project_panel",
|
||||
"crates/project_symbols",
|
||||
"crates/prompt_store",
|
||||
"crates/proto",
|
||||
"crates/recent_projects",
|
||||
"crates/refineable",
|
||||
"crates/refineable/derive_refineable",
|
||||
"crates/release_channel",
|
||||
"crates/scheduler",
|
||||
"crates/remote",
|
||||
"crates/remote_server",
|
||||
"crates/repl",
|
||||
"crates/reqwest_client",
|
||||
"crates/rich_text",
|
||||
"crates/rope",
|
||||
"crates/rpc",
|
||||
"crates/rules_library",
|
||||
"crates/schema_generator",
|
||||
"crates/search",
|
||||
"crates/session",
|
||||
"crates/settings",
|
||||
"crates/settings_json",
|
||||
"crates/settings_macros",
|
||||
"crates/settings_profile_selector",
|
||||
"crates/settings_ui",
|
||||
"crates/snippet",
|
||||
"crates/snippet_provider",
|
||||
"crates/snippets_ui",
|
||||
"crates/sqlez",
|
||||
"crates/sqlez_macros",
|
||||
"crates/story",
|
||||
"crates/storybook",
|
||||
"crates/streaming_diff",
|
||||
"crates/sum_tree",
|
||||
"crates/supermaven",
|
||||
"crates/supermaven_api",
|
||||
"crates/codestral",
|
||||
"crates/svg_preview",
|
||||
"crates/system_specs",
|
||||
"crates/tab_switcher",
|
||||
"crates/task",
|
||||
"crates/tasks_ui",
|
||||
"crates/telemetry",
|
||||
"crates/telemetry_events",
|
||||
"crates/terminal",
|
||||
"crates/terminal_view",
|
||||
"crates/text",
|
||||
"crates/theme",
|
||||
"crates/theme_extension",
|
||||
"crates/theme_importer",
|
||||
"crates/theme_selector",
|
||||
"crates/time_format",
|
||||
"crates/title_bar",
|
||||
"crates/toolchain_selector",
|
||||
"crates/ui",
|
||||
"crates/ui_input",
|
||||
"crates/ui_macros",
|
||||
"crates/ui_prompt",
|
||||
"crates/util",
|
||||
"crates/util_macros",
|
||||
"crates/vercel",
|
||||
"crates/vim",
|
||||
"crates/vim_mode_setting",
|
||||
"crates/which_key",
|
||||
"crates/watch",
|
||||
"crates/web_search",
|
||||
"crates/web_search_providers",
|
||||
"crates/workspace",
|
||||
"crates/worktree",
|
||||
"crates/x_ai",
|
||||
"crates/zed",
|
||||
"crates/zed_actions",
|
||||
"crates/zed_env_vars",
|
||||
"crates/edit_prediction_cli",
|
||||
"crates/zeta_prompt",
|
||||
"crates/zlog",
|
||||
"crates/zlog_settings",
|
||||
"crates/ztracing",
|
||||
"crates/ztracing_macro",
|
||||
|
||||
#
|
||||
# Extensions
|
||||
#
|
||||
|
||||
"extensions/glsl",
|
||||
"extensions/html",
|
||||
"extensions/proto",
|
||||
"extensions/slash-commands-example",
|
||||
"extensions/test-extension",
|
||||
|
||||
#
|
||||
# Tooling
|
||||
#
|
||||
|
||||
"tooling/perf",
|
||||
"tooling/xtask",
|
||||
]
|
||||
default-members = ["crates/zed"]
|
||||
|
||||
[workspace.package]
|
||||
publish = false
|
||||
edition = "2024"
|
||||
|
||||
[workspace.dependencies]
|
||||
|
||||
#
|
||||
# Workspace member crates
|
||||
#
|
||||
|
||||
acp_tools = { path = "crates/acp_tools" }
|
||||
acp_thread = { path = "crates/acp_thread" }
|
||||
action_log = { path = "crates/action_log" }
|
||||
agent = { path = "crates/agent" }
|
||||
activity_indicator = { path = "crates/activity_indicator" }
|
||||
agent_ui = { path = "crates/agent_ui" }
|
||||
agent_ui_v2 = { path = "crates/agent_ui_v2" }
|
||||
agent_settings = { path = "crates/agent_settings" }
|
||||
agent_servers = { path = "crates/agent_servers" }
|
||||
ai_onboarding = { path = "crates/ai_onboarding" }
|
||||
anthropic = { path = "crates/anthropic" }
|
||||
askpass = { path = "crates/askpass" }
|
||||
assets = { path = "crates/assets" }
|
||||
assistant_text_thread = { path = "crates/assistant_text_thread" }
|
||||
assistant_slash_command = { path = "crates/assistant_slash_command" }
|
||||
assistant_slash_commands = { path = "crates/assistant_slash_commands" }
|
||||
audio = { path = "crates/audio" }
|
||||
auto_update = { path = "crates/auto_update" }
|
||||
auto_update_ui = { path = "crates/auto_update_ui" }
|
||||
aws_http_client = { path = "crates/aws_http_client" }
|
||||
bedrock = { path = "crates/bedrock" }
|
||||
breadcrumbs = { path = "crates/breadcrumbs" }
|
||||
buffer_diff = { path = "crates/buffer_diff" }
|
||||
call = { path = "crates/call" }
|
||||
channel = { path = "crates/channel" }
|
||||
cli = { path = "crates/cli" }
|
||||
client = { path = "crates/client" }
|
||||
clock = { path = "crates/clock" }
|
||||
cloud_api_client = { path = "crates/cloud_api_client" }
|
||||
cloud_api_types = { path = "crates/cloud_api_types" }
|
||||
cloud_llm_client = { path = "crates/cloud_llm_client" }
|
||||
collab_ui = { path = "crates/collab_ui" }
|
||||
collections = { path = "crates/collections", version = "0.1.0" }
|
||||
command_palette = { path = "crates/command_palette" }
|
||||
command_palette_hooks = { path = "crates/command_palette_hooks" }
|
||||
component = { path = "crates/component" }
|
||||
context_server = { path = "crates/context_server" }
|
||||
copilot = { path = "crates/copilot" }
|
||||
crashes = { path = "crates/crashes" }
|
||||
credentials_provider = { path = "crates/credentials_provider" }
|
||||
crossbeam = "0.8.4"
|
||||
dap = { path = "crates/dap" }
|
||||
dap_adapters = { path = "crates/dap_adapters" }
|
||||
db = { path = "crates/db" }
|
||||
debug_adapter_extension = { path = "crates/debug_adapter_extension" }
|
||||
debugger_tools = { path = "crates/debugger_tools" }
|
||||
debugger_ui = { path = "crates/debugger_ui" }
|
||||
deepseek = { path = "crates/deepseek" }
|
||||
derive_refineable = { path = "crates/refineable/derive_refineable" }
|
||||
diagnostics = { path = "crates/diagnostics" }
|
||||
editor = { path = "crates/editor" }
|
||||
eval_utils = { path = "crates/eval_utils" }
|
||||
extension = { path = "crates/extension" }
|
||||
extension_host = { path = "crates/extension_host" }
|
||||
extensions_ui = { path = "crates/extensions_ui" }
|
||||
feature_flags = { path = "crates/feature_flags" }
|
||||
feedback = { path = "crates/feedback" }
|
||||
file_finder = { path = "crates/file_finder" }
|
||||
file_icons = { path = "crates/file_icons" }
|
||||
fs = { path = "crates/fs" }
|
||||
fsevent = { path = "crates/fsevent" }
|
||||
fuzzy = { path = "crates/fuzzy" }
|
||||
git = { path = "crates/git" }
|
||||
git_hosting_providers = { path = "crates/git_hosting_providers" }
|
||||
git_ui = { path = "crates/git_ui" }
|
||||
go_to_line = { path = "crates/go_to_line" }
|
||||
google_ai = { path = "crates/google_ai" }
|
||||
gpui = { path = "crates/gpui", default-features = false }
|
||||
gpui_macros = { path = "crates/gpui_macros" }
|
||||
gpui_tokio = { path = "crates/gpui_tokio" }
|
||||
html_to_markdown = { path = "crates/html_to_markdown" }
|
||||
http_client = { path = "crates/http_client" }
|
||||
http_client_tls = { path = "crates/http_client_tls" }
|
||||
icons = { path = "crates/icons" }
|
||||
image_viewer = { path = "crates/image_viewer" }
|
||||
edit_prediction_types = { path = "crates/edit_prediction_types" }
|
||||
edit_prediction_ui = { path = "crates/edit_prediction_ui" }
|
||||
edit_prediction_context = { path = "crates/edit_prediction_context" }
|
||||
inspector_ui = { path = "crates/inspector_ui" }
|
||||
install_cli = { path = "crates/install_cli" }
|
||||
journal = { path = "crates/journal" }
|
||||
json_schema_store = { path = "crates/json_schema_store" }
|
||||
keymap_editor = { path = "crates/keymap_editor" }
|
||||
language = { path = "crates/language" }
|
||||
language_extension = { path = "crates/language_extension" }
|
||||
language_model = { path = "crates/language_model" }
|
||||
language_models = { path = "crates/language_models" }
|
||||
language_onboarding = { path = "crates/language_onboarding" }
|
||||
language_selector = { path = "crates/language_selector" }
|
||||
language_tools = { path = "crates/language_tools" }
|
||||
languages = { path = "crates/languages" }
|
||||
line_ending_selector = { path = "crates/line_ending_selector" }
|
||||
livekit_api = { path = "crates/livekit_api" }
|
||||
livekit_client = { path = "crates/livekit_client" }
|
||||
lmstudio = { path = "crates/lmstudio" }
|
||||
lsp = { path = "crates/lsp" }
|
||||
markdown = { path = "crates/markdown" }
|
||||
markdown_preview = { path = "crates/markdown_preview" }
|
||||
svg_preview = { path = "crates/svg_preview" }
|
||||
media = { path = "crates/media" }
|
||||
menu = { path = "crates/menu" }
|
||||
migrator = { path = "crates/migrator" }
|
||||
mistral = { path = "crates/mistral" }
|
||||
multi_buffer = { path = "crates/multi_buffer" }
|
||||
miniprofiler_ui = { path = "crates/miniprofiler_ui" }
|
||||
nc = { path = "crates/nc" }
|
||||
net = { path = "crates/net" }
|
||||
node_runtime = { path = "crates/node_runtime" }
|
||||
notifications = { path = "crates/notifications" }
|
||||
ollama = { path = "crates/ollama" }
|
||||
onboarding = { path = "crates/onboarding" }
|
||||
open_ai = { path = "crates/open_ai" }
|
||||
open_router = { path = "crates/open_router", features = ["schemars"] }
|
||||
outline = { path = "crates/outline" }
|
||||
outline_panel = { path = "crates/outline_panel" }
|
||||
panel = { path = "crates/panel" }
|
||||
paths = { path = "crates/paths" }
|
||||
perf = { path = "tooling/perf" }
|
||||
picker = { path = "crates/picker" }
|
||||
prettier = { path = "crates/prettier" }
|
||||
settings_profile_selector = { path = "crates/settings_profile_selector" }
|
||||
project = { path = "crates/project" }
|
||||
project_panel = { path = "crates/project_panel" }
|
||||
project_symbols = { path = "crates/project_symbols" }
|
||||
prompt_store = { path = "crates/prompt_store" }
|
||||
proto = { path = "crates/proto" }
|
||||
recent_projects = { path = "crates/recent_projects" }
|
||||
refineable = { path = "crates/refineable" }
|
||||
release_channel = { path = "crates/release_channel" }
|
||||
remote = { path = "crates/remote" }
|
||||
remote_server = { path = "crates/remote_server" }
|
||||
repl = { path = "crates/repl" }
|
||||
reqwest_client = { path = "crates/reqwest_client" }
|
||||
rodio = { git = "https://github.com/RustAudio/rodio", rev ="e2074c6c2acf07b57cf717e076bdda7a9ac6e70b", features = ["wav", "playback", "wav_output", "recording"] }
|
||||
rope = { path = "crates/rope" }
|
||||
rpc = { path = "crates/rpc" }
|
||||
rules_library = { path = "crates/rules_library" }
|
||||
search = { path = "crates/search" }
|
||||
session = { path = "crates/session" }
|
||||
settings = { path = "crates/settings" }
|
||||
settings_json = { path = "crates/settings_json" }
|
||||
settings_macros = { path = "crates/settings_macros" }
|
||||
settings_ui = { path = "crates/settings_ui" }
|
||||
snippet = { path = "crates/snippet" }
|
||||
snippet_provider = { path = "crates/snippet_provider" }
|
||||
snippets_ui = { path = "crates/snippets_ui" }
|
||||
sqlez = { path = "crates/sqlez" }
|
||||
sqlez_macros = { path = "crates/sqlez_macros" }
|
||||
story = { path = "crates/story" }
|
||||
streaming_diff = { path = "crates/streaming_diff" }
|
||||
sum_tree = { path = "crates/sum_tree" }
|
||||
supermaven = { path = "crates/supermaven" }
|
||||
supermaven_api = { path = "crates/supermaven_api" }
|
||||
codestral = { path = "crates/codestral" }
|
||||
system_specs = { path = "crates/system_specs" }
|
||||
tab_switcher = { path = "crates/tab_switcher" }
|
||||
task = { path = "crates/task" }
|
||||
tasks_ui = { path = "crates/tasks_ui" }
|
||||
telemetry = { path = "crates/telemetry" }
|
||||
telemetry_events = { path = "crates/telemetry_events" }
|
||||
terminal = { path = "crates/terminal" }
|
||||
terminal_view = { path = "crates/terminal_view" }
|
||||
text = { path = "crates/text" }
|
||||
theme = { path = "crates/theme" }
|
||||
theme_extension = { path = "crates/theme_extension" }
|
||||
theme_selector = { path = "crates/theme_selector" }
|
||||
time_format = { path = "crates/time_format" }
|
||||
title_bar = { path = "crates/title_bar" }
|
||||
toolchain_selector = { path = "crates/toolchain_selector" }
|
||||
ui = { path = "crates/ui" }
|
||||
ui_input = { path = "crates/ui_input" }
|
||||
ui_macros = { path = "crates/ui_macros" }
|
||||
ui_prompt = { path = "crates/ui_prompt" }
|
||||
util = { path = "crates/util" }
|
||||
util_macros = { path = "crates/util_macros" }
|
||||
vercel = { path = "crates/vercel" }
|
||||
vim = { path = "crates/vim" }
|
||||
vim_mode_setting = { path = "crates/vim_mode_setting" }
|
||||
which_key = { path = "crates/which_key" }
|
||||
|
||||
watch = { path = "crates/watch" }
|
||||
web_search = { path = "crates/web_search" }
|
||||
web_search_providers = { path = "crates/web_search_providers" }
|
||||
workspace = { path = "crates/workspace" }
|
||||
worktree = { path = "crates/worktree" }
|
||||
x_ai = { path = "crates/x_ai" }
|
||||
zed = { path = "crates/zed" }
|
||||
zed_actions = { path = "crates/zed_actions" }
|
||||
zed_env_vars = { path = "crates/zed_env_vars" }
|
||||
edit_prediction = { path = "crates/edit_prediction" }
|
||||
zeta_prompt = { path = "crates/zeta_prompt" }
|
||||
zlog = { path = "crates/zlog" }
|
||||
zlog_settings = { path = "crates/zlog_settings" }
|
||||
ztracing = { path = "crates/ztracing" }
|
||||
ztracing_macro = { path = "crates/ztracing_macro" }
|
||||
|
||||
#
|
||||
# External crates
|
||||
#
|
||||
|
||||
agent-client-protocol = { version = "=0.9.2", features = ["unstable"] }
|
||||
aho-corasick = "1.1"
|
||||
alacritty_terminal = "0.25.1-rc1"
|
||||
any_vec = "0.14"
|
||||
anyhow = "1.0.86"
|
||||
arrayvec = { version = "0.7.4", features = ["serde"] }
|
||||
ashpd = { version = "0.11", default-features = false, features = ["async-std"] }
|
||||
async-compat = "0.2.1"
|
||||
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
||||
async-dispatcher = "0.1"
|
||||
async-fs = "2.1"
|
||||
async-lock = "2.1"
|
||||
async-pipe = { git = "https://github.com/zed-industries/async-pipe-rs", rev = "82d00a04211cf4e1236029aa03e6b6ce2a74c553" }
|
||||
async-recursion = "1.0.0"
|
||||
async-tar = "0.5.1"
|
||||
async-task = "4.7"
|
||||
async-trait = "0.1"
|
||||
async-tungstenite = "0.31.0"
|
||||
async_zip = { version = "0.0.18", features = ["deflate", "deflate64"] }
|
||||
aws-config = { version = "1.8.10", features = ["behavior-version-latest"] }
|
||||
aws-credential-types = { version = "1.2.8", features = [
|
||||
"hardcoded-credentials",
|
||||
] }
|
||||
aws-sdk-bedrockruntime = { version = "1.112.0", features = [
|
||||
"behavior-version-latest",
|
||||
] }
|
||||
aws-smithy-runtime-api = { version = "1.9.2", features = ["http-1x", "client"] }
|
||||
aws-smithy-types = { version = "1.3.4", features = ["http-body-1-x"] }
|
||||
backtrace = "0.3"
|
||||
base64 = "0.22"
|
||||
bincode = "1.2.1"
|
||||
bitflags = "2.6.0"
|
||||
blade-graphics = { version = "0.7.0" }
|
||||
blade-macros = { version = "0.3.0" }
|
||||
blade-util = { version = "0.3.0" }
|
||||
brotli = "8.0.2"
|
||||
bytes = "1.0"
|
||||
cargo_metadata = "0.19"
|
||||
cargo_toml = "0.21"
|
||||
cfg-if = "1.0.3"
|
||||
chardetng = "0.1"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
ciborium = "0.2"
|
||||
circular-buffer = "1.0"
|
||||
clap = { version = "4.4", features = ["derive", "wrap_help"] }
|
||||
cocoa = "=0.26.0"
|
||||
cocoa-foundation = "=0.2.0"
|
||||
convert_case = "0.8.0"
|
||||
core-foundation = "=0.10.0"
|
||||
core-foundation-sys = "0.8.6"
|
||||
core-video = { version = "0.4.3", features = ["metal"] }
|
||||
cpal = "0.16"
|
||||
crash-handler = "0.6"
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
ctor = "0.4.0"
|
||||
dap-types = { git = "https://github.com/zed-industries/dap-types", rev = "1b461b310481d01e02b2603c16d7144b926339f8" }
|
||||
dashmap = "6.0"
|
||||
derive_more = "0.99.17"
|
||||
dirs = "4.0"
|
||||
documented = "0.9.1"
|
||||
dotenvy = "0.15.0"
|
||||
ec4rs = "1.1"
|
||||
emojis = "0.6.1"
|
||||
env_logger = "0.11"
|
||||
encoding_rs = "0.8"
|
||||
exec = "0.3.1"
|
||||
fancy-regex = "0.16.0"
|
||||
fork = "0.4.0"
|
||||
futures = "0.3"
|
||||
futures-lite = "1.13"
|
||||
gh-workflow = { git = "https://github.com/zed-industries/gh-workflow", rev = "09acfdf2bd5c1d6254abefd609c808ff73547b2c" }
|
||||
git2 = { version = "0.20.1", default-features = false }
|
||||
globset = "0.4"
|
||||
handlebars = "4.3"
|
||||
heck = "0.5"
|
||||
heed = { version = "0.21.0", features = ["read-txn-no-tls"] }
|
||||
hex = "0.4.3"
|
||||
human_bytes = "0.4.1"
|
||||
html5ever = "0.27.0"
|
||||
http = "1.1"
|
||||
http-body = "1.0"
|
||||
hyper = "0.14"
|
||||
ignore = "0.4.22"
|
||||
image = "0.25.1"
|
||||
imara-diff = "0.1.8"
|
||||
indexmap = { version = "2.7.0", features = ["serde"] }
|
||||
indoc = "2"
|
||||
inventory = "0.3.19"
|
||||
itertools = "0.14.0"
|
||||
json_dotpath = "1.1"
|
||||
jsonschema = "0.37.0"
|
||||
jsonwebtoken = "9.3"
|
||||
jupyter-protocol = "0.10.0"
|
||||
jupyter-websocket-client = "0.15.0"
|
||||
libc = "0.2"
|
||||
libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
|
||||
linkify = "0.10.0"
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
|
||||
lsp-types = { git = "https://github.com/zed-industries/lsp-types", rev = "b71ab4eeb27d9758be8092020a46fe33fbca4e33" }
|
||||
mach2 = "0.5"
|
||||
markup5ever_rcdom = "0.3.0"
|
||||
metal = "0.29"
|
||||
minidumper = "0.8"
|
||||
moka = { version = "0.12.10", features = ["sync"] }
|
||||
naga = { version = "25.0", features = ["wgsl-in"] }
|
||||
nanoid = "0.4"
|
||||
nbformat = "0.15.0"
|
||||
nix = "0.29"
|
||||
num-format = "0.4.4"
|
||||
objc = "0.2"
|
||||
objc2-foundation = { version = "=0.3.1", default-features = false, features = [
|
||||
"NSArray",
|
||||
"NSAttributedString",
|
||||
"NSBundle",
|
||||
"NSCoder",
|
||||
"NSData",
|
||||
"NSDate",
|
||||
"NSDictionary",
|
||||
"NSEnumerator",
|
||||
"NSError",
|
||||
"NSGeometry",
|
||||
"NSNotification",
|
||||
"NSNull",
|
||||
"NSObjCRuntime",
|
||||
"NSObject",
|
||||
"NSProcessInfo",
|
||||
"NSRange",
|
||||
"NSRunLoop",
|
||||
"NSString",
|
||||
"NSURL",
|
||||
"NSUndoManager",
|
||||
"NSValue",
|
||||
"objc2-core-foundation",
|
||||
"std"
|
||||
] }
|
||||
open = "5.0.0"
|
||||
ordered-float = "2.1.1"
|
||||
palette = { version = "0.7.5", default-features = false, features = ["std"] }
|
||||
parking_lot = "0.12.1"
|
||||
partial-json-fixer = "0.5.3"
|
||||
parse_int = "0.9"
|
||||
pciid-parser = "0.8.0"
|
||||
pathdiff = "0.2"
|
||||
pet = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-conda = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-core = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-fs = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
pet-virtualenv = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
|
||||
portable-pty = "0.9.0"
|
||||
postage = { version = "0.5", features = ["futures-traits"] }
|
||||
pretty_assertions = { version = "1.3.0", features = ["unstable"] }
|
||||
proc-macro2 = "1.0.93"
|
||||
profiling = "1"
|
||||
prost = "0.9"
|
||||
prost-build = "0.9"
|
||||
prost-types = "0.9"
|
||||
pulldown-cmark = { version = "0.12.0", default-features = false }
|
||||
quote = "1.0.9"
|
||||
rand = "0.9"
|
||||
rayon = "1.8"
|
||||
regex = "1.5"
|
||||
# WARNING: If you change this, you must also publish a new version of zed-reqwest to crates.io
|
||||
reqwest = { git = "https://github.com/zed-industries/reqwest.git", rev = "c15662463bda39148ba154100dd44d3fba5873a4", default-features = false, features = [
|
||||
"charset",
|
||||
"http2",
|
||||
"macos-system-configuration",
|
||||
"multipart",
|
||||
"rustls-tls-native-roots",
|
||||
"socks",
|
||||
"stream",
|
||||
], package = "zed-reqwest", version = "0.12.15-zed" }
|
||||
rsa = "0.9.6"
|
||||
runtimelib = { version = "0.30.0", default-features = false, features = [
|
||||
"async-dispatcher-runtime", "aws-lc-rs"
|
||||
] }
|
||||
rust-embed = { version = "8.4", features = ["include-exclude"] }
|
||||
rustc-hash = "2.1.0"
|
||||
rustls = { version = "0.23.26" }
|
||||
rustls-platform-verifier = "0.5.0"
|
||||
# WARNING: If you change this, you must also publish a new version of zed-scap to crates.io
|
||||
scap = { git = "https://github.com/zed-industries/scap", rev = "4afea48c3b002197176fb19cd0f9b180dd36eaac", default-features = false, package = "zed-scap", version = "0.0.8-zed" }
|
||||
schemars = { version = "1.0", features = ["indexmap2"] }
|
||||
semver = { version = "1.0", features = ["serde"] }
|
||||
serde = { version = "1.0.221", features = ["derive", "rc"] }
|
||||
serde_json = { version = "1.0.144", features = ["preserve_order", "raw_value"] }
|
||||
serde_json_lenient = { version = "0.2", features = [
|
||||
"preserve_order",
|
||||
"raw_value",
|
||||
] }
|
||||
serde_path_to_error = "0.1.17"
|
||||
serde_repr = "0.1"
|
||||
serde_urlencoded = "0.7"
|
||||
sha2 = "0.10"
|
||||
shellexpand = "2.1.0"
|
||||
shlex = "1.3.0"
|
||||
simplelog = "0.12.2"
|
||||
slotmap = "1.0.6"
|
||||
smallvec = { version = "1.6", features = ["union", "const_new"] }
|
||||
smol = "2.0"
|
||||
sqlformat = "0.2"
|
||||
stacksafe = "0.1"
|
||||
streaming-iterator = "0.1"
|
||||
strsim = "0.11"
|
||||
strum = { version = "0.27.2", features = ["derive"] }
|
||||
subtle = "2.5.0"
|
||||
syn = { version = "2.0.101", features = ["full", "extra-traits", "visit-mut"] }
|
||||
sys-locale = "0.3.1"
|
||||
sysinfo = "0.37.0"
|
||||
take-until = "0.2.0"
|
||||
tempfile = "3.20.0"
|
||||
thiserror = "2.0.12"
|
||||
tiktoken-rs = { git = "https://github.com/zed-industries/tiktoken-rs", rev = "2570c4387a8505fb8f1d3f3557454b474f1e8271" }
|
||||
time = { version = "0.3", features = [
|
||||
"macros",
|
||||
"parsing",
|
||||
"serde",
|
||||
"serde-well-known",
|
||||
"formatting",
|
||||
"local-offset",
|
||||
] }
|
||||
tiny_http = "0.8"
|
||||
tokio = { version = "1" }
|
||||
tokio-tungstenite = { version = "0.26", features = ["__rustls-tls"] }
|
||||
tokio-socks = { version = "0.5.2", default-features = false, features = ["futures-io", "tokio"] }
|
||||
toml = "0.8"
|
||||
toml_edit = { version = "0.22", default-features = false, features = ["display", "parse", "serde"] }
|
||||
tower-http = "0.4.4"
|
||||
tree-sitter = { version = "0.26", features = ["wasm"] }
|
||||
tree-sitter-bash = "0.25.1"
|
||||
tree-sitter-c = "0.23"
|
||||
tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev = "5cb9b693cfd7bfacab1d9ff4acac1a4150700609" }
|
||||
tree-sitter-css = "0.23"
|
||||
tree-sitter-diff = "0.1.0"
|
||||
tree-sitter-elixir = "0.3"
|
||||
tree-sitter-embedded-template = "0.23.0"
|
||||
tree-sitter-gitcommit = { git = "https://github.com/zed-industries/tree-sitter-git-commit", rev = "88309716a69dd13ab83443721ba6e0b491d37ee9" }
|
||||
tree-sitter-go = "0.23"
|
||||
tree-sitter-go-mod = { git = "https://github.com/camdencheek/tree-sitter-go-mod", rev = "2e886870578eeba1927a2dc4bd2e2b3f598c5f9a", package = "tree-sitter-gomod" }
|
||||
tree-sitter-gowork = { git = "https://github.com/zed-industries/tree-sitter-go-work", rev = "acb0617bf7f4fda02c6217676cc64acb89536dc7" }
|
||||
tree-sitter-heex = { git = "https://github.com/zed-industries/tree-sitter-heex", rev = "1dd45142fbb05562e35b2040c6129c9bca346592" }
|
||||
tree-sitter-html = "0.23"
|
||||
tree-sitter-jsdoc = "0.23"
|
||||
tree-sitter-json = "0.24"
|
||||
tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", rev = "9a23c1a96c0513d8fc6520972beedd419a973539" }
|
||||
tree-sitter-python = "0.25"
|
||||
tree-sitter-regex = "0.24"
|
||||
tree-sitter-ruby = "0.23"
|
||||
tree-sitter-rust = "0.24"
|
||||
tree-sitter-typescript = { git = "https://github.com/zed-industries/tree-sitter-typescript", rev = "e2c53597d6a5d9cf7bbe8dccde576fe1e46c5899" } # https://github.com/tree-sitter/tree-sitter-typescript/pull/347
|
||||
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "baff0b51c64ef6a1fb1f8390f3ad6015b83ec13a" }
|
||||
tracing = "0.1.40"
|
||||
unicase = "2.6"
|
||||
unicode-script = "0.5.7"
|
||||
unicode-segmentation = "1.10"
|
||||
unindent = "0.2.0"
|
||||
url = "2.2"
|
||||
urlencoding = "2.1.2"
|
||||
uuid = { version = "1.1.2", features = ["v4", "v5", "v7", "serde"] }
|
||||
walkdir = "2.5"
|
||||
wasm-encoder = "0.221"
|
||||
wasmparser = "0.221"
|
||||
wasmtime = { version = "33", default-features = false, features = [
|
||||
"async",
|
||||
"demangle",
|
||||
"runtime",
|
||||
"cranelift",
|
||||
"component-model",
|
||||
"incremental-cache",
|
||||
"parallel-compilation",
|
||||
] }
|
||||
wasmtime-wasi = "33"
|
||||
wax = "0.6"
|
||||
which = "6.0.0"
|
||||
windows-core = "0.61"
|
||||
yawc = "0.2.5"
|
||||
zeroize = "1.8"
|
||||
zstd = "0.11"
|
||||
|
||||
|
||||
[workspace.dependencies.windows]
|
||||
version = "0.61"
|
||||
features = [
|
||||
"Foundation_Numerics",
|
||||
"Storage_Search",
|
||||
"Storage_Streams",
|
||||
"System_Threading",
|
||||
"UI_ViewManagement",
|
||||
"Wdk_System_SystemServices",
|
||||
"Win32_Globalization",
|
||||
"Win32_Graphics_Direct3D",
|
||||
"Win32_Graphics_Direct3D11",
|
||||
"Win32_Graphics_Direct3D_Fxc",
|
||||
"Win32_Graphics_DirectComposition",
|
||||
"Win32_Graphics_DirectWrite",
|
||||
"Win32_Graphics_Dwm",
|
||||
"Win32_Graphics_Dxgi",
|
||||
"Win32_Graphics_Dxgi_Common",
|
||||
"Win32_Graphics_Gdi",
|
||||
"Win32_Graphics_Imaging",
|
||||
"Win32_Graphics_Hlsl",
|
||||
"Win32_Networking_WinSock",
|
||||
"Win32_Security",
|
||||
"Win32_Security_Credentials",
|
||||
"Win32_Security_Cryptography",
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_System_Com",
|
||||
"Win32_System_Com_StructuredStorage",
|
||||
"Win32_System_Console",
|
||||
"Win32_System_DataExchange",
|
||||
"Win32_System_IO",
|
||||
"Win32_System_LibraryLoader",
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_Ole",
|
||||
"Win32_System_Performance",
|
||||
"Win32_System_Pipes",
|
||||
"Win32_System_SystemInformation",
|
||||
"Win32_System_SystemServices",
|
||||
"Win32_System_Threading",
|
||||
"Win32_System_Variant",
|
||||
"Win32_System_WinRT",
|
||||
"Win32_UI_Controls",
|
||||
"Win32_UI_HiDpi",
|
||||
"Win32_UI_Input_Ime",
|
||||
"Win32_UI_Input_KeyboardAndMouse",
|
||||
"Win32_UI_Shell",
|
||||
"Win32_UI_Shell_Common",
|
||||
"Win32_UI_Shell_PropertiesSystem",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
notify = { git = "https://github.com/zed-industries/notify.git", rev = "b4588b2e5aee68f4c0e100f140e808cbce7b1419" }
|
||||
notify-types = { git = "https://github.com/zed-industries/notify.git", rev = "b4588b2e5aee68f4c0e100f140e808cbce7b1419" }
|
||||
windows-capture = { git = "https://github.com/zed-industries/windows-capture.git", rev = "f0d6c1b6691db75461b732f6d5ff56eed002eeb9" }
|
||||
calloop = { git = "https://github.com/zed-industries/calloop" }
|
||||
|
||||
[profile.dev]
|
||||
split-debuginfo = "unpacked"
|
||||
# https://github.com/rust-lang/cargo/issues/16104
|
||||
incremental = false
|
||||
codegen-units = 16
|
||||
|
||||
# mirror configuration for crates compiled for the build platform
|
||||
# (without this cargo will compile ~400 crates twice)
|
||||
[profile.dev.build-override]
|
||||
codegen-units = 16
|
||||
|
||||
[profile.dev.package]
|
||||
# proc-macros start
|
||||
gpui_macros = { opt-level = 3 }
|
||||
derive_refineable = { opt-level = 3 }
|
||||
settings_macros = { opt-level = 3 }
|
||||
sqlez_macros = { opt-level = 3, codegen-units = 1 }
|
||||
ui_macros = { opt-level = 3 }
|
||||
util_macros = { opt-level = 3 }
|
||||
quote = { opt-level = 3 }
|
||||
syn = { opt-level = 3 }
|
||||
proc-macro2 = { opt-level = 3 }
|
||||
# proc-macros end
|
||||
|
||||
taffy = { opt-level = 3 }
|
||||
resvg = { opt-level = 3 }
|
||||
wasmtime = { opt-level = 3 }
|
||||
# Build single-source-file crates with cg=1 as it helps make `cargo build` of a whole workspace a bit faster
|
||||
activity_indicator = { codegen-units = 1 }
|
||||
assets = { codegen-units = 1 }
|
||||
breadcrumbs = { codegen-units = 1 }
|
||||
collections = { codegen-units = 1 }
|
||||
command_palette = { codegen-units = 1 }
|
||||
command_palette_hooks = { codegen-units = 1 }
|
||||
feature_flags = { codegen-units = 1 }
|
||||
file_icons = { codegen-units = 1 }
|
||||
fsevent = { codegen-units = 1 }
|
||||
image_viewer = { codegen-units = 1 }
|
||||
edit_prediction_ui = { codegen-units = 1 }
|
||||
install_cli = { codegen-units = 1 }
|
||||
journal = { codegen-units = 1 }
|
||||
json_schema_store = { codegen-units = 1 }
|
||||
lmstudio = { codegen-units = 1 }
|
||||
menu = { codegen-units = 1 }
|
||||
notifications = { codegen-units = 1 }
|
||||
ollama = { codegen-units = 1 }
|
||||
outline = { codegen-units = 1 }
|
||||
paths = { codegen-units = 1 }
|
||||
prettier = { codegen-units = 1 }
|
||||
project_symbols = { codegen-units = 1 }
|
||||
refineable = { codegen-units = 1 }
|
||||
release_channel = { codegen-units = 1 }
|
||||
reqwest_client = { codegen-units = 1 }
|
||||
session = { codegen-units = 1 }
|
||||
snippet = { codegen-units = 1 }
|
||||
snippets_ui = { codegen-units = 1 }
|
||||
story = { codegen-units = 1 }
|
||||
supermaven_api = { codegen-units = 1 }
|
||||
telemetry_events = { codegen-units = 1 }
|
||||
theme_selector = { codegen-units = 1 }
|
||||
time_format = { codegen-units = 1 }
|
||||
ui_input = { codegen-units = 1 }
|
||||
zed_actions = { codegen-units = 1 }
|
||||
|
||||
[profile.release]
|
||||
debug = "limited"
|
||||
lto = "thin"
|
||||
codegen-units = 1
|
||||
|
||||
[profile.release.package]
|
||||
zed = { codegen-units = 16 }
|
||||
|
||||
[profile.release-fast]
|
||||
inherits = "release"
|
||||
debug = "full"
|
||||
lto = false
|
||||
codegen-units = 16
|
||||
|
||||
[workspace.lints.rust]
|
||||
unexpected_cfgs = { level = "allow" }
|
||||
|
||||
[workspace.lints.clippy]
|
||||
dbg_macro = "deny"
|
||||
todo = "deny"
|
||||
|
||||
declare_interior_mutable_const = "deny"
|
||||
|
||||
redundant_clone = "deny"
|
||||
disallowed_methods = "deny"
|
||||
|
||||
# We currently do not restrict any style rules
|
||||
# as it slows down shipping code to Zed.
|
||||
#
|
||||
# Running ./script/clippy can take several minutes, and so it's
|
||||
# common to skip that step and let CI do it. Any unexpected failures
|
||||
# (which also take minutes to discover) thus require switching back
|
||||
# to an old branch, manual fixing, and re-pushing.
|
||||
#
|
||||
# In the future we could improve this by either making sure
|
||||
# Zed can surface clippy errors in diagnostics (in addition to the
|
||||
# rust-analyzer errors), or by having CI fix style nits automatically.
|
||||
style = { level = "allow", priority = -1 }
|
||||
|
||||
# Individual rules that have violations in the codebase:
|
||||
type_complexity = "allow"
|
||||
let_underscore_future = "allow"
|
||||
|
||||
# Motivation: We use `vec![a..b]` a lot when dealing with ranges in text, so
|
||||
# warning on this rule produces a lot of noise.
|
||||
single_range_in_vec_init = "allow"
|
||||
|
||||
# in Rust it can be very tedious to reduce argument count without
|
||||
# running afoul of the borrow checker.
|
||||
too_many_arguments = "allow"
|
||||
|
||||
# We often have large enum variants yet we rarely actually bother with splitting them up.
|
||||
large_enum_variant = "allow"
|
||||
|
||||
# Boolean expressions can be hard to read, requiring only the minimal form gets in the way
|
||||
nonminimal_bool = "allow"
|
||||
|
||||
[workspace.metadata.cargo-machete]
|
||||
ignored = [
|
||||
"bindgen",
|
||||
"cbindgen",
|
||||
"prost_build",
|
||||
"serde",
|
||||
"component",
|
||||
"documented",
|
||||
"sea-orm-macros",
|
||||
]
|
||||
@@ -28,6 +28,8 @@ pub use entity_map::*;
|
||||
use http_client::{HttpClient, Url};
|
||||
use smallvec::SmallVec;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub use test_app::*;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub use test_context::*;
|
||||
use util::{ResultExt, debug_panic};
|
||||
|
||||
@@ -51,6 +53,8 @@ mod async_context;
|
||||
mod context;
|
||||
mod entity_map;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
mod test_app;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
mod test_context;
|
||||
|
||||
/// The duration for which futures returned from [Context::on_app_quit] can run before the application fully quits.
|
||||
|
||||
605
crates/gpui/src/app/test_app.rs
Normal file
605
crates/gpui/src/app/test_app.rs
Normal file
@@ -0,0 +1,605 @@
|
||||
//! A clean testing API for GPUI applications.
|
||||
//!
|
||||
//! `TestApp` provides a simpler alternative to `TestAppContext` with:
|
||||
//! - Automatic effect flushing after updates
|
||||
//! - Clean window creation and inspection
|
||||
//! - Input simulation helpers
|
||||
//!
|
||||
//! # Example
|
||||
//! ```ignore
|
||||
//! #[test]
|
||||
//! fn test_my_view() {
|
||||
//! let mut app = TestApp::new();
|
||||
//!
|
||||
//! let mut window = app.open_window(|window, cx| {
|
||||
//! MyView::new(window, cx)
|
||||
//! });
|
||||
//!
|
||||
//! window.update(|view, window, cx| {
|
||||
//! view.do_something(cx);
|
||||
//! });
|
||||
//!
|
||||
//! // Check rendered state
|
||||
//! assert_eq!(window.title(), Some("Expected Title"));
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use crate::{
|
||||
AnyWindowHandle, App, AppCell, AppContext, AsyncApp, BackgroundExecutor, BorrowAppContext,
|
||||
Bounds, ClipboardItem, Context, Entity, ForegroundExecutor, Global, InputEvent, Keystroke,
|
||||
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Platform, Point, Render,
|
||||
SceneSnapshot, Size, Task, TestDispatcher, TestPlatform, TextSystem, Window, WindowBounds,
|
||||
WindowHandle, WindowOptions, app::GpuiMode,
|
||||
};
|
||||
use rand::{SeedableRng, rngs::StdRng};
|
||||
use std::{future::Future, rc::Rc, sync::Arc, time::Duration};
|
||||
|
||||
/// A test application context with a clean API.
|
||||
///
|
||||
/// Unlike `TestAppContext`, `TestApp` automatically flushes effects after
|
||||
/// each update and provides simpler window management.
|
||||
pub struct TestApp {
|
||||
app: Rc<AppCell>,
|
||||
platform: Rc<TestPlatform>,
|
||||
background_executor: BackgroundExecutor,
|
||||
foreground_executor: ForegroundExecutor,
|
||||
#[allow(dead_code)]
|
||||
dispatcher: TestDispatcher,
|
||||
text_system: Arc<TextSystem>,
|
||||
}
|
||||
|
||||
impl TestApp {
|
||||
/// Create a new test application.
|
||||
pub fn new() -> Self {
|
||||
Self::with_seed(0)
|
||||
}
|
||||
|
||||
/// Create a new test application with a specific random seed.
|
||||
pub fn with_seed(seed: u64) -> Self {
|
||||
let dispatcher = TestDispatcher::new(StdRng::seed_from_u64(seed));
|
||||
let arc_dispatcher = Arc::new(dispatcher.clone());
|
||||
let background_executor = BackgroundExecutor::new(arc_dispatcher.clone());
|
||||
let foreground_executor = ForegroundExecutor::new(arc_dispatcher);
|
||||
let platform = TestPlatform::new(background_executor.clone(), foreground_executor.clone());
|
||||
let asset_source = Arc::new(());
|
||||
let http_client = http_client::FakeHttpClient::with_404_response();
|
||||
let text_system = Arc::new(TextSystem::new(platform.text_system()));
|
||||
|
||||
let mut app = App::new_app(platform.clone(), asset_source, http_client);
|
||||
app.borrow_mut().mode = GpuiMode::test();
|
||||
|
||||
Self {
|
||||
app,
|
||||
platform,
|
||||
background_executor,
|
||||
foreground_executor,
|
||||
dispatcher,
|
||||
text_system,
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a closure with mutable access to the App context.
|
||||
/// Automatically runs until parked after the closure completes.
|
||||
pub fn update<R>(&mut self, f: impl FnOnce(&mut App) -> R) -> R {
|
||||
let result = {
|
||||
let mut app = self.app.borrow_mut();
|
||||
app.update(f)
|
||||
};
|
||||
self.run_until_parked();
|
||||
result
|
||||
}
|
||||
|
||||
/// Run a closure with read-only access to the App context.
|
||||
pub fn read<R>(&self, f: impl FnOnce(&App) -> R) -> R {
|
||||
let app = self.app.borrow();
|
||||
f(&app)
|
||||
}
|
||||
|
||||
/// Create a new entity in the app.
|
||||
pub fn new_entity<T: 'static>(
|
||||
&mut self,
|
||||
build: impl FnOnce(&mut Context<T>) -> T,
|
||||
) -> Entity<T> {
|
||||
self.update(|cx| cx.new(build))
|
||||
}
|
||||
|
||||
/// Update an entity.
|
||||
pub fn update_entity<T: 'static, R>(
|
||||
&mut self,
|
||||
entity: &Entity<T>,
|
||||
f: impl FnOnce(&mut T, &mut Context<T>) -> R,
|
||||
) -> R {
|
||||
self.update(|cx| entity.update(cx, f))
|
||||
}
|
||||
|
||||
/// Read an entity.
|
||||
pub fn read_entity<T: 'static, R>(
|
||||
&self,
|
||||
entity: &Entity<T>,
|
||||
f: impl FnOnce(&T, &App) -> R,
|
||||
) -> R {
|
||||
self.read(|cx| f(entity.read(cx), cx))
|
||||
}
|
||||
|
||||
/// Open a test window with the given root view.
|
||||
pub fn open_window<V: Render + 'static>(
|
||||
&mut self,
|
||||
build_view: impl FnOnce(&mut Window, &mut Context<V>) -> V,
|
||||
) -> TestWindow<V> {
|
||||
let bounds = self.read(|cx| Bounds::maximized(None, cx));
|
||||
let handle = self.update(|cx| {
|
||||
cx.open_window(
|
||||
WindowOptions {
|
||||
window_bounds: Some(WindowBounds::Windowed(bounds)),
|
||||
..Default::default()
|
||||
},
|
||||
|window, cx| cx.new(|cx| build_view(window, cx)),
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
TestWindow {
|
||||
handle,
|
||||
app: self.app.clone(),
|
||||
platform: self.platform.clone(),
|
||||
background_executor: self.background_executor.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Open a test window with specific options.
|
||||
pub fn open_window_with_options<V: Render + 'static>(
|
||||
&mut self,
|
||||
options: WindowOptions,
|
||||
build_view: impl FnOnce(&mut Window, &mut Context<V>) -> V,
|
||||
) -> TestWindow<V> {
|
||||
let handle = self.update(|cx| {
|
||||
cx.open_window(options, |window, cx| cx.new(|cx| build_view(window, cx)))
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
TestWindow {
|
||||
handle,
|
||||
app: self.app.clone(),
|
||||
platform: self.platform.clone(),
|
||||
background_executor: self.background_executor.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Run pending tasks until there's nothing left to do.
|
||||
pub fn run_until_parked(&self) {
|
||||
self.background_executor.run_until_parked();
|
||||
}
|
||||
|
||||
/// Advance the simulated clock by the given duration.
|
||||
pub fn advance_clock(&self, duration: Duration) {
|
||||
self.background_executor.advance_clock(duration);
|
||||
}
|
||||
|
||||
/// Spawn a future on the foreground executor.
|
||||
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncApp) -> Fut) -> Task<R>
|
||||
where
|
||||
Fut: Future<Output = R> + 'static,
|
||||
R: 'static,
|
||||
{
|
||||
self.foreground_executor.spawn(f(self.to_async()))
|
||||
}
|
||||
|
||||
/// Spawn a future on the background executor.
|
||||
pub fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
|
||||
where
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.background_executor.spawn(future)
|
||||
}
|
||||
|
||||
/// Get an async handle to the app.
|
||||
pub fn to_async(&self) -> AsyncApp {
|
||||
AsyncApp {
|
||||
app: Rc::downgrade(&self.app),
|
||||
background_executor: self.background_executor.clone(),
|
||||
foreground_executor: self.foreground_executor.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the background executor.
|
||||
pub fn background_executor(&self) -> &BackgroundExecutor {
|
||||
&self.background_executor
|
||||
}
|
||||
|
||||
/// Get the foreground executor.
|
||||
pub fn foreground_executor(&self) -> &ForegroundExecutor {
|
||||
&self.foreground_executor
|
||||
}
|
||||
|
||||
/// Get the text system.
|
||||
pub fn text_system(&self) -> &Arc<TextSystem> {
|
||||
&self.text_system
|
||||
}
|
||||
|
||||
/// Check if a global of the given type exists.
|
||||
pub fn has_global<G: Global>(&self) -> bool {
|
||||
self.read(|cx| cx.has_global::<G>())
|
||||
}
|
||||
|
||||
/// Set a global value.
|
||||
pub fn set_global<G: Global>(&mut self, global: G) {
|
||||
self.update(|cx| cx.set_global(global));
|
||||
}
|
||||
|
||||
/// Read a global value.
|
||||
pub fn read_global<G: Global, R>(&self, f: impl FnOnce(&G, &App) -> R) -> R {
|
||||
self.read(|cx| f(cx.global(), cx))
|
||||
}
|
||||
|
||||
/// Update a global value.
|
||||
pub fn update_global<G: Global, R>(&mut self, f: impl FnOnce(&mut G, &mut App) -> R) -> R {
|
||||
self.update(|cx| cx.update_global(f))
|
||||
}
|
||||
|
||||
// Platform simulation methods
|
||||
|
||||
/// Write text to the simulated clipboard.
|
||||
pub fn write_to_clipboard(&self, item: ClipboardItem) {
|
||||
self.platform.write_to_clipboard(item);
|
||||
}
|
||||
|
||||
/// Read from the simulated clipboard.
|
||||
pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
|
||||
self.platform.read_from_clipboard()
|
||||
}
|
||||
|
||||
/// Get URLs that have been opened via `cx.open_url()`.
|
||||
pub fn opened_url(&self) -> Option<String> {
|
||||
self.platform.opened_url.borrow().clone()
|
||||
}
|
||||
|
||||
/// Check if a file path prompt is pending.
|
||||
pub fn did_prompt_for_new_path(&self) -> bool {
|
||||
self.platform.did_prompt_for_new_path()
|
||||
}
|
||||
|
||||
/// Simulate answering a path selection dialog.
|
||||
pub fn simulate_new_path_selection(
|
||||
&self,
|
||||
select: impl FnOnce(&std::path::Path) -> Option<std::path::PathBuf>,
|
||||
) {
|
||||
self.platform.simulate_new_path_selection(select);
|
||||
}
|
||||
|
||||
/// Check if a prompt dialog is pending.
|
||||
pub fn has_pending_prompt(&self) -> bool {
|
||||
self.platform.has_pending_prompt()
|
||||
}
|
||||
|
||||
/// Simulate answering a prompt dialog.
|
||||
pub fn simulate_prompt_answer(&self, button: &str) {
|
||||
self.platform.simulate_prompt_answer(button);
|
||||
}
|
||||
|
||||
/// Get all open windows.
|
||||
pub fn windows(&self) -> Vec<AnyWindowHandle> {
|
||||
self.read(|cx| cx.windows())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TestApp {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// A test window with inspection and simulation capabilities.
|
||||
pub struct TestWindow<V> {
|
||||
handle: WindowHandle<V>,
|
||||
app: Rc<AppCell>,
|
||||
platform: Rc<TestPlatform>,
|
||||
background_executor: BackgroundExecutor,
|
||||
}
|
||||
|
||||
impl<V: 'static + Render> TestWindow<V> {
|
||||
/// Get the window handle.
|
||||
pub fn handle(&self) -> WindowHandle<V> {
|
||||
self.handle
|
||||
}
|
||||
|
||||
/// Get the root view entity.
|
||||
pub fn root(&self) -> Entity<V> {
|
||||
let mut app = self.app.borrow_mut();
|
||||
let any_handle: AnyWindowHandle = self.handle.into();
|
||||
app.update_window(any_handle, |root_view, _, _| {
|
||||
root_view.downcast::<V>().expect("root view type mismatch")
|
||||
})
|
||||
.expect("window not found")
|
||||
}
|
||||
|
||||
/// Update the root view.
|
||||
/// Automatically draws the window after the update to ensure the scene is current.
|
||||
pub fn update<R>(&mut self, f: impl FnOnce(&mut V, &mut Window, &mut Context<V>) -> R) -> R {
|
||||
let result = {
|
||||
let mut app = self.app.borrow_mut();
|
||||
let any_handle: AnyWindowHandle = self.handle.into();
|
||||
app.update_window(any_handle, |root_view, window, cx| {
|
||||
let view = root_view.downcast::<V>().expect("root view type mismatch");
|
||||
view.update(cx, |view, cx| f(view, window, cx))
|
||||
})
|
||||
.expect("window not found")
|
||||
};
|
||||
self.background_executor.run_until_parked();
|
||||
self.draw();
|
||||
result
|
||||
}
|
||||
|
||||
/// Read the root view.
|
||||
pub fn read<R>(&self, f: impl FnOnce(&V, &App) -> R) -> R {
|
||||
let app = self.app.borrow();
|
||||
let view = self
|
||||
.app
|
||||
.borrow()
|
||||
.windows
|
||||
.get(self.handle.window_id())
|
||||
.and_then(|w| w.as_ref())
|
||||
.and_then(|w| w.root.clone())
|
||||
.and_then(|r| r.downcast::<V>().ok())
|
||||
.expect("window or root view not found");
|
||||
f(view.read(&app), &app)
|
||||
}
|
||||
|
||||
/// Get the window title.
|
||||
pub fn title(&self) -> Option<String> {
|
||||
let app = self.app.borrow();
|
||||
app.read_window(&self.handle, |_, _cx| {
|
||||
// TODO: expose title through Window API
|
||||
None
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Simulate a keystroke.
|
||||
/// Automatically draws the window after the keystroke.
|
||||
pub fn simulate_keystroke(&mut self, keystroke: &str) {
|
||||
let keystroke = Keystroke::parse(keystroke).unwrap();
|
||||
{
|
||||
let mut app = self.app.borrow_mut();
|
||||
let any_handle: AnyWindowHandle = self.handle.into();
|
||||
app.update_window(any_handle, |_, window, cx| {
|
||||
window.dispatch_keystroke(keystroke, cx);
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
self.background_executor.run_until_parked();
|
||||
self.draw();
|
||||
}
|
||||
|
||||
/// Simulate multiple keystrokes (space-separated).
|
||||
pub fn simulate_keystrokes(&mut self, keystrokes: &str) {
|
||||
for keystroke in keystrokes.split(' ') {
|
||||
self.simulate_keystroke(keystroke);
|
||||
}
|
||||
}
|
||||
|
||||
/// Simulate typing text.
|
||||
pub fn simulate_input(&mut self, input: &str) {
|
||||
for char in input.chars() {
|
||||
self.simulate_keystroke(&char.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/// Simulate a mouse move.
|
||||
pub fn simulate_mouse_move(&mut self, position: Point<Pixels>) {
|
||||
self.simulate_event(MouseMoveEvent {
|
||||
position,
|
||||
modifiers: Default::default(),
|
||||
pressed_button: None,
|
||||
});
|
||||
}
|
||||
|
||||
/// Simulate a mouse down event.
|
||||
pub fn simulate_mouse_down(&mut self, position: Point<Pixels>, button: MouseButton) {
|
||||
self.simulate_event(MouseDownEvent {
|
||||
position,
|
||||
button,
|
||||
modifiers: Default::default(),
|
||||
click_count: 1,
|
||||
first_mouse: false,
|
||||
});
|
||||
}
|
||||
|
||||
/// Simulate a mouse up event.
|
||||
pub fn simulate_mouse_up(&mut self, position: Point<Pixels>, button: MouseButton) {
|
||||
self.simulate_event(MouseUpEvent {
|
||||
position,
|
||||
button,
|
||||
modifiers: Default::default(),
|
||||
click_count: 1,
|
||||
});
|
||||
}
|
||||
|
||||
/// Simulate a click at the given position.
|
||||
pub fn simulate_click(&mut self, position: Point<Pixels>, button: MouseButton) {
|
||||
self.simulate_mouse_down(position, button);
|
||||
self.simulate_mouse_up(position, button);
|
||||
}
|
||||
|
||||
/// Simulate a scroll event.
|
||||
pub fn simulate_scroll(&mut self, position: Point<Pixels>, delta: Point<Pixels>) {
|
||||
self.simulate_event(crate::ScrollWheelEvent {
|
||||
position,
|
||||
delta: crate::ScrollDelta::Pixels(delta),
|
||||
modifiers: Default::default(),
|
||||
touch_phase: crate::TouchPhase::Moved,
|
||||
});
|
||||
}
|
||||
|
||||
/// Simulate an input event.
|
||||
/// Automatically draws the window after the event.
|
||||
pub fn simulate_event<E: InputEvent>(&mut self, event: E) {
|
||||
let platform_input = event.to_platform_input();
|
||||
{
|
||||
let mut app = self.app.borrow_mut();
|
||||
let any_handle: AnyWindowHandle = self.handle.into();
|
||||
app.update_window(any_handle, |_, window, cx| {
|
||||
window.dispatch_event(platform_input, cx);
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
self.background_executor.run_until_parked();
|
||||
self.draw();
|
||||
}
|
||||
|
||||
/// Simulate resizing the window.
|
||||
/// Automatically draws the window after the resize.
|
||||
pub fn simulate_resize(&mut self, size: Size<Pixels>) {
|
||||
let window_id = self.handle.window_id();
|
||||
let mut app = self.app.borrow_mut();
|
||||
if let Some(Some(window)) = app.windows.get_mut(window_id) {
|
||||
if let Some(test_window) = window.platform_window.as_test() {
|
||||
test_window.simulate_resize(size);
|
||||
}
|
||||
}
|
||||
drop(app);
|
||||
self.background_executor.run_until_parked();
|
||||
self.draw();
|
||||
}
|
||||
|
||||
/// Force a redraw of the window.
|
||||
pub fn draw(&mut self) {
|
||||
let mut app = self.app.borrow_mut();
|
||||
let any_handle: AnyWindowHandle = self.handle.into();
|
||||
app.update_window(any_handle, |_, window, cx| {
|
||||
window.draw(cx).clear();
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Get a snapshot of the rendered scene for inspection.
|
||||
/// The scene is automatically kept up to date after `update()` and `simulate_*()` calls.
|
||||
pub fn scene_snapshot(&self) -> SceneSnapshot {
|
||||
let app = self.app.borrow();
|
||||
let window = app
|
||||
.windows
|
||||
.get(self.handle.window_id())
|
||||
.and_then(|w| w.as_ref())
|
||||
.expect("window not found");
|
||||
window.rendered_frame.scene.snapshot()
|
||||
}
|
||||
|
||||
/// Get the named diagnostic quads recorded during imperative paint, without inspecting the
|
||||
/// rest of the scene snapshot.
|
||||
///
|
||||
/// This is useful for tests that want a stable, semantic view of layout/paint geometry without
|
||||
/// coupling to the low-level quad/glyph output.
|
||||
pub fn diagnostic_quads(&self) -> Vec<crate::scene::test_scene::DiagnosticQuad> {
|
||||
self.scene_snapshot().diagnostic_quads
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Clone for TestWindow<V> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
handle: self.handle,
|
||||
app: self.app.clone(),
|
||||
platform: self.platform.clone(),
|
||||
background_executor: self.background_executor.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{FocusHandle, Focusable, div, prelude::*};
|
||||
|
||||
struct Counter {
|
||||
count: usize,
|
||||
focus_handle: FocusHandle,
|
||||
}
|
||||
|
||||
impl Counter {
|
||||
fn new(_window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let focus_handle = cx.focus_handle();
|
||||
Self {
|
||||
count: 0,
|
||||
focus_handle,
|
||||
}
|
||||
}
|
||||
|
||||
fn increment(&mut self, _cx: &mut Context<Self>) {
|
||||
self.count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for Counter {
|
||||
fn focus_handle(&self, _cx: &App) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Counter {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div().child(format!("Count: {}", self.count))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_usage() {
|
||||
let mut app = TestApp::new();
|
||||
|
||||
let mut window = app.open_window(Counter::new);
|
||||
|
||||
window.update(|counter, _window, cx| {
|
||||
counter.increment(cx);
|
||||
});
|
||||
|
||||
window.read(|counter, _| {
|
||||
assert_eq!(counter.count, 1);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_entity_creation() {
|
||||
let mut app = TestApp::new();
|
||||
|
||||
let entity = app.new_entity(|cx| Counter {
|
||||
count: 42,
|
||||
focus_handle: cx.focus_handle(),
|
||||
});
|
||||
|
||||
app.read_entity(&entity, |counter, _| {
|
||||
assert_eq!(counter.count, 42);
|
||||
});
|
||||
|
||||
app.update_entity(&entity, |counter, _cx| {
|
||||
counter.count += 1;
|
||||
});
|
||||
|
||||
app.read_entity(&entity, |counter, _| {
|
||||
assert_eq!(counter.count, 43);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_globals() {
|
||||
let mut app = TestApp::new();
|
||||
|
||||
struct MyGlobal(String);
|
||||
impl Global for MyGlobal {}
|
||||
|
||||
assert!(!app.has_global::<MyGlobal>());
|
||||
|
||||
app.set_global(MyGlobal("hello".into()));
|
||||
|
||||
assert!(app.has_global::<MyGlobal>());
|
||||
|
||||
app.read_global::<MyGlobal, _>(|global, _| {
|
||||
assert_eq!(global.0, "hello");
|
||||
});
|
||||
|
||||
app.update_global::<MyGlobal, _>(|global, _| {
|
||||
global.0 = "world".into();
|
||||
});
|
||||
|
||||
app.read_global::<MyGlobal, _>(|global, _| {
|
||||
assert_eq!(global.0, "world");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@ use crate::{
|
||||
BackgroundExecutor, BorrowAppContext, Bounds, Capslock, ClipboardItem, DrawPhase, Drawable,
|
||||
Element, Empty, EventEmitter, ForegroundExecutor, Global, InputEvent, Keystroke, Modifiers,
|
||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
|
||||
Platform, Point, Render, Result, Size, Task, TestDispatcher, TestPlatform,
|
||||
TestScreenCaptureSource, TestWindow, TextSystem, VisualContext, Window, WindowBounds,
|
||||
WindowHandle, WindowOptions, app::GpuiMode,
|
||||
Platform, Point, Render, Result, Size, Task, TestDispatcher, TestPlatform, TestPlatformWindow,
|
||||
TestScreenCaptureSource, TextSystem, VisualContext, Window, WindowBounds, WindowHandle,
|
||||
WindowOptions, app::GpuiMode,
|
||||
};
|
||||
use anyhow::{anyhow, bail};
|
||||
use futures::{Stream, StreamExt, channel::oneshot};
|
||||
@@ -220,7 +220,7 @@ impl TestAppContext {
|
||||
f(&cx)
|
||||
}
|
||||
|
||||
/// Adds a new window. The Window will always be backed by a `TestWindow` which
|
||||
/// Adds a new window. The Window will always be backed by a `TestPlatformWindow` which
|
||||
/// can be retrieved with `self.test_window(handle)`
|
||||
pub fn add_window<F, V>(&mut self, build_window: F) -> WindowHandle<V>
|
||||
where
|
||||
@@ -465,8 +465,8 @@ impl TestAppContext {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Returns the `TestWindow` backing the given handle.
|
||||
pub(crate) fn test_window(&self, window: AnyWindowHandle) -> TestWindow {
|
||||
/// Returns the `TestPlatformWindow` backing the given handle.
|
||||
pub(crate) fn test_window(&self, window: AnyWindowHandle) -> TestPlatformWindow {
|
||||
self.app
|
||||
.borrow_mut()
|
||||
.windows
|
||||
|
||||
@@ -808,6 +808,15 @@ impl LinearColorStop {
|
||||
}
|
||||
|
||||
impl Background {
|
||||
/// Returns the solid color if this is a solid background, None otherwise.
|
||||
pub fn as_solid(&self) -> Option<Hsla> {
|
||||
if self.tag == BackgroundTag::Solid {
|
||||
Some(self.solid)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Use specified color space for color interpolation.
|
||||
///
|
||||
/// <https://developer.mozilla.org/en-US/docs/Web/CSS/color-interpolation-method>
|
||||
|
||||
@@ -561,7 +561,7 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle {
|
||||
fn update_ime_position(&self, _bounds: Bounds<Pixels>);
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
fn as_test(&mut self) -> Option<&mut TestWindow> {
|
||||
fn as_test(&mut self) -> Option<&mut TestPlatformWindow> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
DummyKeyboardMapper, ForegroundExecutor, Keymap, NoopTextSystem, Platform, PlatformDisplay,
|
||||
PlatformKeyboardLayout, PlatformKeyboardMapper, PlatformTextSystem, PromptButton,
|
||||
ScreenCaptureFrame, ScreenCaptureSource, ScreenCaptureStream, SourceMetadata, Task,
|
||||
TestDisplay, TestWindow, WindowAppearance, WindowParams, size,
|
||||
TestDisplay, TestPlatformWindow, WindowAppearance, WindowParams, size,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use collections::VecDeque;
|
||||
@@ -26,7 +26,7 @@ pub(crate) struct TestPlatform {
|
||||
background_executor: BackgroundExecutor,
|
||||
foreground_executor: ForegroundExecutor,
|
||||
|
||||
pub(crate) active_window: RefCell<Option<TestWindow>>,
|
||||
pub(crate) active_window: RefCell<Option<TestPlatformWindow>>,
|
||||
active_display: Rc<dyn PlatformDisplay>,
|
||||
active_cursor: Mutex<CursorStyle>,
|
||||
current_clipboard_item: Mutex<Option<ClipboardItem>>,
|
||||
@@ -196,7 +196,7 @@ impl TestPlatform {
|
||||
rx
|
||||
}
|
||||
|
||||
pub(crate) fn set_active_window(&self, window: Option<TestWindow>) {
|
||||
pub(crate) fn set_active_window(&self, window: Option<TestPlatformWindow>) {
|
||||
let executor = self.foreground_executor();
|
||||
let previous_window = self.active_window.borrow_mut().take();
|
||||
self.active_window.borrow_mut().clone_from(&window);
|
||||
@@ -314,7 +314,7 @@ impl Platform for TestPlatform {
|
||||
handle: AnyWindowHandle,
|
||||
params: WindowParams,
|
||||
) -> anyhow::Result<Box<dyn crate::PlatformWindow>> {
|
||||
let window = TestWindow::new(
|
||||
let window = TestPlatformWindow::new(
|
||||
handle,
|
||||
params,
|
||||
self.weak.clone(),
|
||||
|
||||
@@ -12,7 +12,7 @@ use std::{
|
||||
sync::{self, Arc},
|
||||
};
|
||||
|
||||
pub(crate) struct TestWindowState {
|
||||
pub(crate) struct TestPlatformWindowState {
|
||||
pub(crate) bounds: Bounds<Pixels>,
|
||||
pub(crate) handle: AnyWindowHandle,
|
||||
display: Rc<dyn PlatformDisplay>,
|
||||
@@ -32,9 +32,9 @@ pub(crate) struct TestWindowState {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct TestWindow(pub(crate) Rc<Mutex<TestWindowState>>);
|
||||
pub(crate) struct TestPlatformWindow(pub(crate) Rc<Mutex<TestPlatformWindowState>>);
|
||||
|
||||
impl HasWindowHandle for TestWindow {
|
||||
impl HasWindowHandle for TestPlatformWindow {
|
||||
fn window_handle(
|
||||
&self,
|
||||
) -> Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
|
||||
@@ -42,7 +42,7 @@ impl HasWindowHandle for TestWindow {
|
||||
}
|
||||
}
|
||||
|
||||
impl HasDisplayHandle for TestWindow {
|
||||
impl HasDisplayHandle for TestPlatformWindow {
|
||||
fn display_handle(
|
||||
&self,
|
||||
) -> Result<raw_window_handle::DisplayHandle<'_>, raw_window_handle::HandleError> {
|
||||
@@ -50,14 +50,14 @@ impl HasDisplayHandle for TestWindow {
|
||||
}
|
||||
}
|
||||
|
||||
impl TestWindow {
|
||||
impl TestPlatformWindow {
|
||||
pub fn new(
|
||||
handle: AnyWindowHandle,
|
||||
params: WindowParams,
|
||||
platform: Weak<TestPlatform>,
|
||||
display: Rc<dyn PlatformDisplay>,
|
||||
) -> Self {
|
||||
Self(Rc::new(Mutex::new(TestWindowState {
|
||||
Self(Rc::new(Mutex::new(TestPlatformWindowState {
|
||||
bounds: params.bounds,
|
||||
display,
|
||||
platform,
|
||||
@@ -111,7 +111,7 @@ impl TestWindow {
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformWindow for TestWindow {
|
||||
impl PlatformWindow for TestPlatformWindow {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.0.lock().bounds
|
||||
}
|
||||
@@ -272,7 +272,7 @@ impl PlatformWindow for TestWindow {
|
||||
self.0.lock().sprite_atlas.clone()
|
||||
}
|
||||
|
||||
fn as_test(&mut self) -> Option<&mut TestWindow> {
|
||||
fn as_test(&mut self) -> Option<&mut TestPlatformWindow> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,126 @@ pub(crate) type PathVertex_ScaledPixels = PathVertex<ScaledPixels>;
|
||||
|
||||
pub(crate) type DrawOrder = u32;
|
||||
|
||||
/// Test-only scene snapshot for inspecting rendered content.
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub mod test_scene {
|
||||
use crate::{Bounds, Hsla, Point, ScaledPixels, SharedString};
|
||||
|
||||
/// A rendered quad (background, border, cursor, selection, etc.)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RenderedQuad {
|
||||
/// Bounds in scaled pixels.
|
||||
pub bounds: Bounds<ScaledPixels>,
|
||||
/// Background color (if solid).
|
||||
pub background_color: Option<Hsla>,
|
||||
/// Border color.
|
||||
pub border_color: Hsla,
|
||||
}
|
||||
|
||||
/// A named diagnostic quad for tests and debugging of imperative paint logic.
|
||||
///
|
||||
/// This is not necessarily a "real" painted quad; it is metadata recorded alongside a scene.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DiagnosticQuad {
|
||||
/// A stable name that test code can filter by.
|
||||
pub name: SharedString,
|
||||
/// Bounds in scaled pixels.
|
||||
pub bounds: Bounds<ScaledPixels>,
|
||||
/// Optional color hint (useful when visualizing).
|
||||
pub color: Option<Hsla>,
|
||||
}
|
||||
|
||||
/// A rendered text glyph.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RenderedGlyph {
|
||||
/// Origin position in scaled pixels.
|
||||
pub origin: Point<ScaledPixels>,
|
||||
/// Size in scaled pixels.
|
||||
pub size: crate::Size<ScaledPixels>,
|
||||
/// Color of the glyph.
|
||||
pub color: Hsla,
|
||||
}
|
||||
|
||||
/// Snapshot of scene contents for testing.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SceneSnapshot {
|
||||
/// All rendered quads.
|
||||
pub quads: Vec<RenderedQuad>,
|
||||
/// All rendered text glyphs.
|
||||
pub glyphs: Vec<RenderedGlyph>,
|
||||
/// Named diagnostic quads recorded by imperative drawing code for tests/debugging.
|
||||
pub diagnostic_quads: Vec<DiagnosticQuad>,
|
||||
/// Number of shadow primitives.
|
||||
pub shadow_count: usize,
|
||||
/// Number of path primitives.
|
||||
pub path_count: usize,
|
||||
/// Number of underline primitives.
|
||||
pub underline_count: usize,
|
||||
/// Number of polychrome sprites (images, emoji).
|
||||
pub polychrome_sprite_count: usize,
|
||||
/// Number of surface primitives.
|
||||
pub surface_count: usize,
|
||||
}
|
||||
|
||||
impl SceneSnapshot {
|
||||
/// Get unique Y positions of quads, sorted.
|
||||
pub fn quad_y_positions(&self) -> Vec<f32> {
|
||||
let mut positions: Vec<f32> = self.quads.iter().map(|q| q.bounds.origin.y.0).collect();
|
||||
positions.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
|
||||
positions.dedup();
|
||||
positions
|
||||
}
|
||||
|
||||
/// Get unique Y positions of glyphs, sorted.
|
||||
pub fn glyph_y_positions(&self) -> Vec<f32> {
|
||||
let mut positions: Vec<f32> = self.glyphs.iter().map(|g| g.origin.y.0).collect();
|
||||
positions.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
|
||||
positions.dedup();
|
||||
positions
|
||||
}
|
||||
|
||||
/// Find quads within a Y range.
|
||||
pub fn quads_in_y_range(&self, min_y: f32, max_y: f32) -> Vec<&RenderedQuad> {
|
||||
self.quads
|
||||
.iter()
|
||||
.filter(|q| {
|
||||
let y = q.bounds.origin.y.0;
|
||||
y >= min_y && y < max_y
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Find glyphs within a Y range.
|
||||
pub fn glyphs_in_y_range(&self, min_y: f32, max_y: f32) -> Vec<&RenderedGlyph> {
|
||||
self.glyphs
|
||||
.iter()
|
||||
.filter(|g| {
|
||||
let y = g.origin.y.0;
|
||||
y >= min_y && y < max_y
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Debug summary string.
|
||||
pub fn summary(&self) -> String {
|
||||
format!(
|
||||
"quads: {}, glyphs: {}, diagnostic_quads: {}, shadows: {}, paths: {}, underlines: {}, polychrome: {}, surfaces: {}",
|
||||
self.quads.len(),
|
||||
self.glyphs.len(),
|
||||
self.diagnostic_quads.len(),
|
||||
self.shadow_count,
|
||||
self.path_count,
|
||||
self.underline_count,
|
||||
self.polychrome_sprite_count,
|
||||
self.surface_count,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub use test_scene::*;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct Scene {
|
||||
pub(crate) paint_operations: Vec<PaintOperation>,
|
||||
@@ -32,6 +152,8 @@ pub(crate) struct Scene {
|
||||
pub(crate) monochrome_sprites: Vec<MonochromeSprite>,
|
||||
pub(crate) polychrome_sprites: Vec<PolychromeSprite>,
|
||||
pub(crate) surfaces: Vec<PaintSurface>,
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub(crate) diagnostic_quads: Vec<test_scene::DiagnosticQuad>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
@@ -46,6 +168,8 @@ impl Scene {
|
||||
self.monochrome_sprites.clear();
|
||||
self.polychrome_sprites.clear();
|
||||
self.surfaces.clear();
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
self.diagnostic_quads.clear();
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
@@ -124,6 +248,41 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a snapshot of the scene for testing.
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn snapshot(&self) -> SceneSnapshot {
|
||||
let quads = self
|
||||
.quads
|
||||
.iter()
|
||||
.map(|q| RenderedQuad {
|
||||
bounds: q.bounds,
|
||||
background_color: q.background.as_solid(),
|
||||
border_color: q.border_color,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let glyphs = self
|
||||
.monochrome_sprites
|
||||
.iter()
|
||||
.map(|s| RenderedGlyph {
|
||||
origin: s.bounds.origin,
|
||||
size: s.bounds.size,
|
||||
color: s.color,
|
||||
})
|
||||
.collect();
|
||||
|
||||
SceneSnapshot {
|
||||
quads,
|
||||
glyphs,
|
||||
diagnostic_quads: self.diagnostic_quads.clone(),
|
||||
shadow_count: self.shadows.len(),
|
||||
path_count: self.paths.len(),
|
||||
underline_count: self.underlines.len(),
|
||||
polychrome_sprite_count: self.polychrome_sprites.len(),
|
||||
surface_count: self.surfaces.len(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(&mut self) {
|
||||
self.shadows.sort_by_key(|shadow| shadow.order);
|
||||
self.quads.sort_by_key(|quad| quad.order);
|
||||
@@ -134,6 +293,10 @@ impl Scene {
|
||||
self.polychrome_sprites
|
||||
.sort_by_key(|sprite| (sprite.order, sprite.tile.tile_id));
|
||||
self.surfaces.sort_by_key(|surface| surface.order);
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
self.diagnostic_quads
|
||||
.sort_by(|a, b| a.name.as_ref().cmp(b.name.as_ref()));
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
@@ -620,7 +783,7 @@ impl Default for TransformationMatrix {
|
||||
#[repr(C)]
|
||||
pub(crate) struct MonochromeSprite {
|
||||
pub order: DrawOrder,
|
||||
pub pad: u32, // align to 8 bytes
|
||||
pub pad: u32,
|
||||
pub bounds: Bounds<ScaledPixels>,
|
||||
pub content_mask: ContentMask<ScaledPixels>,
|
||||
pub color: Hsla,
|
||||
@@ -638,7 +801,7 @@ impl From<MonochromeSprite> for Primitive {
|
||||
#[repr(C)]
|
||||
pub(crate) struct PolychromeSprite {
|
||||
pub order: DrawOrder,
|
||||
pub pad: u32, // align to 8 bytes
|
||||
pub pad: u32,
|
||||
pub grayscale: bool,
|
||||
pub opacity: f32,
|
||||
pub bounds: Bounds<ScaledPixels>,
|
||||
|
||||
@@ -44,6 +44,14 @@ impl ShapedLine {
|
||||
self.layout.len
|
||||
}
|
||||
|
||||
/// The width of the shaped line in pixels.
|
||||
///
|
||||
/// This is the glyph advance width computed by the text shaping system and is useful for
|
||||
/// incrementally advancing a "pen" when painting multiple fragments on the same row.
|
||||
pub fn width(&self) -> Pixels {
|
||||
self.layout.width
|
||||
}
|
||||
|
||||
/// Override the len, useful if you're rendering text a
|
||||
/// as text b (e.g. rendering invisibles).
|
||||
pub fn with_len(mut self, len: usize) -> Self {
|
||||
|
||||
@@ -506,6 +506,10 @@ impl HitboxId {
|
||||
///
|
||||
/// See [`Hitbox::is_hovered`] for details.
|
||||
pub fn is_hovered(self, window: &Window) -> bool {
|
||||
// If this hitbox has captured the pointer, it's always considered hovered
|
||||
if window.captured_hitbox == Some(self) {
|
||||
return true;
|
||||
}
|
||||
let hit_test = &window.mouse_hit_test;
|
||||
for id in hit_test.ids.iter().take(hit_test.hover_hitbox_count) {
|
||||
if self == *id {
|
||||
@@ -760,6 +764,11 @@ impl Frame {
|
||||
self.tab_stops.clear();
|
||||
self.focus = None;
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
{
|
||||
self.debug_bounds.clear();
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "inspector", debug_assertions))]
|
||||
{
|
||||
self.next_inspector_instance_ids.clear();
|
||||
@@ -887,6 +896,9 @@ pub struct Window {
|
||||
pub(crate) pending_input_observers: SubscriberSet<(), AnyObserver>,
|
||||
prompt: Option<RenderablePromptHandle>,
|
||||
pub(crate) client_inset: Option<Pixels>,
|
||||
/// The hitbox that has captured the pointer, if any.
|
||||
/// While captured, mouse events route to this hitbox regardless of hit testing.
|
||||
captured_hitbox: Option<HitboxId>,
|
||||
#[cfg(any(feature = "inspector", debug_assertions))]
|
||||
inspector: Option<Entity<Inspector>>,
|
||||
}
|
||||
@@ -1311,6 +1323,7 @@ impl Window {
|
||||
prompt: None,
|
||||
client_inset: None,
|
||||
image_cache_stack: Vec::new(),
|
||||
captured_hitbox: None,
|
||||
#[cfg(any(feature = "inspector", debug_assertions))]
|
||||
inspector: None,
|
||||
})
|
||||
@@ -1994,6 +2007,26 @@ impl Window {
|
||||
self.mouse_position
|
||||
}
|
||||
|
||||
/// Captures the pointer for the given hitbox. While captured, all mouse move and mouse up
|
||||
/// events will be routed to listeners that check this hitbox's `is_hovered` status,
|
||||
/// regardless of actual hit testing. This enables drag operations that continue
|
||||
/// even when the pointer moves outside the element's bounds.
|
||||
///
|
||||
/// The capture is automatically released on mouse up.
|
||||
pub fn capture_pointer(&mut self, hitbox_id: HitboxId) {
|
||||
self.captured_hitbox = Some(hitbox_id);
|
||||
}
|
||||
|
||||
/// Releases any active pointer capture.
|
||||
pub fn release_pointer(&mut self) {
|
||||
self.captured_hitbox = None;
|
||||
}
|
||||
|
||||
/// Returns the hitbox that has captured the pointer, if any.
|
||||
pub fn captured_hitbox(&self) -> Option<HitboxId> {
|
||||
self.captured_hitbox
|
||||
}
|
||||
|
||||
/// The current state of the keyboard's modifiers
|
||||
pub fn modifiers(&self) -> Modifiers {
|
||||
self.modifiers
|
||||
@@ -2966,6 +2999,41 @@ impl Window {
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
/// Record a named diagnostic quad for test/debug snapshots.
|
||||
///
|
||||
/// This is intended for debugging and asserting against imperative painting logic. The
|
||||
/// recorded quad does not affect rendering; it is captured alongside the rendered scene and
|
||||
/// exposed via `scene_snapshot()`.
|
||||
pub fn record_diagnostic_quad(
|
||||
&mut self,
|
||||
name: impl Into<SharedString>,
|
||||
bounds: Bounds<Pixels>,
|
||||
color: Option<Hsla>,
|
||||
) {
|
||||
self.invalidator.debug_assert_paint();
|
||||
|
||||
let scale_factor = self.scale_factor();
|
||||
self.next_frame.scene.diagnostic_quads.push(crate::test_scene::DiagnosticQuad {
|
||||
name: name.into(),
|
||||
bounds: bounds.scale(scale_factor),
|
||||
color,
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
#[inline]
|
||||
/// Record a named diagnostic quad for test/debug snapshots.
|
||||
///
|
||||
/// This is a no-op unless tests or the `test-support` feature are enabled.
|
||||
pub fn record_diagnostic_quad(
|
||||
&mut self,
|
||||
_name: impl Into<SharedString>,
|
||||
_bounds: Bounds<Pixels>,
|
||||
_color: Option<Hsla>,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Paint the given `Path` into the scene for the next frame at the current z-index.
|
||||
///
|
||||
/// This method should only be called as part of the paint phase of element drawing.
|
||||
@@ -3850,6 +3918,11 @@ impl Window {
|
||||
self.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-release pointer capture on mouse up
|
||||
if event.is::<MouseUpEvent>() && self.captured_hitbox.is_some() {
|
||||
self.captured_hitbox = None;
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch_key_event(&mut self, event: &dyn Any, cx: &mut App) {
|
||||
|
||||
Reference in New Issue
Block a user