From a58dfa1b13ddf98b16154e167a7d8fda648a1816 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 1 Jan 2024 14:02:05 +0000 Subject: [PATCH] Fill in percentage in file status lines. I was putting that off because I had a half-formed clever idea about trying to do linear regression on the posts we _have_ formatted to the current width, and using it to estimate the likely line height of the ones we haven't. But then I decided that was either the perfect being the enemy of the good, or a silly idea that was bound to explode in an edge case, or both, and so I've done something simple instead. The _main_ purpose is that '100%' means 'nothing more to read' and anything less means there is. As long as we get that much right, we're in reasonably good shape. --- src/file.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/file.rs b/src/file.rs index c2c7e58..774d97c 100644 --- a/src/file.rs +++ b/src/file.rs @@ -476,10 +476,32 @@ impl } else { fs.add(Space, "Down", 99) }; - let fs = fs.add(Pr('q'), "Exit", 100) - .finalise(); + let fs = fs.add(Pr('q'), "Exit", 100); // FIXME: document more keys - // FIXME: best-effort percentage calculation + + // We calculate the percentage through the file in a loose + // sort of way, by assuming all items are the same size, and + // only calculating a partial item for the one we're actually + // in the middle of. This isn't how Mono did it, but Mono + // didn't have to dynamically rewrap whenever the window + // resized. + // + // (A robust way to get precise line-based percentages even so + // would be to eagerly rewrap the entire collection of items + // on every resize, but I don't think that's a sensible + // tradeoff!) + let fs = { + let base = self.contents.first_index(); + let full_items = (start_item - base) as usize; + let total_items = (self.contents.index_limit() - base) as usize; + let mult = self.rendered.get(&start_item).unwrap().len(); + fs.set_proportion( + full_items * mult + start_line, + total_items * mult) + }; + + let fs = fs.finalise(); + lines.extend_from_slice(&fs.render(w)); (lines, CursorPosition::End) -- 2.30.2