summaryrefslogtreecommitdiffstats
path: root/src/preview
diff options
context:
space:
mode:
Diffstat (limited to 'src/preview')
-rw-r--r--src/preview/mod.rs2
-rw-r--r--src/preview/preview.rs10
-rw-r--r--src/preview/zero_len_file_view.rs56
3 files changed, 66 insertions, 2 deletions
diff --git a/src/preview/mod.rs b/src/preview/mod.rs
index ed49778..0eea813 100644
--- a/src/preview/mod.rs
+++ b/src/preview/mod.rs
@@ -1,9 +1,11 @@
mod preview;
mod preview_state;
+mod zero_len_file_view;
pub use {
preview::Preview,
preview_state::PreviewState,
+ zero_len_file_view::ZeroLenFileView,
};
#[derive(Debug, Clone, Copy, PartialEq)]
diff --git a/src/preview/preview.rs b/src/preview/preview.rs
index ecf6850..19c444e 100644
--- a/src/preview/preview.rs
+++ b/src/preview/preview.rs
@@ -1,6 +1,5 @@
-
use {
- super::PreviewMode,
+ super::*,
crate::{
app::{AppContext, LineNumber},
command::{ScrollCommand},
@@ -25,6 +24,7 @@ pub enum Preview {
Image(ImageView),
Syntactic(SyntacticView),
Hex(HexView),
+ ZeroLen(ZeroLenFileView),
IOError(io::Error),
}
@@ -87,6 +87,10 @@ impl Preview {
) -> Self {
match SyntacticView::new(path, InputPattern::none(), &mut Dam::unlimited(), con) {
Ok(Some(sv)) => Self::Syntactic(sv),
+ Err(ProgramError::ZeroLenFile) => {
+ debug!("zero len file - check if system file");
+ Self::ZeroLen(ZeroLenFileView::new(path.to_path_buf()))
+ }
// not previewable as UTF8 text
// we'll try reading it as binary
_ => Self::hex(path),
@@ -136,6 +140,7 @@ impl Preview {
match self {
Self::Image(_) => Some(PreviewMode::Image),
Self::Syntactic(_) => Some(PreviewMode::Text),
+ Self::ZeroLen(_) => Some(PreviewMode::Text),
Self::Hex(_) => Some(PreviewMode::Hex),
Self::IOError(_) => None,
}
@@ -226,6 +231,7 @@ impl Preview {
match self {
Self::Image(iv) => iv.display(w, screen, panel_skin, area, con),
Self::Syntactic(sv) => sv.display(w, screen, panel_skin, area, con),
+ Self::ZeroLen(zlv) => zlv.display(w, screen, panel_skin, area),
Self::Hex(hv) => hv.display(w, screen, panel_skin, area),
Self::IOError(err) => {
let mut y = area.top;
diff --git a/src/preview/zero_len_file_view.rs b/src/preview/zero_len_file_view.rs
new file mode 100644
index 0000000..5ec3045
--- /dev/null
+++ b/src/preview/zero_len_file_view.rs
@@ -0,0 +1,56 @@
+use {
+ crate::{
+ display::{CropWriter, SPACE_FILLING, Screen, W},
+ errors::ProgramError,
+ skin::PanelSkin,
+ },
+ char_reader::CharReader,
+ crossterm::{
+ cursor,
+ QueueableCommand,
+ },
+ std::{
+ fs::File,
+ path::PathBuf,
+ },
+ termimad::{Area},
+};
+
+/// a (light) display for a file declaring a size 0,
+/// as happens for many system "files", for example in /proc
+pub struct ZeroLenFileView {
+ path: PathBuf,
+}
+
+impl ZeroLenFileView {
+ pub fn new(path: PathBuf) -> Self {
+ Self {
+ path,
+ }
+ }
+ pub fn display(
+ &mut self,
+ w: &mut W,
+ _screen: Screen,
+ panel_skin: &PanelSkin,
+ area: &Area,
+ ) -> Result<(), ProgramError> {
+ let styles = &panel_skin.styles;
+ let line_count = area.height as usize;
+ let file = File::open(&self.path)?;
+ let mut reader = CharReader::new(file);
+ // line_len here is in chars, and we crop in cols, but it's OK because both
+ // are usually identical for system files and we crop later anyway
+ let line_len = area.width as usize;
+ for y in 0..line_count {
+ w.queue(cursor::MoveTo(area.left, y as u16 + area.top))?;
+ let mut cw = CropWriter::new(w, area.width as usize);
+ let cw = &mut cw;
+ if let Some(line) = reader.next_line(line_len, 15_000)? {
+ cw.queue_str(&styles.default, &line)?;
+ }
+ cw.fill(&styles.default, &SPACE_FILLING)?;
+ }
+ Ok(())
+ }
+}