diff --git a/Cargo.lock b/Cargo.lock index d8c9ceae..e27c7e81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,6 +234,7 @@ dependencies = [ "git2", "itertools 0.9.0", "log", + "scopetime", "simplelog", "tui", ] @@ -522,6 +523,13 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scopetime" +version = "0.1.0" +dependencies = [ + "log", +] + [[package]] name = "signal-hook" version = "0.1.13" diff --git a/Cargo.toml b/Cargo.toml index d2955ee8..03308909 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,9 @@ itertools = "0.9" log = "0.4" simplelog = "0.7" dirs = "2.0" -tui = { version = "0.8", default-features = false, features = ['crossterm'] } \ No newline at end of file +scopetime = { path = "./scopetime" } +tui = { version = "0.8", default-features=false, features = ['crossterm'] } + +[features] +default=[] +timing=["scopetime/enabled"] diff --git a/README.md b/README.md index cebace46..0b5c8f1a 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,9 @@ gitui * [x] inspect diffs * [x] commit * [x] [input polling in thread](assets/perf_compare.jpg) -* [x] only ask git when necessary. maybe in a worker thread? -* [ ] show content of new files +* [ ] put libgit calls in threadpool +* [ ] show content of new unstaged files * [ ] discard untracked files (remove) -* [ ] use [notify](https://crates.io/crates/notify) to watch git -* [ ] log view -* [ ] stashing support * [ ] (un)staging selected hunks # resources (quick links) diff --git a/scopetime/Cargo.toml b/scopetime/Cargo.toml new file mode 100644 index 00000000..26442ee3 --- /dev/null +++ b/scopetime/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "scopetime" +version = "0.1.0" +authors = ["Stephan Dilly "] +edition = "2018" + +[dependencies] +log = "0.4" + +[features] +default=[] +enabled=[] \ No newline at end of file diff --git a/scopetime/src/lib.rs b/scopetime/src/lib.rs new file mode 100644 index 00000000..6fc05cb1 --- /dev/null +++ b/scopetime/src/lib.rs @@ -0,0 +1,64 @@ +use log::trace; +use std::time::Instant; + +/// +pub struct ScopeTimeLog<'a> { + title: &'a str, + mod_path: &'a str, + file: &'a str, + line: u32, + time: Instant, +} + +/// +impl<'a> ScopeTimeLog<'a> { + /// + pub fn new( + mod_path: &'a str, + title: &'a str, + file: &'a str, + line: u32, + ) -> Self { + Self { + title, + mod_path, + file, + line, + time: Instant::now(), + } + } +} + +impl<'a> Drop for ScopeTimeLog<'a> { + fn drop(&mut self) { + trace!( + "scopetime: {:?} ms [{}::{}] @{}:{}", + self.time.elapsed().as_millis(), + self.mod_path, + self.title, + self.file, + self.line, + ); + } +} + +#[cfg(feature = "enabled")] +#[macro_export] +macro_rules! scope_time { + ($target:literal) => { + //TODO: add module_path!() aswell? + #[allow(unused_variables)] + let time = $crate::ScopeTimeLog::new( + module_path!(), + $target, + file!(), + line!(), + ); + }; +} + +#[cfg(not(feature = "enabled"))] +#[macro_export] +macro_rules! scope_time { + ($target:literal) => {}; +} diff --git a/src/app.rs b/src/app.rs index fd51fbd2..eadd9e46 100644 --- a/src/app.rs +++ b/src/app.rs @@ -191,7 +191,8 @@ impl App { /// pub fn update(&mut self) { - trace!("update"); + trace!("app::update"); + self.index.update(); self.index_wd.update(); self.update_diff(); @@ -230,6 +231,11 @@ impl App { fn commands(&self) -> Vec { let mut res = Vec::new(); if !self.commit.is_visible() { + res.push(CommandInfo { + name: strings::COMMIT_CMD_OPEN.to_string(), + enabled: !self.index.is_empty(), + }); + if self.index_wd.focused() { let some_selection = self.index_wd.selection().is_some(); diff --git a/src/components/commit.rs b/src/components/commit.rs index dc1e2aaf..39fc835b 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -44,10 +44,7 @@ impl Component for CommitComponent { fn commands(&self) -> Vec { if !self.visible { - vec![CommandInfo { - name: strings::COMMIT_CMD_OPEN.to_string(), - enabled: !git_utils::index_empty(), - }] + vec![] } else { vec![ CommandInfo { diff --git a/src/components/index.rs b/src/components/index.rs index 93e907d1..acef03fe 100644 --- a/src/components/index.rs +++ b/src/components/index.rs @@ -1,12 +1,10 @@ -use crate::components::CommandInfo; -use crate::components::Component; +use crate::components::{CommandInfo, Component}; use crate::{ - git_status::{self, StatusItem}, + git_status::{self, StatusItem, StatusItemType}, tui_utils, }; use crossterm::event::{Event, KeyCode}; use git2::StatusShow; -use git_status::StatusItemType; use std::{borrow::Cow, cmp}; use tui::{ backend::Backend, @@ -68,6 +66,11 @@ impl IndexComponent { self.show_selection = focus; } + /// + pub fn is_empty(&self) -> bool { + self.items.is_empty() + } + fn move_selection(&mut self, delta: i32) { let items_len = self.items.len(); if items_len > 0 { diff --git a/src/git_status.rs b/src/git_status.rs index eb848f0f..625e23ec 100644 --- a/src/git_status.rs +++ b/src/git_status.rs @@ -1,5 +1,6 @@ use crate::git_utils; use git2::{Status, StatusOptions, StatusShow}; +use scopetime::scope_time; #[derive(PartialEq, Copy, Clone)] pub enum StatusItemType { @@ -33,6 +34,8 @@ pub struct StatusItem { } pub fn get_index(show: StatusShow) -> Vec { + scope_time!("get_index"); + let repo = git_utils::repo(); let mut res = Vec::new(); diff --git a/src/git_utils.rs b/src/git_utils.rs index eeaa4745..34036a87 100644 --- a/src/git_utils.rs +++ b/src/git_utils.rs @@ -3,6 +3,7 @@ use git2::{ ObjectType, Repository, RepositoryOpenFlags, StatusOptions, StatusShow, }; +use scopetime::scope_time; use std::path::Path; /// @@ -33,6 +34,8 @@ pub struct Diff(pub Vec); /// pub fn get_diff(p: &Path, stage: bool) -> Diff { + scope_time!("get_diff"); + let repo = repo(); let mut opt = DiffOptions::new(); @@ -108,6 +111,8 @@ pub fn repo() -> Repository { /// pub fn commit(msg: &String) { + scope_time!("commit"); + let repo = repo(); let signature = repo.signature().unwrap(); @@ -131,6 +136,8 @@ pub fn commit(msg: &String) { /// pub fn index_empty() -> bool { + scope_time!("index_empty"); + let repo = repo(); let statuses = repo @@ -143,6 +150,8 @@ pub fn index_empty() -> bool { } pub fn stage_add(path: &Path) -> bool { + scope_time!("stage_add"); + let repo = repo(); let mut index = repo.index().unwrap(); @@ -168,6 +177,8 @@ pub fn stage_add(path: &Path) -> bool { } pub fn stage_reset(path: &Path) -> bool { + scope_time!("stage_reset"); + let repo = repo(); let reference = repo.head().unwrap(); @@ -186,6 +197,8 @@ pub fn stage_reset(path: &Path) -> bool { } pub fn index_reset(path: &Path) -> bool { + scope_time!("index_reset"); + let repo = repo(); let mut checkout_opts = CheckoutBuilder::new(); diff --git a/src/main.rs b/src/main.rs index 08567415..1146ee3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ use crossterm::{ }, ExecutableCommand, Result, }; +use scopetime::scope_time; use simplelog::*; use std::{env, fs, fs::File, io}; use tui::{backend::CrosstermBackend, Terminal}; @@ -41,18 +42,22 @@ fn main() -> Result<()> { loop { let events = receiver.recv().unwrap(); - for e in events { - if let QueueEvent::InputEvent(ev) = e { - app.event(ev); - } else { - app.update(); + { + scope_time!("loop"); + + for e in events { + if let QueueEvent::InputEvent(ev) = e { + app.event(ev); + } else { + app.update(); + } } - } - terminal.draw(|mut f| app.draw(&mut f))?; + terminal.draw(|mut f| app.draw(&mut f))?; - if app.is_quit() { - break; + if app.is_quit() { + break; + } } }