commit dd9d7d30ab0380a8f399f9003a36510c0b6d841a
parent 062d92b04571a4f93163cafab7756ced100ad282
Author: finwo <finwo@pm.me>
Date: Sat, 21 Mar 2026 05:19:05 +0100
Clamp preview to file length; keep selected file in view
Diffstat:
| M | vecfinder.js | | | 52 | +++++++++++++++++++++++++++++++++++++++++++++++++--- |
1 file changed, 49 insertions(+), 3 deletions(-)
diff --git a/vecfinder.js b/vecfinder.js
@@ -275,6 +275,7 @@ class UI {
this.store = store;
this.query = '';
this.selectedIndex = 0;
+ this.listOffset = 0;
this.previewOffset = 0;
this.rl = null;
this._previewWrapped = null;
@@ -286,6 +287,7 @@ class UI {
this.store.on('documentAdded', () => this.render());
this.store.on('queryUpdated', () => {
this.selectedIndex = 0;
+ this.listOffset = 0;
this.previewOffset = 0;
this.render();
});
@@ -309,6 +311,20 @@ class UI {
if (this.rl) this.rl.close();
}
+ adjustListOffset(maxHeight) {
+ const results = this.store.getResults();
+ const topThreshold = this.listOffset + 2;
+ const bottomThreshold = this.listOffset + maxHeight - 3;
+
+ if (this.selectedIndex < topThreshold) {
+ this.listOffset = Math.max(0, this.selectedIndex - 2);
+ } else if (this.selectedIndex > bottomThreshold) {
+ this.listOffset = Math.min(results.length - maxHeight, this.selectedIndex - (maxHeight - 3));
+ }
+
+ this.listOffset = Math.max(0, Math.min(this.listOffset, Math.max(0, results.length - maxHeight)));
+ }
+
handleKeyPress(str, key) {
if (!key) return;
@@ -321,6 +337,9 @@ class UI {
if (this.selectedIndex > 0) {
this.selectedIndex--;
this.previewOffset = 0;
+ const height = process.stdout.rows || 24;
+ const maxHeight = height - 4;
+ this.adjustListOffset(maxHeight);
this.render();
}
return;
@@ -331,11 +350,35 @@ class UI {
if (this.selectedIndex < results.length - 1) {
this.selectedIndex++;
this.previewOffset = 0;
+ const height = process.stdout.rows || 24;
+ const maxHeight = height - 4;
+ this.adjustListOffset(maxHeight);
this.render();
}
return;
}
+ if (key.name === 'home') {
+ this.selectedIndex = 0;
+ this.previewOffset = 0;
+ const height = process.stdout.rows || 24;
+ const maxHeight = height - 4;
+ this.adjustListOffset(maxHeight);
+ this.render();
+ return;
+ }
+
+ if (key.name === 'end') {
+ const results = this.store.getResults();
+ this.selectedIndex = results.length - 1;
+ this.previewOffset = 0;
+ const height = process.stdout.rows || 24;
+ const maxHeight = height - 4;
+ this.adjustListOffset(maxHeight);
+ this.render();
+ return;
+ }
+
if (key.name === 'pageup') {
this.previewOffset = Math.max(0, this.previewOffset - 10);
this.render();
@@ -343,7 +386,10 @@ class UI {
}
if (key.name === 'pagedown') {
- this.previewOffset += 10;
+ const height = process.stdout.rows || 24;
+ const previewHeight = height - 4;
+ const maxPreviewOffset = this._previewWrapped ? Math.max(0, this._previewWrapped.length - previewHeight) : 0;
+ this.previewOffset = Math.min(maxPreviewOffset, this.previewOffset + 10);
this.render();
return;
}
@@ -395,8 +441,8 @@ class UI {
// Rows
for (let row = 0; row < maxHeight; row++) {
- const result = results[row];
- const isSelected = (row === this.selectedIndex);
+ const result = results[row + this.listOffset];
+ const isSelected = (row + this.listOffset === this.selectedIndex);
// Left pane - name left, score right
let left;