Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dialogs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<'a> FileDialog<'a> {

pub fn fwd(&mut self, steps: usize) {
let i = match self.state.selected() {
Some(i) => std::cmp::min(i.saturating_add(steps), self.dirs.len() - 1),
Some(i) => std::cmp::min(i.saturating_add(steps), self.dirs.len().saturating_sub(1)),
None => 0,
};
self.state.select(Some(i));
Expand Down
116 changes: 66 additions & 50 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,8 +793,8 @@ fn run(

let mut app = None;
if file_dialog.error_message.is_some() {
if let Event::Input(event) = next_event() {
match event.code {
match next_event() {
Event::Input(event) => match event.code {
KeyCode::Enter | KeyCode::Esc => {
file_dialog.clear_error();
}
Expand All @@ -805,61 +805,77 @@ fn run(
break;
}
_ => {}
},
Event::Update => {
let now = Instant::now();
if next_repo_refresh.get() <= now {
next_repo_refresh.set(now + repo_refresh_interval);
}
}
}
} else if let Event::Input(event) = next_event() {
match event.code {
KeyCode::Char('q') => {
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
terminal.show_cursor()?;
break;
}
KeyCode::Char('o') if event.modifiers.contains(KeyModifiers::CONTROL) => {
if let Some(prev_app) = file_dialog.previous_app.take() {
app = Some(prev_app);
} else {
file_dialog.set_error("No repository to return to.\nSelect a Git rrpository or quit with Q.".to_string())
} else {
match next_event() {
Event::Input(event) => match event.code {
KeyCode::Char('q') => {
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
terminal.show_cursor()?;
break;
}
}
KeyCode::Esc => {
if let Some(prev_app) = file_dialog.previous_app.take() {
app = Some(prev_app);
} else {
file_dialog.set_error("No repository to return to.\nSelect a Git rrpository or quit with Q.".to_string())
KeyCode::Char('o') if event.modifiers.contains(KeyModifiers::CONTROL) => {
if let Some(prev_app) = file_dialog.previous_app.take() {
app = Some(prev_app);
} else {
file_dialog.set_error("No repository to return to.\nSelect a Git rrpository or quit with Q.".to_string())
}
}
}
KeyCode::Up => file_dialog.on_up(event.modifiers.contains(KeyModifiers::SHIFT)),
KeyCode::Down => {
file_dialog.on_down(event.modifiers.contains(KeyModifiers::SHIFT))
}
KeyCode::Left => file_dialog.on_left()?,
KeyCode::Right => file_dialog.on_right()?,
KeyCode::Enter => {
file_dialog.on_enter();
if let Some(path) = &file_dialog.selection {
match get_repo(path) {
Ok(repo) => {
if repo.is_shallow() {
file_dialog.set_error(format!("{} is a shallow clone. Shallow clones are not supported due to a missing feature in the underlying libgit2 library.", repo.path().parent().unwrap().display()));
} else {
app = Some(create_app(
repo,
&mut settings,
&app_settings,
model,
max_commits,
)?)
KeyCode::Esc => {
if let Some(prev_app) = file_dialog.previous_app.take() {
app = Some(prev_app);
} else {
file_dialog.set_error("No repository to return to.\nSelect a Git rrpository or quit with Q.".to_string())
}
}
KeyCode::Up => {
file_dialog.on_up(event.modifiers.contains(KeyModifiers::SHIFT))
}
KeyCode::Down => {
file_dialog.on_down(event.modifiers.contains(KeyModifiers::SHIFT))
}
KeyCode::Left => file_dialog.on_left()?,
KeyCode::Right => file_dialog.on_right()?,
KeyCode::Enter => {
file_dialog.on_enter();
if let Some(path) = &file_dialog.selection {
match get_repo(path) {
Ok(repo) => {
if repo.is_shallow() {
file_dialog.set_error(format!("{} is a shallow clone. Shallow clones are not supported due to a missing feature in the underlying libgit2 library.", repo.path().parent().unwrap().display()));
} else {
app = Some(create_app(
repo,
&mut settings,
&app_settings,
model,
max_commits,
)?)
}
}
}
Err(_) => {
file_dialog.on_right()?;
}
};
Err(_) => {
file_dialog.on_right()?;
}
};
}
}
_ => {}
},
Event::Update => {
let now = Instant::now();
if next_repo_refresh.get() <= now {
next_repo_refresh.set(now + repo_refresh_interval);
}
}
_ => {}
};
}
}
app
};
Expand Down
53 changes: 34 additions & 19 deletions src/widgets/graph_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ impl GraphViewState {
pub fn move_selection(&mut self, steps: usize, down: bool) -> bool {
let changed = if let Some(sel) = self.selected {
let new_idx = if down {
std::cmp::min(sel.saturating_add(steps), self.indices.len() - 1)
std::cmp::min(
sel.saturating_add(steps),
self.indices.len().saturating_sub(1),
)
} else {
std::cmp::max(sel.saturating_sub(steps), 0)
sel.saturating_sub(steps)
};
self.selected = Some(new_idx);
new_idx != sel
Expand All @@ -49,18 +52,24 @@ impl GraphViewState {
pub fn move_secondary_selection(&mut self, steps: usize, down: bool) -> bool {
let changed = if let Some(sel) = self.secondary_selected {
let new_idx = if down {
std::cmp::min(sel.saturating_add(steps), self.indices.len() - 1)
std::cmp::min(
sel.saturating_add(steps),
self.indices.len().saturating_sub(1),
)
} else {
std::cmp::max(sel.saturating_sub(steps), 0)
sel.saturating_sub(steps)
};
self.secondary_selected = Some(new_idx);
new_idx != sel
} else if !self.graph_lines.is_empty() {
if let Some(sel) = self.selected {
let new_idx = if down {
std::cmp::min(sel.saturating_add(steps), self.indices.len() - 1)
std::cmp::min(
sel.saturating_add(steps),
self.indices.len().saturating_sub(1),
)
} else {
std::cmp::max(sel.saturating_sub(steps), 0)
sel.saturating_sub(steps)
};
self.secondary_selected = Some(new_idx);
new_idx != sel
Expand Down Expand Up @@ -131,7 +140,7 @@ impl StatefulWidget for GraphView<'_> {
return;
}

if state.graph_lines.is_empty() {
if state.graph_lines.is_empty() || state.indices.is_empty() {
return;
}
let list_height = list_area.height as usize;
Expand All @@ -144,31 +153,37 @@ impl StatefulWidget for GraphView<'_> {
);
let mut end = start + height;

let selected_row = state.selected.map(|idx| state.indices[idx]);
let selected = selected_row.unwrap_or(0).min(state.graph_lines.len() - 1);
let max_graph_idx = state.graph_lines.len().saturating_sub(1);
let max_indices_idx = state.indices.len().saturating_sub(1);

let secondary_selected_row = state.secondary_selected.map(|idx| state.indices[idx]);
let secondary_selected = secondary_selected_row
.unwrap_or(0)
.min(state.graph_lines.len() - 1);
let selected_row = state
.selected
.and_then(|idx| state.indices.get(idx).copied());
let selected = selected_row.unwrap_or(0).min(max_graph_idx);

let secondary_selected_row = state
.secondary_selected
.and_then(|idx| state.indices.get(idx).copied());
let secondary_selected = secondary_selected_row.unwrap_or(0).min(max_graph_idx);

let selected_index = if state.secondary_changed {
state.secondary_selected.unwrap_or(0)
state.secondary_selected.unwrap_or(0).min(max_indices_idx)
} else {
state.selected.unwrap_or(0)
state.selected.unwrap_or(0).min(max_indices_idx)
};
let move_to_selected = if state.secondary_changed {
secondary_selected
} else {
selected
};

let move_to_end = if selected_index >= state.indices.len() - 1 {
state.graph_lines.len() - 1
let move_to_end = if selected_index >= max_indices_idx {
max_graph_idx
} else {
(state.indices[selected_index + 1] - 1)
state.indices[selected_index + 1]
.saturating_sub(1)
.max(move_to_selected + SCROLL_MARGIN)
.min(state.graph_lines.len() - 1)
.min(max_graph_idx)
};
let move_to_start = move_to_selected.saturating_sub(SCROLL_MARGIN);

Expand Down
2 changes: 1 addition & 1 deletion src/widgets/models_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl ModelListState {

pub fn fwd(&mut self, steps: usize) {
let i = match self.state.selected() {
Some(i) => std::cmp::min(i.saturating_add(steps), self.models.len() - 1),
Some(i) => std::cmp::min(i.saturating_add(steps), self.models.len().saturating_sub(1)),
None => 0,
};
self.state.select(Some(i));
Expand Down