Fix bugs resulting from refactoring the terminal into project and workspace halves

This commit is contained in:
Mikayla Maki 2022-12-08 15:18:24 -08:00
parent 83aefffa38
commit 2733f91d8c
7 changed files with 101 additions and 76 deletions

View file

@ -199,10 +199,10 @@ macro_rules! query {
use $crate::anyhow::Context; use $crate::anyhow::Context;
self.write(|connection| { self.write(move |connection| {
let sql_stmt = $crate::sqlez_macros::sql!($($sql)+); let sql_stmt = $crate::sqlez_macros::sql!($($sql)+);
connection.select_row_bound::<($($arg_type),+), $return_type>(indoc! { $sql })?(($($arg),+)) connection.select_row_bound::<($($arg_type),+), $return_type>(sql_stmt)?(($($arg),+))
.context(::std::format!( .context(::std::format!(
"Error in {}, select_row_bound failed to execute or parse for: {}", "Error in {}, select_row_bound failed to execute or parse for: {}",
::std::stringify!($id), ::std::stringify!($id),

View file

@ -199,7 +199,7 @@ impl Default for Shell {
} }
} }
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum AlternateScroll { pub enum AlternateScroll {
On, On,
@ -473,6 +473,32 @@ impl Settings {
}) })
} }
pub fn terminal_scroll(&self) -> AlternateScroll {
*self.terminal_overrides.alternate_scroll.as_ref().unwrap_or(
self.terminal_defaults
.alternate_scroll
.as_ref()
.unwrap_or_else(|| &AlternateScroll::On),
)
}
pub fn terminal_shell(&self) -> Option<Shell> {
self.terminal_overrides
.shell
.as_ref()
.or(self.terminal_defaults.shell.as_ref())
.cloned()
}
pub fn terminal_env(&self) -> HashMap<String, String> {
self.terminal_overrides.env.clone().unwrap_or_else(|| {
self.terminal_defaults
.env
.clone()
.unwrap_or_else(|| HashMap::default())
})
}
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
pub fn test(cx: &gpui::AppContext) -> Settings { pub fn test(cx: &gpui::AppContext) -> Settings {
Settings { Settings {

View file

@ -269,9 +269,9 @@ impl TerminalBuilder {
pub fn new( pub fn new(
working_directory: Option<PathBuf>, working_directory: Option<PathBuf>,
shell: Option<Shell>, shell: Option<Shell>,
env: Option<HashMap<String, String>>, mut env: HashMap<String, String>,
blink_settings: Option<TerminalBlink>, blink_settings: Option<TerminalBlink>,
alternate_scroll: &AlternateScroll, alternate_scroll: AlternateScroll,
window_id: usize, window_id: usize,
) -> Result<TerminalBuilder> { ) -> Result<TerminalBuilder> {
let pty_config = { let pty_config = {
@ -288,10 +288,9 @@ impl TerminalBuilder {
} }
}; };
let mut env = env.unwrap_or_default();
//TODO: Properly set the current locale, //TODO: Properly set the current locale,
env.insert("LC_ALL".to_string(), "en_US.UTF-8".to_string()); env.insert("LC_ALL".to_string(), "en_US.UTF-8".to_string());
env.insert("ZED_TERM".to_string(), true.to_string());
let alac_scrolling = Scrolling::default(); let alac_scrolling = Scrolling::default();
// alac_scrolling.set_history((BACK_BUFFER_SIZE * 2) as u32); // alac_scrolling.set_history((BACK_BUFFER_SIZE * 2) as u32);

View file

@ -1,18 +1,16 @@
use std::path::PathBuf; use std::path::PathBuf;
use db::{define_connection, query, sqlez_macros::sql}; use db::{define_connection, query, sqlez_macros::sql};
use workspace::{WorkspaceDb, WorkspaceId}; use workspace::{ItemId, WorkspaceDb, WorkspaceId};
type ModelId = usize;
define_connection! { define_connection! {
pub static ref TERMINAL_DB: TerminalDb<WorkspaceDb> = pub static ref TERMINAL_DB: TerminalDb<WorkspaceDb> =
&[sql!( &[sql!(
CREATE TABLE terminals ( CREATE TABLE terminals (
workspace_id INTEGER, workspace_id INTEGER,
model_id INTEGER UNIQUE, item_id INTEGER UNIQUE,
working_directory BLOB, working_directory BLOB,
PRIMARY KEY(workspace_id, model_id), PRIMARY KEY(workspace_id, item_id),
FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id)
ON DELETE CASCADE ON DELETE CASCADE
) STRICT; ) STRICT;
@ -24,7 +22,7 @@ impl TerminalDb {
pub async fn update_workspace_id( pub async fn update_workspace_id(
new_id: WorkspaceId, new_id: WorkspaceId,
old_id: WorkspaceId, old_id: WorkspaceId,
item_id: ModelId item_id: ItemId
) -> Result<()> { ) -> Result<()> {
UPDATE terminals UPDATE terminals
SET workspace_id = ? SET workspace_id = ?
@ -34,8 +32,8 @@ impl TerminalDb {
query! { query! {
pub async fn save_working_directory( pub async fn save_working_directory(
item_id: ModelId, item_id: ItemId,
workspace_id: i64, workspace_id: WorkspaceId,
working_directory: PathBuf working_directory: PathBuf
) -> Result<()> { ) -> Result<()> {
INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory) INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory)
@ -44,10 +42,10 @@ impl TerminalDb {
} }
query! { query! {
pub fn get_working_directory(item_id: ModelId, workspace_id: WorkspaceId) -> Result<Option<PathBuf>> { pub async fn take_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> Result<Option<PathBuf>> {
SELECT working_directory DELETE FROM terminals
FROM terminals
WHERE item_id = ? AND workspace_id = ? WHERE item_id = ? AND workspace_id = ?
RETURNING working_directory
} }
} }
} }

View file

@ -22,7 +22,7 @@ use workspace::{
use workspace::{register_deserializable_item, Pane, WorkspaceId}; use workspace::{register_deserializable_item, Pane, WorkspaceId};
use project::{LocalWorktree, Project, ProjectPath}; use project::{LocalWorktree, Project, ProjectPath};
use settings::{AlternateScroll, Settings, WorkingDirectory}; use settings::{Settings, WorkingDirectory};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -99,25 +99,13 @@ impl TerminalContainer {
pub fn new( pub fn new(
working_directory: Option<PathBuf>, working_directory: Option<PathBuf>,
modal: bool, modal: bool,
_workspace_id: WorkspaceId, workspace_id: WorkspaceId,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Self { ) -> Self {
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
let shell = settings.terminal_overrides.shell.clone(); let shell = settings.terminal_shell();
let envs = settings.terminal_overrides.env.clone(); //Should be short and cheap. let envs = settings.terminal_env();
let scroll = settings.terminal_scroll();
//TODO: move this pattern to settings
let scroll = settings
.terminal_overrides
.alternate_scroll
.as_ref()
.unwrap_or(
settings
.terminal_defaults
.alternate_scroll
.as_ref()
.unwrap_or_else(|| &AlternateScroll::On),
);
let content = match TerminalBuilder::new( let content = match TerminalBuilder::new(
working_directory.clone(), working_directory.clone(),
@ -129,7 +117,10 @@ impl TerminalContainer {
) { ) {
Ok(terminal) => { Ok(terminal) => {
let terminal = cx.add_model(|cx| terminal.subscribe(cx)); let terminal = cx.add_model(|cx| terminal.subscribe(cx));
let view = cx.add_view(|cx| TerminalView::from_terminal(terminal, modal, cx)); let item_id = cx.view_id();
let view = cx.add_view(|cx| {
TerminalView::from_terminal(terminal, modal, workspace_id, item_id, cx)
});
cx.subscribe(&view, |_this, _content, event, cx| cx.emit(*event)) cx.subscribe(&view, |_this, _content, event, cx| cx.emit(*event))
.detach(); .detach();
@ -394,25 +385,26 @@ impl Item for TerminalContainer {
item_id: workspace::ItemId, item_id: workspace::ItemId,
cx: &mut ViewContext<Pane>, cx: &mut ViewContext<Pane>,
) -> Task<anyhow::Result<ViewHandle<Self>>> { ) -> Task<anyhow::Result<ViewHandle<Self>>> {
let working_directory = TERMINAL_DB.get_working_directory(item_id, workspace_id); cx.spawn(|pane, mut cx| async move {
Task::ready(Ok(cx.add_view(|cx| { let cwd = TERMINAL_DB
TerminalContainer::new( .take_working_directory(item_id, workspace_id)
working_directory.log_err().flatten(), .await
false, .log_err()
workspace_id, .flatten();
cx,
) cx.update(|cx| {
}))) Ok(cx.add_view(pane, |cx| {
TerminalContainer::new(cwd, false, workspace_id, cx)
}))
})
})
} }
fn added_to_workspace(&mut self, _workspace: &mut Workspace, cx: &mut ViewContext<Self>) { fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
if let Some(_connected) = self.connected() { if let Some(connected) = self.connected() {
// let id = workspace.database_id(); connected.update(cx, |connected_view, cx| {
// let terminal_handle = connected.read(cx).terminal().clone(); connected_view.added_to_workspace(workspace.database_id(), cx);
//TODO })
cx.background()
.spawn(TERMINAL_DB.update_workspace_id(0, 0, 0))
.detach();
} }
} }
} }

View file

@ -18,7 +18,7 @@ use ordered_float::OrderedFloat;
use settings::Settings; use settings::Settings;
use terminal::{ use terminal::{
alacritty_terminal::{ alacritty_terminal::{
ansi::{Color as AnsiColor, CursorShape as AlacCursorShape, NamedColor}, ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
grid::Dimensions, grid::Dimensions,
index::Point, index::Point,
term::{cell::Flags, TermMode}, term::{cell::Flags, TermMode},
@ -198,10 +198,7 @@ impl TerminalElement {
//Expand background rect range //Expand background rect range
{ {
if matches!( if matches!(bg, Named(NamedColor::Background)) {
bg,
terminal::alacritty_terminal::ansi::Color::Named(NamedColor::Background)
) {
//Continue to next cell, resetting variables if nescessary //Continue to next cell, resetting variables if nescessary
cur_alac_color = None; cur_alac_color = None;
if let Some(rect) = cur_rect { if let Some(rect) = cur_rect {
@ -639,7 +636,7 @@ impl Element for TerminalElement {
//Layout cursor. Rectangle is used for IME, so we should lay it out even //Layout cursor. Rectangle is used for IME, so we should lay it out even
//if we don't end up showing it. //if we don't end up showing it.
let cursor = if let terminal::alacritty_terminal::ansi::CursorShape::Hidden = cursor.shape { let cursor = if let AlacCursorShape::Hidden = cursor.shape {
None None
} else { } else {
let cursor_point = DisplayCursor::from(cursor.point, *display_offset); let cursor_point = DisplayCursor::from(cursor.point, *display_offset);

View file

@ -1,4 +1,4 @@
use std::{ops::RangeInclusive, path::PathBuf, time::Duration}; use std::{ops::RangeInclusive, time::Duration};
use context_menu::{ContextMenu, ContextMenuItem}; use context_menu::{ContextMenu, ContextMenuItem};
use gpui::{ use gpui::{
@ -21,7 +21,7 @@ use terminal::{
Terminal, Terminal,
}; };
use util::ResultExt; use util::ResultExt;
use workspace::pane; use workspace::{pane, ItemId, WorkspaceId};
use crate::{persistence::TERMINAL_DB, terminal_element::TerminalElement, Event}; use crate::{persistence::TERMINAL_DB, terminal_element::TerminalElement, Event};
@ -75,6 +75,8 @@ pub struct TerminalView {
blinking_on: bool, blinking_on: bool,
blinking_paused: bool, blinking_paused: bool,
blink_epoch: usize, blink_epoch: usize,
workspace_id: WorkspaceId,
item_id: ItemId,
} }
impl Entity for TerminalView { impl Entity for TerminalView {
@ -85,6 +87,8 @@ impl TerminalView {
pub fn from_terminal( pub fn from_terminal(
terminal: ModelHandle<Terminal>, terminal: ModelHandle<Terminal>,
modal: bool, modal: bool,
workspace_id: WorkspaceId,
item_id: ItemId,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Self { ) -> Self {
cx.observe(&terminal, |_, _, cx| cx.notify()).detach(); cx.observe(&terminal, |_, _, cx| cx.notify()).detach();
@ -102,20 +106,20 @@ impl TerminalView {
} }
Event::BlinkChanged => this.blinking_on = !this.blinking_on, Event::BlinkChanged => this.blinking_on = !this.blinking_on,
Event::TitleChanged => { Event::TitleChanged => {
// if let Some(foreground_info) = &terminal.read(cx).foreground_process_info { if let Some(foreground_info) = &this.terminal().read(cx).foreground_process_info {
// let cwd = foreground_info.cwd.clone(); let cwd = foreground_info.cwd.clone();
//TODO
// let item_id = self.item_id; let item_id = this.item_id;
// let workspace_id = self.workspace_id; let workspace_id = this.workspace_id;
cx.background() cx.background()
.spawn(async move { .spawn(async move {
TERMINAL_DB TERMINAL_DB
.save_working_directory(0, 0, PathBuf::new()) .save_working_directory(item_id, workspace_id, cwd)
.await .await
.log_err(); .log_err();
}) })
.detach(); .detach();
// } }
} }
_ => cx.emit(*event), _ => cx.emit(*event),
}) })
@ -131,6 +135,8 @@ impl TerminalView {
blinking_on: false, blinking_on: false,
blinking_paused: false, blinking_paused: false,
blink_epoch: 0, blink_epoch: 0,
workspace_id,
item_id,
} }
} }
@ -282,6 +288,13 @@ impl TerminalView {
&self.terminal &self.terminal
} }
pub fn added_to_workspace(&mut self, new_id: WorkspaceId, cx: &mut ViewContext<Self>) {
cx.background()
.spawn(TERMINAL_DB.update_workspace_id(new_id, self.workspace_id, self.item_id))
.detach();
self.workspace_id = new_id;
}
fn next_blink_epoch(&mut self) -> usize { fn next_blink_epoch(&mut self) -> usize {
self.blink_epoch += 1; self.blink_epoch += 1;
self.blink_epoch self.blink_epoch