mirror of
https://github.com/sayanarijit/xplr.git
synced 2024-09-11 11:05:39 +03:00
Improve scrolling behaviour
Closes: https://github.com/sayanarijit/xplr/issues/54
This commit is contained in:
parent
d63d612339
commit
ea42b1969a
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1362,7 +1362,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xplr"
|
name = "xplr"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "xplr"
|
name = "xplr"
|
||||||
version = "0.4.2" # Update config.yml, config.rs and default.nix
|
version = "0.4.3" # Update config.yml, config.rs and default.nix
|
||||||
authors = ["Arijit Basu <sayanarijit@gmail.com>"]
|
authors = ["Arijit Basu <sayanarijit@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "A hackable, minimal, fast TUI file explorer, stealing ideas from nnn and fzf"
|
description = "A hackable, minimal, fast TUI file explorer, stealing ideas from nnn and fzf"
|
||||||
|
7
RELEASE.md
Normal file
7
RELEASE.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Process
|
||||||
|
-------
|
||||||
|
- [ ] Update `Cargo.toml` version.
|
||||||
|
- [ ] Update `config.yml` version.
|
||||||
|
- [ ] Update `Config::is_compatible()` and `Config::upgrade_notification()`.
|
||||||
|
- [ ] Publish GitHub tag.
|
||||||
|
- [ ] Update Wiki and docs.
|
@ -4,9 +4,9 @@ with import <nixpkgs> {};
|
|||||||
|
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage rec {
|
||||||
name = "xplr";
|
name = "xplr";
|
||||||
version = "0.4.2";
|
version = "0.4.3";
|
||||||
src = fetchTarball
|
src = fetchTarball
|
||||||
("https://github.com/sayanarijit/xplr/archive/refs/tags/v0.4.2.tar.gz");
|
("https://github.com/sayanarijit/xplr/archive/refs/tags/v0.4.3.tar.gz");
|
||||||
buildInputs = [ cargo ];
|
buildInputs = [ cargo ];
|
||||||
checkPhase = "";
|
checkPhase = "";
|
||||||
cargoSha256 = "0000000000000000000000000000000000000000000000000000";
|
cargoSha256 = "0000000000000000000000000000000000000000000000000000";
|
||||||
|
@ -559,6 +559,7 @@ impl Config {
|
|||||||
|
|
||||||
pub fn is_compatible(&self) -> Result<bool> {
|
pub fn is_compatible(&self) -> Result<bool> {
|
||||||
let result = match self.parsed_version()? {
|
let result = match self.parsed_version()? {
|
||||||
|
(0, 4, 3) => true,
|
||||||
(0, 4, 2) => true,
|
(0, 4, 2) => true,
|
||||||
(0, 4, 1) => true,
|
(0, 4, 1) => true,
|
||||||
(0, 4, 0) => true,
|
(0, 4, 0) => true,
|
||||||
@ -570,8 +571,8 @@ impl Config {
|
|||||||
|
|
||||||
pub fn upgrade_notification(&self) -> Result<Option<&str>> {
|
pub fn upgrade_notification(&self) -> Result<Option<&str>> {
|
||||||
let result = match self.parsed_version()? {
|
let result = match self.parsed_version()? {
|
||||||
(0, 4, 2) => None,
|
(0, 4, 3) => None,
|
||||||
(_, _, _) => Some("New version available"),
|
(_, _, _) => Some("App version updated"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: v0.4.2
|
version: v0.4.3
|
||||||
general:
|
general:
|
||||||
show_hidden: false
|
show_hidden: false
|
||||||
prompt:
|
prompt:
|
||||||
|
33
src/ui.rs
33
src/ui.rs
@ -10,13 +10,9 @@ use tui::layout::Rect;
|
|||||||
use tui::layout::{Constraint as TuiConstraint, Direction, Layout};
|
use tui::layout::{Constraint as TuiConstraint, Direction, Layout};
|
||||||
use tui::style::{Color, Style};
|
use tui::style::{Color, Style};
|
||||||
use tui::text::{Span, Spans};
|
use tui::text::{Span, Spans};
|
||||||
use tui::widgets::{
|
use tui::widgets::{Block, Borders, Cell, List, ListItem, Paragraph, Row, Table};
|
||||||
Block, Borders, Cell, List, ListItem, ListState, Paragraph, Row, Table, TableState,
|
|
||||||
};
|
|
||||||
use tui::Frame;
|
use tui::Frame;
|
||||||
|
|
||||||
const TOTAL_ROWS: usize = 50;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct NodeUiMetadata {
|
struct NodeUiMetadata {
|
||||||
@ -87,20 +83,17 @@ impl NodeUiMetadata {
|
|||||||
|
|
||||||
fn draw_table<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, hb: &Handlebars) {
|
fn draw_table<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, hb: &Handlebars) {
|
||||||
let config = app.config().to_owned();
|
let config = app.config().to_owned();
|
||||||
|
let header_height = config.general.table.header.height.unwrap_or(1);
|
||||||
|
let height: usize = (rect.height.max(header_height + 2) - (header_height + 2)).into();
|
||||||
|
|
||||||
let rows = app
|
let rows = app
|
||||||
.directory_buffer()
|
.directory_buffer()
|
||||||
.map(|dir| {
|
.map(|dir| {
|
||||||
let offset = (
|
|
||||||
dir.focus.max(TOTAL_ROWS) - TOTAL_ROWS,
|
|
||||||
dir.focus.max(TOTAL_ROWS),
|
|
||||||
);
|
|
||||||
|
|
||||||
dir.nodes
|
dir.nodes
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.skip_while(|(i, _)| *i < offset.0)
|
.skip(height * (dir.focus / height))
|
||||||
.take_while(|(i, _)| *i <= offset.1)
|
.take(height)
|
||||||
.map(|(index, node)| {
|
.map(|(index, node)| {
|
||||||
let is_focused = dir.focus == index;
|
let is_focused = dir.focus == index;
|
||||||
|
|
||||||
@ -242,20 +235,20 @@ fn draw_table<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, hb: &Han
|
|||||||
.map(|c| Cell::from(c.format.to_owned().unwrap_or_default()))
|
.map(|c| Cell::from(c.format.to_owned().unwrap_or_default()))
|
||||||
.collect::<Vec<Cell>>(),
|
.collect::<Vec<Cell>>(),
|
||||||
)
|
)
|
||||||
.height(config.general.table.header.height.unwrap_or_default())
|
.height(header_height)
|
||||||
.style(config.general.table.header.style.into()),
|
.style(config.general.table.header.style.into()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut table_state = TableState::default();
|
f.render_widget(table, rect);
|
||||||
table_state.select(app.directory_buffer().map(|dir| dir.focus));
|
|
||||||
|
|
||||||
f.render_stateful_widget(table, rect, &mut table_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_selection<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _: &Handlebars) {
|
fn draw_selection<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _: &Handlebars) {
|
||||||
let selection: Vec<ListItem> = app
|
let selection: Vec<ListItem> = app
|
||||||
.selection()
|
.selection()
|
||||||
.iter()
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.take((rect.height.max(2) - 2).into())
|
||||||
|
.rev()
|
||||||
.map(|n| n.absolute_path.clone())
|
.map(|n| n.absolute_path.clone())
|
||||||
.map(ListItem::new)
|
.map(ListItem::new)
|
||||||
.collect();
|
.collect();
|
||||||
@ -269,11 +262,7 @@ fn draw_selection<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _: &
|
|||||||
.title(format!(" Selection ({}) ", selection_count)),
|
.title(format!(" Selection ({}) ", selection_count)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut list_state = ListState::default();
|
f.render_widget(selection_list, rect);
|
||||||
if selection_count > 0 {
|
|
||||||
list_state.select(Some(selection_count.max(1) - 1));
|
|
||||||
}
|
|
||||||
f.render_stateful_widget(selection_list, rect, &mut list_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_help_menu<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _: &Handlebars) {
|
fn draw_help_menu<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _: &Handlebars) {
|
||||||
|
Loading…
Reference in New Issue
Block a user