Merge branch 'main' into multibuffer-following

This commit is contained in:
Max Brunsfeld 2022-12-12 11:47:39 -08:00
commit f797dfb88f
175 changed files with 16722 additions and 8699 deletions

View file

@ -5,7 +5,7 @@ use gpui::{
Element, Entity, MouseButton, RenderContext, View,
};
use settings::Settings;
use workspace::StatusItemView;
use workspace::{item::ItemHandle, StatusItemView};
pub const NEW_ISSUE_URL: &str = "https://github.com/zed-industries/feedback/issues/new/choose";
@ -43,7 +43,7 @@ impl View for FeedbackLink {
impl StatusItemView for FeedbackLink {
fn set_active_pane_item(
&mut self,
_: Option<&dyn workspace::ItemHandle>,
_: Option<&dyn ItemHandle>,
_: &mut gpui::ViewContext<Self>,
) {
}

View file

@ -14,6 +14,7 @@ mod language_plugin;
mod python;
mod ruby;
mod rust;
mod typescript;
// 1. Add tree-sitter-{language} parser to zed crate
@ -127,6 +128,8 @@ pub async fn init(languages: Arc<LanguageRegistry>, _executor: Arc<Background>)
tree_sitter_embedded_template::language(),
Some(CachedLspAdapter::new(ruby::RubyLanguageServer).await),
),
("scheme", tree_sitter_scheme::language(), None),
("racket", tree_sitter_racket::language(), None),
] {
languages.add(language(name, grammar, lsp_adapter));
}

View file

@ -14,17 +14,57 @@
declarator: (_) @name) @item
(declaration
type: (_) @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))) @item
(type_qualifier)? @context
type: (_)? @context
declarator: [
(function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))
(pointer_declarator
"*" @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context)))
(pointer_declarator
"*" @context
declarator: (pointer_declarator
"*" @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))))
]
) @item
(function_definition
type: (_) @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))) @item
(type_qualifier)? @context
type: (_)? @context
declarator: [
(function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))
(pointer_declarator
"*" @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context)))
(pointer_declarator
"*" @context
declarator: (pointer_declarator
"*" @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))))
]
) @item

View file

@ -51,6 +51,22 @@
parameters: (parameter_list
"(" @context
")" @context)))
(pointer_declarator
"*" @context
declarator: (pointer_declarator
"*" @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))))
(reference_declarator
["&" "&&"] @context
(function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context)))
]
(type_qualifier)? @context) @item
@ -74,6 +90,22 @@
parameters: (parameter_list
"(" @context
")" @context)))
(pointer_declarator
"*" @context
declarator: (pointer_declarator
"*" @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))))
(reference_declarator
["&" "&&"] @context
(function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context)))
]
(type_qualifier)? @context) @item
@ -97,5 +129,21 @@
parameters: (parameter_list
"(" @context
")" @context)))
(pointer_declarator
"*" @context
declarator: (pointer_declarator
"*" @context
declarator: (function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context))))
(reference_declarator
["&" "&&"] @context
(function_declarator
declarator: (_) @name
parameters: (parameter_list
"(" @context
")" @context)))
]
(type_qualifier)? @context) @item

View file

@ -0,0 +1,3 @@
("(" @open ")" @close)
("[" @open "]" @close)
("{" @open "}" @close)

View file

@ -0,0 +1,9 @@
name = "Racket"
path_suffixes = ["rkt"]
line_comment = "; "
autoclose_before = "])"
brackets = [
{ start = "[", end = "]", close = true, newline = false },
{ start = "(", end = ")", close = true, newline = false },
{ start = "\"", end = "\"", close = true, newline = false },
]

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
(_ "[" "]") @indent
(_ "{" "}") @indent
(_ "(" ")") @indent

View file

