Skip to content

Commit d03ef0d

Browse files
ozgesolidkeyclaude
andcommitted
Add search history with up/down arrow navigation
- Last 50 searches stored in localStorage - Up/Down arrows in search input navigate through history - Deduplication: repeated patterns move to top instead of duplicating - Current input is stashed and restored when navigating back Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7b19cca commit d03ef0d

File tree

2 files changed

+77
-7
lines changed

2 files changed

+77
-7
lines changed

src/main/index.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4695,8 +4695,27 @@ function streamFormatJson(inputPath: string, outputPath: string, onProgress?: (p
46954695
}
46964696
};
46974697

4698+
// Shallow JSON formatter: expands only top-level keys to one line each,
4699+
// keeping nested values compact. Limits line explosion for large JSONL files.
4700+
const shallowFormat = (obj: any): string => {
4701+
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
4702+
return JSON.stringify(obj);
4703+
}
4704+
const keys = Object.keys(obj);
4705+
if (keys.length === 0) return '{}';
4706+
const lines = ['{'];
4707+
for (let i = 0; i < keys.length; i++) {
4708+
const k = keys[i];
4709+
const val = JSON.stringify(obj[k]);
4710+
const comma = i < keys.length - 1 ? ',' : '';
4711+
lines.push(` ${JSON.stringify(k)}: ${val}${comma}`);
4712+
}
4713+
lines.push('}');
4714+
return lines.join('\n');
4715+
};
4716+
46984717
if (isJsonl) {
4699-
// JSONL: format each line independently
4718+
// JSONL: format each line with shallow expansion (top-level keys only)
47004719
let lineBuffer = '';
47014720

47024721
readStream.on('data', (rawChunk: string | Buffer) => {
@@ -4705,28 +4724,26 @@ function streamFormatJson(inputPath: string, outputPath: string, onProgress?: (p
47054724

47064725
lineBuffer += chunk;
47074726
const lines = lineBuffer.split('\n');
4708-
lineBuffer = lines.pop() || ''; // Keep incomplete last line
4727+
lineBuffer = lines.pop() || '';
47094728

47104729
for (const line of lines) {
47114730
const trimmed = line.trim();
47124731
if (!trimmed) { write('\n'); continue; }
47134732
try {
47144733
const obj = JSON.parse(trimmed);
4715-
write(JSON.stringify(obj, null, 2) + '\n');
4734+
write(shallowFormat(obj) + '\n');
47164735
} catch {
4717-
// Not valid JSON — write as-is
47184736
write(trimmed + '\n');
47194737
}
47204738
}
47214739
});
47224740

47234741
readStream.on('end', () => {
4724-
// Process remaining buffer
47254742
const trimmed = lineBuffer.trim();
47264743
if (trimmed) {
47274744
try {
47284745
const obj = JSON.parse(trimmed);
4729-
write(JSON.stringify(obj, null, 2) + '\n');
4746+
write(shallowFormat(obj) + '\n');
47304747
} catch {
47314748
write(trimmed + '\n');
47324749
}
@@ -4846,7 +4863,6 @@ ipcMain.handle('format-json-file', async (_, filePath: string) => {
48464863
});
48474864

48484865
const writtenStats = fs.statSync(formattedPath);
4849-
console.log(`[JSON Format] Done. Output: ${writtenStats.size} bytes`);
48504866

48514867
if (writtenStats.size > MAX_FORMATTED_SIZE) {
48524868
// Clean up - file too large to index efficiently

src/renderer/renderer.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8942,9 +8942,57 @@ function applyColumnFilter(text: string): string {
89428942
}
89438943

89448944
// Search
8945+
// ─── Search History ──────────────────────────────────────────────
8946+
const SEARCH_HISTORY_KEY = 'logan-search-history';
8947+
const SEARCH_HISTORY_MAX = 50;
8948+
let searchHistory: string[] = (() => {
8949+
try { return JSON.parse(localStorage.getItem(SEARCH_HISTORY_KEY) || '[]'); }
8950+
catch { return []; }
8951+
})();
8952+
let searchHistoryIndex = -1; // -1 means "not navigating, showing current input"
8953+
let searchHistoryStash = ''; // What user typed before starting to navigate history
8954+
8955+
function addToSearchHistory(pattern: string): void {
8956+
if (!pattern.trim()) return;
8957+
// Remove existing duplicate, then add to top
8958+
searchHistory = searchHistory.filter(p => p !== pattern);
8959+
searchHistory.unshift(pattern);
8960+
if (searchHistory.length > SEARCH_HISTORY_MAX) {
8961+
searchHistory = searchHistory.slice(0, SEARCH_HISTORY_MAX);
8962+
}
8963+
try { localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(searchHistory)); } catch {}
8964+
searchHistoryIndex = -1;
8965+
}
8966+
8967+
function navigateSearchHistory(direction: 'up' | 'down'): void {
8968+
if (searchHistory.length === 0) return;
8969+
if (direction === 'up') {
8970+
if (searchHistoryIndex === -1) {
8971+
searchHistoryStash = elements.searchInput.value;
8972+
searchHistoryIndex = 0;
8973+
} else if (searchHistoryIndex < searchHistory.length - 1) {
8974+
searchHistoryIndex++;
8975+
}
8976+
elements.searchInput.value = searchHistory[searchHistoryIndex];
8977+
} else {
8978+
if (searchHistoryIndex === -1) return;
8979+
if (searchHistoryIndex === 0) {
8980+
searchHistoryIndex = -1;
8981+
elements.searchInput.value = searchHistoryStash;
8982+
} else {
8983+
searchHistoryIndex--;
8984+
elements.searchInput.value = searchHistory[searchHistoryIndex];
8985+
}
8986+
}
8987+
// Move cursor to end
8988+
const len = elements.searchInput.value.length;
8989+
elements.searchInput.setSelectionRange(len, len);
8990+
}
8991+
89458992
async function performSearch(): Promise<void> {
89468993
const pattern = elements.searchInput.value;
89478994
if (!pattern || !state.filePath) return;
8995+
addToSearchHistory(pattern);
89488996

89498997
showProgress('Searching...');
89508998

@@ -11891,6 +11939,12 @@ function setupKeyboardShortcuts(): void {
1189111939
performSearch();
1189211940
}
1189311941

11942+
// Up/Down arrows in search input: navigate history
11943+
if (document.activeElement === elements.searchInput && (e.key === 'ArrowUp' || e.key === 'ArrowDown')) {
11944+
e.preventDefault();
11945+
navigateSearchHistory(e.key === 'ArrowUp' ? 'up' : 'down');
11946+
}
11947+
1189411948
// F3 or Ctrl/Cmd + G: Next search result (respects direction)
1189511949
if (e.key === 'F3' || ((e.ctrlKey || e.metaKey) && e.key === 'g')) {
1189611950
e.preventDefault();

0 commit comments

Comments
 (0)