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

@ -1,20 +1,18 @@
use std::path::PathBuf;
use db::{define_connection, query, sqlez_macros::sql};
use workspace::{WorkspaceDb, WorkspaceId};
type ModelId = usize;
use workspace::{ItemId, WorkspaceDb, WorkspaceId};
define_connection! {
pub static ref TERMINAL_DB: TerminalDb<WorkspaceDb> =
&[sql!(
CREATE TABLE terminals (
workspace_id INTEGER,
model_id INTEGER UNIQUE,
item_id INTEGER UNIQUE,
working_directory BLOB,
PRIMARY KEY(workspace_id, model_id),
PRIMARY KEY(workspace_id, item_id),
FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id)
ON DELETE CASCADE
ON DELETE CASCADE
) STRICT;
)];
}
@ -24,7 +22,7 @@ impl TerminalDb {
pub async fn update_workspace_id(
new_id: WorkspaceId,
old_id: WorkspaceId,
item_id: ModelId
item_id: ItemId
) -> Result<()> {
UPDATE terminals
SET workspace_id = ?
@ -34,8 +32,8 @@ impl TerminalDb {
query! {
pub async fn save_working_directory(
item_id: ModelId,
workspace_id: i64,
item_id: ItemId,
workspace_id: WorkspaceId,
working_directory: PathBuf
) -> Result<()> {
INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory)
@ -44,10 +42,10 @@ impl TerminalDb {
}
query! {
pub fn get_working_directory(item_id: ModelId, workspace_id: WorkspaceId) -> Result<Option<PathBuf>> {
SELECT working_directory
FROM terminals
pub async fn take_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> Result<Option<PathBuf>> {
DELETE FROM terminals
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 project::{LocalWorktree, Project, ProjectPath};
use settings::{AlternateScroll, Settings, WorkingDirectory};
use settings::{Settings, WorkingDirectory};
use smallvec::SmallVec;
use std::ops::RangeInclusive;
use std::path::{Path, PathBuf};
@ -99,25 +99,13 @@ impl TerminalContainer {
pub fn new(
working_directory: Option<PathBuf>,
modal: bool,
_workspace_id: WorkspaceId,
workspace_id: WorkspaceId,
cx: &mut ViewContext<Self>,
) -> Self {
let settings = cx.global::<Settings>();
let shell = settings.terminal_overrides.shell.clone();
let envs = settings.terminal_overrides.env.clone(); //Should be short and cheap.
//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 shell = settings.terminal_shell();
let envs = settings.terminal_env();
let scroll = settings.terminal_scroll();
let content = match TerminalBuilder::new(
working_directory.clone(),
@ -129,7 +117,10 @@ impl TerminalContainer {
) {
Ok(terminal) => {
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))
.detach();
@ -394,25 +385,26 @@ impl Item for TerminalContainer {
item_id: workspace::ItemId,
cx: &mut ViewContext<Pane>,
) -> Task<anyhow::Result<ViewHandle<Self>>> {
let working_directory = TERMINAL_DB.get_working_directory(item_id, workspace_id);
Task::ready(Ok(cx.add_view(|cx| {
TerminalContainer::new(
working_directory.log_err().flatten(),
false,
workspace_id,
cx,
)
})))
cx.spawn(|pane, mut cx| async move {
let cwd = TERMINAL_DB
.take_working_directory(item_id, workspace_id)
.await
.log_err()
.flatten();
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>) {
if let Some(_connected) = self.connected() {
// let id = workspace.database_id();
// let terminal_handle = connected.read(cx).terminal().clone();
//TODO
cx.background()
.spawn(TERMINAL_DB.update_workspace_id(0, 0, 0))
.detach();
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
if let Some(connected) = self.connected() {
connected.update(cx, |connected_view, cx| {
connected_view.added_to_workspace(workspace.database_id(), cx);
})
}
}
}

View file

@ -18,7 +18,7 @@ use ordered_float::OrderedFloat;
use settings::Settings;
use terminal::{
alacritty_terminal::{
ansi::{Color as AnsiColor, CursorShape as AlacCursorShape, NamedColor},
ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
grid::Dimensions,
index::Point,
term::{cell::Flags, TermMode},
@ -198,10 +198,7 @@ impl TerminalElement {
//Expand background rect range
{
if matches!(
bg,
terminal::alacritty_terminal::ansi::Color::Named(NamedColor::Background)
) {
if matches!(bg, Named(NamedColor::Background)) {
//Continue to next cell, resetting variables if nescessary
cur_alac_color = None;
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
//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
} else {
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 gpui::{
@ -21,7 +21,7 @@ use terminal::{
Terminal,
};
use util::ResultExt;
use workspace::pane;
use workspace::{pane, ItemId, WorkspaceId};
use crate::{persistence::TERMINAL_DB, terminal_element::TerminalElement, Event};
@ -75,6 +75,8 @@ pub struct TerminalView {
blinking_on: bool,
blinking_paused: bool,
blink_epoch: usize,
workspace_id: WorkspaceId,
item_id: ItemId,
}
impl Entity for TerminalView {
@ -85,6 +87,8 @@ impl TerminalView {
pub fn from_terminal(
terminal: ModelHandle<Terminal>,
modal: bool,
workspace_id: WorkspaceId,
item_id: ItemId,
cx: &mut ViewContext<Self>,
) -> Self {
cx.observe(&terminal, |_, _, cx| cx.notify()).detach();
@ -102,20 +106,20 @@ impl TerminalView {
}
Event::BlinkChanged => this.blinking_on = !this.blinking_on,
Event::TitleChanged => {
// if let Some(foreground_info) = &terminal.read(cx).foreground_process_info {
// let cwd = foreground_info.cwd.clone();
//TODO
// let item_id = self.item_id;
// let workspace_id = self.workspace_id;
cx.background()
.spawn(async move {
TERMINAL_DB
.save_working_directory(0, 0, PathBuf::new())
.await
.log_err();
})
.detach();
// }
if let Some(foreground_info) = &this.terminal().read(cx).foreground_process_info {
let cwd = foreground_info.cwd.clone();
let item_id = this.item_id;
let workspace_id = this.workspace_id;
cx.background()
.spawn(async move {
TERMINAL_DB
.save_working_directory(item_id, workspace_id, cwd)
.await
.log_err();
})
.detach();
}
}
_ => cx.emit(*event),
})
@ -131,6 +135,8 @@ impl TerminalView {
blinking_on: false,
blinking_paused: false,
blink_epoch: 0,
workspace_id,
item_id,
}
}
@ -282,6 +288,13 @@ impl TerminalView {
&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 {
self.blink_epoch += 1;
self.blink_epoch