@ -0,0 +1,10 @@
(list
.
(symbol) @start-symbol @context
.
[
(symbol) @name
(list . (symbol) @name)
]
(#match? @start-symbol "^define")
) @item

View file

@ -11,4 +11,4 @@
(begin "begin" @open "end" @close)
(module "module" @open "end" @close)
(_ . "def" @open "end" @close)
(_ . "class" @open "end" @close)
(_ . "class" @open "end" @close)

View file

@ -0,0 +1,3 @@
("(" @open ")" @close)
("[" @open "]" @close)
("{" @open "}" @close)

View file

@ -0,0 +1,9 @@
name = "Scheme"
path_suffixes = ["scm", "ss"]
line_comment = "; "
autoclose_before = "])"
brackets = [
{ start = "[", end = "]", close = true, newline = false },
{ start = "(", end = ")", close = true, newline = false },
{ start = "\"", end = "\"", close = true, newline = false },
]

View file

@ -0,0 +1,28 @@
["(" ")" "[" "]" "{" "}"] @punctuation.bracket
(number) @number
(character) @constant.builtin
(boolean) @constant.builtin
(symbol) @variable
(string) @string
(escape_sequence) @escape
[(comment)
(block_comment)
(directive)] @comment
((symbol) @operator
(#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
(list
.
(symbol) @function)
(list
.
(symbol) @keyword
(#match? @keyword
"^(define-syntax|let\\*|lambda|λ|case|=>|quote-splicing|unquote-splicing|set!|let|letrec|letrec-syntax|let-values|let\\*-values|do|else|define|cond|syntax-rules|unquote|begin|quote|let-syntax|and|if|quasiquote|letrec|delay|or|when|unless|identifier-syntax|assert|library|export|import|rename|only|except|prefix)$"
))

View file

@ -0,0 +1,3 @@
(_ "[" "]") @indent
(_ "{" "}") @indent
(_ "(" ")") @indent

View file

@ -0,0 +1,10 @@
(list
.
(symbol) @start-symbol @context
.
[
(symbol) @name
(list . (symbol) @name)
]
(#match? @start-symbol "^define")
) @item

View file

@ -23,7 +23,7 @@ use isahc::{config::Configurable, Request};
use language::LanguageRegistry;
use log::LevelFilter;
use parking_lot::Mutex;
use project::{Fs, HomeDir, ProjectStore};
use project::{Fs, HomeDir};
use serde_json::json;
use settings::{
self, settings_file::SettingsFile, KeymapFileContent, Settings, SettingsFileContent,
@ -32,17 +32,16 @@ use settings::{
use smol::process::Command;
use std::fs::OpenOptions;
use std::{env, ffi::OsStr, panic, path::PathBuf, sync::Arc, thread, time::Duration};
use terminal::terminal_container_view::{get_working_directory, TerminalContainer};
use terminal_view::{get_working_directory, TerminalView};
use fs::RealFs;
use settings::watched_json::{watch_keymap_file, watch_settings_file, WatchedJsonFile};
use theme::ThemeRegistry;
use util::{ResultExt, TryFutureExt};
use workspace::{self, AppState, ItemHandle, NewFile, OpenPaths, Workspace};
use zed::{
self, build_window_options, initialize_workspace, languages, menus, RELEASE_CHANNEL,
RELEASE_CHANNEL_NAME,
use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt};
use workspace::{
self, item::ItemHandle, notifications::NotifyResultExt, AppState, NewFile, OpenPaths, Workspace,
};
use zed::{self, build_window_options, initialize_workspace, languages, menus};
fn main() {
let http = http::client();
@ -56,10 +55,6 @@ fn main() {
.map_or("dev".to_string(), |v| v.to_string());
init_panic_hook(app_version, http.clone(), app.background());
let db = app.background().spawn(async move {
project::Db::open(&*zed::paths::DB_DIR, RELEASE_CHANNEL_NAME.as_str())
});
load_embedded_fonts(&app);
let fs = Arc::new(RealFs);
@ -91,11 +86,11 @@ fn main() {
app.run(move |cx| {
cx.set_global(*RELEASE_CHANNEL);
cx.set_global(HomeDir(zed::paths::HOME.to_path_buf()));
cx.set_global(HomeDir(paths::HOME.to_path_buf()));
let client = client::Client::new(http.clone(), cx);
let mut languages = LanguageRegistry::new(login_shell_env_loaded);
languages.set_language_server_download_dir(zed::paths::LANGUAGES_DIR.clone());
languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone());
let languages = Arc::new(languages);
let init_languages = cx
.background()
@ -106,7 +101,7 @@ fn main() {
//Setup settings global before binding actions
cx.set_global(SettingsFile::new(
&*zed::paths::SETTINGS,
&*paths::SETTINGS,
settings_file_content.clone(),
fs.clone(),
));
@ -126,7 +121,7 @@ fn main() {
diagnostics::init(cx);
search::init(cx);
vim::init(cx);
terminal::init(cx);
terminal_view::init(cx);
theme_testbench::init(cx);
cx.spawn(|cx| watch_themes(fs.clone(), themes.clone(), cx))
@ -146,9 +141,7 @@ fn main() {
})
.detach();
let project_store = cx.add_model(|_| ProjectStore::new());
let db = cx.background().block(db);
client.start_telemetry(db.clone());
client.start_telemetry();
client.report_event("start app", Default::default());
let app_state = Arc::new(AppState {
@ -156,14 +149,15 @@ fn main() {
themes,
client: client.clone(),
user_store,
project_store,
fs,
build_window_options,
initialize_workspace,
default_item_factory,
dock_default_item_factory,
});
auto_update::init(db, http, cx);
auto_update::init(http, client::ZED_SERVER_URL.clone(), cx);
workspace::init(app_state.clone(), cx);
journal::init(app_state.clone(), cx);
theme_selector::init(app_state.clone(), cx);
zed::init(&app_state, cx);
@ -209,25 +203,10 @@ fn main() {
}
fn init_paths() {
std::fs::create_dir_all(&*zed::paths::CONFIG_DIR).expect("could not create config path");
std::fs::create_dir_all(&*zed::paths::LANGUAGES_DIR).expect("could not create languages path");
std::fs::create_dir_all(&*zed::paths::DB_DIR).expect("could not create database path");
std::fs::create_dir_all(&*zed::paths::LOGS_DIR).expect("could not create logs path");
// Copy setting files from legacy locations. TODO: remove this after a few releases.
thread::spawn(|| {
if std::fs::metadata(&*zed::paths::legacy::SETTINGS).is_ok()
&& std::fs::metadata(&*zed::paths::SETTINGS).is_err()
{
std::fs::copy(&*zed::paths::legacy::SETTINGS, &*zed::paths::SETTINGS).log_err();
}
if std::fs::metadata(&*zed::paths::legacy::KEYMAP).is_ok()
&& std::fs::metadata(&*zed::paths::KEYMAP).is_err()
{
std::fs::copy(&*zed::paths::legacy::KEYMAP, &*zed::paths::KEYMAP).log_err();
}
});
std::fs::create_dir_all(&*util::paths::CONFIG_DIR).expect("could not create config path");
std::fs::create_dir_all(&*util::paths::LANGUAGES_DIR).expect("could not create languages path");
std::fs::create_dir_all(&*util::paths::DB_DIR).expect("could not create database path");
std::fs::create_dir_all(&*util::paths::LOGS_DIR).expect("could not create logs path");
}
fn init_logger() {
@ -240,16 +219,15 @@ fn init_logger() {
const KIB: u64 = 1024;
const MIB: u64 = 1024 * KIB;
const MAX_LOG_BYTES: u64 = MIB;
if std::fs::metadata(&*zed::paths::LOG)
.map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES)
if std::fs::metadata(&*paths::LOG).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES)
{
let _ = std::fs::rename(&*zed::paths::LOG, &*zed::paths::OLD_LOG);
let _ = std::fs::rename(&*paths::LOG, &*paths::OLD_LOG);
}
let log_file = OpenOptions::new()
.create(true)
.append(true)
.open(&*zed::paths::LOG)
.open(&*paths::LOG)
.expect("could not open logfile");
simplelog::WriteLogger::init(level, simplelog::Config::default(), log_file)
.expect("could not initialize logger");
@ -261,7 +239,7 @@ fn init_panic_hook(app_version: String, http: Arc<dyn HttpClient>, background: A
.spawn({
async move {
let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL);
let mut children = smol::fs::read_dir(&*zed::paths::LOGS_DIR).await?;
let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
while let Some(child) = children.next().await {
let child = child?;
let child_path = child.path();
@ -349,7 +327,7 @@ fn init_panic_hook(app_version: String, http: Arc<dyn HttpClient>, background: A
let panic_filename = chrono::Utc::now().format("%Y_%m_%d %H_%M_%S").to_string();
std::fs::write(
zed::paths::LOGS_DIR.join(format!("zed-{}-{}.panic", app_version, panic_filename)),
paths::LOGS_DIR.join(format!("zed-{}-{}.panic", app_version, panic_filename)),
&message,
)
.context("error writing panic to disk")
@ -483,8 +461,8 @@ fn load_config_files(
.clone()
.spawn(async move {
let settings_file =
WatchedJsonFile::new(fs.clone(), &executor, zed::paths::SETTINGS.clone()).await;
let keymap_file = WatchedJsonFile::new(fs, &executor, zed::paths::KEYMAP.clone()).await;
WatchedJsonFile::new(fs.clone(), &executor, paths::SETTINGS.clone()).await;
let keymap_file = WatchedJsonFile::new(fs, &executor, paths::KEYMAP.clone()).await;
tx.send((settings_file, keymap_file)).ok()
})
.detach();
@ -605,10 +583,10 @@ async fn handle_cli_connection(
}
}
pub fn default_item_factory(
pub fn dock_default_item_factory(
workspace: &mut Workspace,
cx: &mut ViewContext<Workspace>,
) -> Box<dyn ItemHandle> {
) -> Option<Box<dyn ItemHandle>> {
let strategy = cx
.global::<Settings>()
.terminal_overrides
@ -618,6 +596,15 @@ pub fn default_item_factory(
let working_directory = get_working_directory(workspace, cx, strategy);
let terminal_handle = cx.add_view(|cx| TerminalContainer::new(working_directory, false, cx));
Box::new(terminal_handle)
let window_id = cx.window_id();
let terminal = workspace
.project()
.update(cx, |project, cx| {
project.create_terminal(working_directory, window_id, cx)
})
.notify_err(workspace, cx)?;
let terminal_view = cx.add_view(|cx| TerminalView::new(terminal, workspace.database_id(), cx));
Some(Box::new(terminal_view))
}

View file

@ -1,24 +0,0 @@
use std::path::PathBuf;
lazy_static::lazy_static! {
pub static ref HOME: PathBuf = dirs::home_dir().expect("failed to determine home directory");
pub static ref CONFIG_DIR: PathBuf = HOME.join(".config").join("zed");
pub static ref LOGS_DIR: PathBuf = HOME.join("Library/Logs/Zed");
pub static ref LANGUAGES_DIR: PathBuf = HOME.join("Library/Application Support/Zed/languages");
pub static ref DB_DIR: PathBuf = HOME.join("Library/Application Support/Zed/db");
pub static ref SETTINGS: PathBuf = CONFIG_DIR.join("settings.json");
pub static ref KEYMAP: PathBuf = CONFIG_DIR.join("keymap.json");
pub static ref LAST_USERNAME: PathBuf = CONFIG_DIR.join("last-username.txt");
pub static ref LOG: PathBuf = LOGS_DIR.join("Zed.log");
pub static ref OLD_LOG: PathBuf = LOGS_DIR.join("Zed.log.old");
}
pub mod legacy {
use std::path::PathBuf;
lazy_static::lazy_static! {
static ref CONFIG_DIR: PathBuf = super::HOME.join(".zed");
pub static ref SETTINGS: PathBuf = CONFIG_DIR.join("settings.json");
pub static ref KEYMAP: PathBuf = CONFIG_DIR.join("keymap.json");
}
}

View file

@ -1,7 +1,6 @@
mod feedback;
pub mod languages;
pub mod menus;
pub mod paths;
#[cfg(any(test, feature = "test-support"))]
pub mod test;
@ -13,7 +12,6 @@ use collab_ui::{CollabTitlebarItem, ToggleCollaborationMenu};
use collections::VecDeque;
pub use editor;
use editor::{Editor, MultiBuffer};
use lazy_static::lazy_static;
use gpui::{
actions,
@ -26,15 +24,16 @@ use gpui::{
AssetSource, AsyncAppContext, TitlebarOptions, ViewContext, WindowKind,
};
use language::Rope;
use lazy_static::lazy_static;
pub use lsp;
pub use project;
use project_panel::ProjectPanel;
use search::{BufferSearchBar, ProjectSearchBar};
use serde::Deserialize;
use serde_json::to_string_pretty;
use settings::{keymap_file_json_schema, settings_file_json_schema, ReleaseChannel, Settings};
use settings::{keymap_file_json_schema, settings_file_json_schema, Settings};
use std::{env, path::Path, str, sync::Arc};
use util::ResultExt;
use util::{channel::ReleaseChannel, paths, ResultExt};
pub use workspace;
use workspace::{sidebar::SidebarSide, AppState, Workspace};
@ -82,14 +81,6 @@ lazy_static! {
.ok()
.as_deref()
.and_then(parse_pixel_position_env_var);
pub static ref RELEASE_CHANNEL_NAME: String =
env::var("ZED_RELEASE_CHANNEL").unwrap_or(include_str!("../RELEASE_CHANNEL").to_string());
pub static ref RELEASE_CHANNEL: ReleaseChannel = match RELEASE_CHANNEL_NAME.as_str() {
"dev" => ReleaseChannel::Dev,
"preview" => ReleaseChannel::Preview,
"stable" => ReleaseChannel::Stable,
_ => panic!("invalid release channel {}", *RELEASE_CHANNEL_NAME),
};
}
pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
@ -348,6 +339,9 @@ pub fn initialize_workspace(
auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
let window_id = cx.window_id();
vim::observe_keypresses(window_id, cx);
cx.on_window_should_close(|workspace, cx| {
if let Some(task) = workspace.close(&Default::default(), cx) {
task.detach_and_log_err(cx);
@ -406,7 +400,7 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
}
fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
let app_name = cx.global::<ReleaseChannel>().name();
let app_name = cx.global::<ReleaseChannel>().display_name();
let version = env!("CARGO_PKG_VERSION");
cx.prompt(
gpui::PromptLevel::Info,
@ -479,10 +473,11 @@ fn open_config_file(
workspace
.update(&mut cx, |workspace, cx| {
workspace.with_local_workspace(cx, app_state, |workspace, cx| {
workspace.with_local_workspace(&app_state, cx, |workspace, cx| {
workspace.open_paths(vec![path.to_path_buf()], false, cx)
})
})
.await
.await;
Ok::<_, anyhow::Error>(())
})
@ -496,51 +491,55 @@ fn open_log_file(
) {
const MAX_LINES: usize = 1000;
workspace.with_local_workspace(cx, app_state.clone(), |_, cx| {
cx.spawn_weak(|workspace, mut cx| async move {
let (old_log, new_log) = futures::join!(
app_state.fs.load(&paths::OLD_LOG),
app_state.fs.load(&paths::LOG)
);
workspace
.with_local_workspace(&app_state.clone(), cx, move |_, cx| {
cx.spawn_weak(|workspace, mut cx| async move {
let (old_log, new_log) = futures::join!(
app_state.fs.load(&paths::OLD_LOG),
app_state.fs.load(&paths::LOG)
);
if let Some(workspace) = workspace.upgrade(&cx) {
let mut lines = VecDeque::with_capacity(MAX_LINES);
for line in old_log
.iter()
.flat_map(|log| log.lines())
.chain(new_log.iter().flat_map(|log| log.lines()))
{
if lines.len() == MAX_LINES {
lines.pop_front();
if let Some(workspace) = workspace.upgrade(&cx) {
let mut lines = VecDeque::with_capacity(MAX_LINES);
for line in old_log
.iter()
.flat_map(|log| log.lines())
.chain(new_log.iter().flat_map(|log| log.lines()))
{
if lines.len() == MAX_LINES {
lines.pop_front();
}
lines.push_back(line);
}
lines.push_back(line);
}
let log = lines
.into_iter()
.flat_map(|line| [line, "\n"])
.collect::<String>();
let log = lines
.into_iter()
.flat_map(|line| [line, "\n"])
.collect::<String>();
workspace.update(&mut cx, |workspace, cx| {
let project = workspace.project().clone();
let buffer = project
.update(cx, |project, cx| project.create_buffer("", None, cx))
.expect("creating buffers on a local workspace always succeeds");
buffer.update(cx, |buffer, cx| buffer.edit([(0..0, log)], None, cx));
workspace.update(&mut cx, |workspace, cx| {
let project = workspace.project().clone();
let buffer = project
.update(cx, |project, cx| project.create_buffer("", None, cx))
.expect("creating buffers on a local workspace always succeeds");
buffer.update(cx, |buffer, cx| buffer.edit([(0..0, log)], None, cx));
let buffer = cx.add_model(|cx| {
MultiBuffer::singleton(buffer, cx).with_title("Log".into())
let buffer = cx.add_model(|cx| {
MultiBuffer::singleton(buffer, cx).with_title("Log".into())
});
workspace.add_item(
Box::new(
cx.add_view(|cx| {
Editor::for_multibuffer(buffer, Some(project), cx)
}),
),
cx,
);
});
workspace.add_item(
Box::new(
cx.add_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx)),
),
cx,
);
});
}
}
})
.detach();
})
.detach();
});
}
fn open_telemetry_log_file(
@ -548,7 +547,7 @@ fn open_telemetry_log_file(
app_state: Arc<AppState>,
cx: &mut ViewContext<Workspace>,
) {
workspace.with_local_workspace(cx, app_state.clone(), |_, cx| {
workspace.with_local_workspace(&app_state.clone(), cx, move |_, cx| {
cx.spawn_weak(|workspace, mut cx| async move {
let workspace = workspace.upgrade(&cx)?;
let path = app_state.client.telemetry_log_file_path()?;
@ -596,31 +595,36 @@ fn open_telemetry_log_file(
Some(())
})
.detach();
});
}).detach();
}
fn open_bundled_config_file(
workspace: &mut Workspace,
app_state: Arc<AppState>,
asset_path: &'static str,
title: &str,
title: &'static str,
cx: &mut ViewContext<Workspace>,
) {
workspace.with_local_workspace(cx, app_state, |workspace, cx| {
let project = workspace.project().clone();
let buffer = project.update(cx, |project, cx| {
let text = Assets::get(asset_path).unwrap().data;
let text = str::from_utf8(text.as_ref()).unwrap();
project
.create_buffer(text, project.languages().get_language("JSON"), cx)
.expect("creating buffers on a local workspace always succeeds")
});
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx).with_title(title.into()));
workspace.add_item(
Box::new(cx.add_view(|cx| Editor::for_multibuffer(buffer, Some(project.clone()), cx))),
cx,
);
});
workspace
.with_local_workspace(&app_state.clone(), cx, |workspace, cx| {
let project = workspace.project().clone();
let buffer = project.update(cx, |project, cx| {
let text = Assets::get(asset_path).unwrap().data;
let text = str::from_utf8(text.as_ref()).unwrap();
project
.create_buffer(text, project.languages().get_language("JSON"), cx)
.expect("creating buffers on a local workspace always succeeds")
});
let buffer =
cx.add_model(|cx| MultiBuffer::singleton(buffer, cx).with_title(title.into()));
workspace.add_item(
Box::new(
cx.add_view(|cx| Editor::for_multibuffer(buffer, Some(project.clone()), cx)),
),
cx,
);
})
.detach();
}
fn schema_file_match(path: &Path) -> &Path {
@ -639,7 +643,7 @@ fn parse_pixel_position_env_var(value: &str) -> Option<Vector2F> {
mod tests {
use super::*;
use assets::Assets;
use editor::{Autoscroll, DisplayPoint, Editor};
use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor};
use gpui::{
executor::Deterministic, AssetSource, MutableAppContext, TestAppContext, ViewHandle,
};
@ -651,7 +655,8 @@ mod tests {
};
use theme::ThemeRegistry;
use workspace::{
open_paths, pane, Item, ItemHandle, NewFile, Pane, SplitDirection, WorkspaceHandle,
item::{Item, ItemHandle},
open_new, open_paths, pane, NewFile, Pane, SplitDirection, WorkspaceHandle,
};
#[gpui::test]
@ -787,7 +792,8 @@ mod tests {
#[gpui::test]
async fn test_new_empty_workspace(cx: &mut TestAppContext) {
let app_state = init(cx);
cx.dispatch_global_action(workspace::NewFile);
cx.update(|cx| open_new(&app_state, cx)).await;
let window_id = *cx.window_ids().first().unwrap();
let workspace = cx.root_view::<Workspace>(window_id).unwrap();
let editor = workspace.update(cx, |workspace, cx| {
@ -831,8 +837,9 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (_, workspace) =
cx.add_window(|cx| Workspace::new(project, |_, _| unimplemented!(), cx));
let (_, workspace) = cx.add_window(|cx| {
Workspace::new(Default::default(), 0, project, |_, _| unimplemented!(), cx)
});
let entries = cx.read(|cx| workspace.file_project_paths(cx));
let file1 = entries[0].clone();
@ -951,8 +958,9 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/dir1".as_ref()], cx).await;
let (_, workspace) =
cx.add_window(|cx| Workspace::new(project, |_, _| unimplemented!(), cx));
let (_, workspace) = cx.add_window(|cx| {
Workspace::new(Default::default(), 0, project, |_, _| unimplemented!(), cx)
});
// Open a file within an existing worktree.
cx.update(|cx| {
@ -1111,8 +1119,9 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (window_id, workspace) =
cx.add_window(|cx| Workspace::new(project, |_, _| unimplemented!(), cx));
let (window_id, workspace) = cx.add_window(|cx| {
Workspace::new(Default::default(), 0, project, |_, _| unimplemented!(), cx)
});
// Open a file within an existing worktree.
cx.update(|cx| {
@ -1154,8 +1163,9 @@ mod tests {
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
project.update(cx, |project, _| project.languages().add(rust_lang()));
let (window_id, workspace) =
cx.add_window(|cx| Workspace::new(project, |_, _| unimplemented!(), cx));
let (window_id, workspace) = cx.add_window(|cx| {
Workspace::new(Default::default(), 0, project, |_, _| unimplemented!(), cx)
});
let worktree = cx.read(|cx| workspace.read(cx).worktrees(cx).next().unwrap());
// Create a new untitled buffer
@ -1244,8 +1254,9 @@ mod tests {
let project = Project::test(app_state.fs.clone(), [], cx).await;
project.update(cx, |project, _| project.languages().add(rust_lang()));
let (window_id, workspace) =
cx.add_window(|cx| Workspace::new(project, |_, _| unimplemented!(), cx));
let (window_id, workspace) = cx.add_window(|cx| {
Workspace::new(Default::default(), 0, project, |_, _| unimplemented!(), cx)
});
// Create a new untitled buffer
cx.dispatch_action(window_id, NewFile);
@ -1298,8 +1309,9 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (window_id, workspace) =
cx.add_window(|cx| Workspace::new(project, |_, _| unimplemented!(), cx));
let (window_id, workspace) = cx.add_window(|cx| {
Workspace::new(Default::default(), 0, project, |_, _| unimplemented!(), cx)
});
let entries = cx.read(|cx| workspace.file_project_paths(cx));
let file1 = entries[0].clone();
@ -1373,8 +1385,15 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (_, workspace) =
cx.add_window(|cx| Workspace::new(project.clone(), |_, _| unimplemented!(), cx));
let (_, workspace) = cx.add_window(|cx| {
Workspace::new(
Default::default(),
0,
project.clone(),
|_, _| unimplemented!(),
cx,
)
});
let entries = cx.read(|cx| workspace.file_project_paths(cx));
let file1 = entries[0].clone();
@ -1638,8 +1657,15 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (_, workspace) =
cx.add_window(|cx| Workspace::new(project.clone(), |_, _| unimplemented!(), cx));
let (_, workspace) = cx.add_window(|cx| {
Workspace::new(
Default::default(),
0,
project.clone(),
|_, _| unimplemented!(),
cx,
)
});
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let entries = cx.read(|cx| workspace.file_project_paths(cx));