db to save lapce workspace info

This commit is contained in:
Dongdong Zhou 2021-10-27 22:10:24 +01:00
parent f3607dd822
commit 331252460e
8 changed files with 140 additions and 12 deletions

29
Cargo.lock generated
View File

@ -498,7 +498,7 @@ dependencies = [
"clicolors-control",
"lazy_static 1.4.0",
"libc",
"parking_lot 0.6.4",
"parking_lot 0.11.2",
"regex",
"termios",
"unicode-width",
@ -1326,6 +1326,16 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]]
name = "fsevent"
version = "0.4.0"
@ -1960,6 +1970,7 @@ dependencies = [
"regex",
"serde 1.0.130",
"serde_json",
"sled",
"strum",
"strum_macros",
"tinyfiledialogs",
@ -3668,6 +3679,22 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
[[package]]
name = "sled"
version = "0.34.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935"
dependencies = [
"crc32fast",
"crossbeam-epoch 0.9.5",
"crossbeam-utils 0.8.5",
"fs2",
"fxhash",
"libc",
"log",
"parking_lot 0.11.2",
]
[[package]]
name = "slotmap"
version = "1.0.6"

View File

@ -5,6 +5,7 @@ authors = ["Dongdong Zhou <dzhou121@gmail.com>"]
edition = "2021"
[dependencies]
sled = "0.34.7"
base64 = "0.13.0"
alacritty_terminal = "0.15.0"
config = "0.11"

View File

@ -32,7 +32,7 @@
Location, Position, TextEdit, WorkspaceClientCapabilities,
};
use parking_lot::Mutex;
use serde::{Deserialize, Deserializer};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use tree_sitter::{Node, Parser};
use tree_sitter_highlight::{
@ -60,6 +60,7 @@
},
completion::{CompletionData, CompletionStatus, Snippet},
config::{Config, LapceTheme},
db::LapceDb,
editor::{EditorLocationNew, LapceEditorBufferData, LapceEditorViewContent},
find::Find,
keypress::{KeyPressData, KeyPressFocus},
@ -121,6 +122,7 @@ pub struct LapceWindowData {
pub keypress: Arc<KeyPressData>,
pub theme: Arc<std::collections::HashMap<String, Color>>,
pub config: Arc<Config>,
pub db: Arc<LapceDb>,
}
impl Data for LapceWindowData {
@ -134,9 +136,16 @@ pub fn new(
keypress: Arc<KeyPressData>,
theme: Arc<std::collections::HashMap<String, Color>>,
) -> Self {
let db = Arc::new(LapceDb::new().unwrap());
let mut tabs = im::HashMap::new();
let tab_id = WidgetId::next();
let tab = LapceTabData::new(tab_id, keypress.clone(), theme.clone(), None);
let tab = LapceTabData::new(
tab_id,
db.clone(),
keypress.clone(),
theme.clone(),
None,
);
tabs.insert(tab_id, tab);
let config = Arc::new(Config::load(None).unwrap_or_default());
Self {
@ -146,6 +155,7 @@ pub fn new(
keypress,
theme,
config,
db,
}
}
}
@ -245,6 +255,7 @@ pub struct LapceTabData {
pub config: Arc<Config>,
pub focus: WidgetId,
pub focus_area: FocusArea,
pub db: Arc<LapceDb>,
}
impl Data for LapceTabData {
@ -269,6 +280,7 @@ fn same(&self, other: &Self) -> bool {
impl LapceTabData {
pub fn new(
tab_id: WidgetId,
db: Arc<LapceDb>,
keypress: Arc<KeyPressData>,
theme: Arc<std::collections::HashMap<String, Color>>,
event_sink: Option<ExtEventSink>,
@ -345,6 +357,7 @@ pub fn new(
panel_active: PanelPosition::LeftTop,
config,
focus_area: FocusArea::Editor,
db,
};
if let Some(event_sink) = event_sink {
tab.start_update_process(event_sink);
@ -1471,7 +1484,7 @@ pub enum LapceEditorContainerKind {
DiffSplit(WidgetId, WidgetId),
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum EditorContent {
Buffer(PathBuf),
None,

64
core/src/db.rs Normal file
View File

@ -0,0 +1,64 @@
use anyhow::{anyhow, Result};
use directories::ProjectDirs;
use druid::Vec2;
use serde::{Deserialize, Serialize};
use crate::{
data::{EditorContent, EditorType, LapceTabData},
movement::Cursor,
state::LapceWorkspace,
};
pub struct LapceDb {
db: sled::Db,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct WorkspaceInfo {
pub editors: Vec<EditorInfo>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct EditorInfo {
pub content: EditorContent,
pub scroll_offset: (f64, f64),
pub cursor: Cursor,
}
impl LapceDb {
pub fn new() -> Result<Self> {
let proj_dirs = ProjectDirs::from("", "", "Lapce")
.ok_or(anyhow!("can't find project dirs"))?;
let path = proj_dirs.config_dir().join("lapce.db");
let db = sled::Config::default()
.path(path)
.flush_every_ms(None)
.open()?;
Ok(Self { db })
}
pub fn save_workspace(&self, data: &LapceTabData) -> Result<()> {
let workspace = data.workspace.as_ref().ok_or(anyhow!("no workspace"))?;
let editors = data
.main_split
.editors
.iter()
.filter_map(|(_, editor)| match &editor.editor_type {
EditorType::Normal => Some(EditorInfo {
content: editor.content.clone(),
scroll_offset: (editor.scroll_offset.x, editor.scroll_offset.y),
cursor: editor.cursor.clone(),
}),
_ => None,
})
.collect();
let workspace_info = WorkspaceInfo { editors };
let workspace_info = serde_json::to_string(&workspace_info)?;
let workspace = workspace.to_string();
self.db
.insert(workspace.as_bytes(), workspace_info.as_bytes())?;
self.db.flush()?;
println!("db save workspace done {} {}", workspace, workspace_info);
Ok(())
}
}

View File

@ -6,6 +6,7 @@
pub mod config;
pub mod container;
mod data;
pub mod db;
pub mod editor;
pub mod explorer;
pub mod find;

View File

@ -1,4 +1,5 @@
use druid::{piet::PietText, Env, Point, Rect, Size};
use serde::{Deserialize, Serialize};
use xi_core_lib::selection::InsertDrift;
use xi_rope::{RopeDelta, Transformer};
@ -11,13 +12,13 @@
};
use std::cmp::{max, min};
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Cursor {
pub mode: CursorMode,
pub horiz: Option<ColPosition>,
}
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum CursorMode {
Normal(usize),
Visual {
@ -241,7 +242,7 @@ pub fn apply_delta(&mut self, delta: &RopeDelta) {
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
pub enum ColPosition {
FirstNonBlank,
Start,
@ -249,7 +250,7 @@ pub enum ColPosition {
Col(usize),
}
#[derive(Clone, Copy, PartialEq, Debug)]
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
pub struct SelRegion {
start: usize,
end: usize,
@ -313,7 +314,7 @@ fn merge_with(self, other: SelRegion) -> SelRegion {
}
}
#[derive(Clone, PartialEq, Debug)]
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Selection {
regions: Vec<SelRegion>,
}

View File

@ -12,6 +12,7 @@
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::json;
use serde_json::Value;
use std::fmt::Display;
use std::process::Child;
use std::process::Command;
use std::process::Stdio;
@ -41,7 +42,7 @@ pub enum LapceFocus {
SourceControl,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy)]
#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, Deserialize, Serialize)]
pub enum VisualMode {
Normal,
Linewise,
@ -76,13 +77,24 @@ pub struct KeyMap {
pub command: String,
}
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum LapceWorkspaceType {
Local,
RemoteSSH(String, String),
}
#[derive(Clone, Debug, PartialEq)]
impl Display for LapceWorkspaceType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LapceWorkspaceType::Local => f.write_str("Local"),
LapceWorkspaceType::RemoteSSH(user, host) => {
write!(f, "ssh://{}@{}", user, host)
}
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct LapceWorkspace {
pub kind: LapceWorkspaceType,
pub path: PathBuf,
@ -105,6 +117,12 @@ fn default() -> Self {
}
}
impl Display for LapceWorkspace {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}:{}", self.kind, self.path.to_str().unwrap())
}
}
pub struct Counter(AtomicU64);
impl Counter {

View File

@ -65,6 +65,7 @@ pub fn new_tab(
let tab_id = WidgetId::next();
let mut tab_data = LapceTabData::new(
tab_id,
data.db.clone(),
data.keypress.clone(),
data.theme.clone(),
Some(ctx.get_external_handle()),
@ -77,6 +78,7 @@ pub fn new_tab(
self.tabs[data.active] = WidgetPod::new(tab.boxed());
self.tab_headers[data.active] = WidgetPod::new(tab_header);
if let Some(tab) = data.tabs.remove(&data.active_id) {
tab.db.save_workspace(&tab);
tab.proxy.stop();
}
data.active_id = tab_id;
@ -113,6 +115,7 @@ pub fn close_index_tab(
self.tabs.remove(index);
self.tab_headers.remove(index);
if let Some(tab) = data.tabs.remove(&id) {
tab.db.save_workspace(&tab);
tab.proxy.stop();
}