Skip to content

Commit 3f06a71

Browse files
ozgesolidkeyclaude
andcommitted
Add unified search panel, context menus, highlight color picker, and bug fixes
- Search results panel: bottom slide-up overlay listing matches with navigation - Context menus: file context menu for tabs and folder tree (copy name/path/content, show in folder) - Terminal copy/paste/select-all via custom key event handler - Highlight color picker: clickable swatch opens native color input - Bug fixes: advanced filter empty rule stripping, case-insensitive levels, save-to-notes append Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e29904a commit 3f06a71

6 files changed

Lines changed: 550 additions & 36 deletions

File tree

src/main/index.ts

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,26 @@ ipcMain.handle('open-external-url', async (_, url: string) => {
16111611
}
16121612
});
16131613

1614+
// Show file in OS file manager
1615+
ipcMain.handle('show-item-in-folder', async (_, filePath: string) => {
1616+
shell.showItemInFolder(filePath);
1617+
});
1618+
1619+
// Read entire file content (for Copy All)
1620+
ipcMain.handle('read-file-content', async (_, filePath: string) => {
1621+
try {
1622+
const stats = fs.statSync(filePath);
1623+
const sizeMB = stats.size / (1024 * 1024);
1624+
if (sizeMB > 50) {
1625+
return { success: false, error: 'File too large to copy (>50MB)' };
1626+
}
1627+
const content = fs.readFileSync(filePath, 'utf-8');
1628+
return { success: true, content, sizeMB };
1629+
} catch (error) {
1630+
return { success: false, error: String(error) };
1631+
}
1632+
});
1633+
16141634
// === Save Selected Lines ===
16151635

16161636
ipcMain.handle('save-selected-lines', async (_, startLine: number, endLine: number, columnConfig?: ColumnConfig) => {
@@ -1817,20 +1837,8 @@ ipcMain.handle('save-to-notes', async (
18171837
content += newEntry;
18181838
fs.writeFileSync(notesFilePath, content, 'utf-8');
18191839
} else {
1820-
// Insert entry in line-number order among existing entries
1821-
const existing = fs.readFileSync(notesFilePath, 'utf-8');
1822-
const entryRegex = /\n--- \[.*?\] Lines (\d+)-/g;
1823-
let insertPos = existing.length; // default: append at end
1824-
let match;
1825-
while ((match = entryRegex.exec(existing)) !== null) {
1826-
const entryStartLine = parseInt(match[1], 10);
1827-
if (entryStartLine > startLine + 1) {
1828-
insertPos = match.index;
1829-
break;
1830-
}
1831-
}
1832-
const result = existing.substring(0, insertPos) + newEntry + existing.substring(insertPos);
1833-
fs.writeFileSync(notesFilePath, result, 'utf-8');
1840+
// Simple append to existing file
1841+
fs.appendFileSync(notesFilePath, newEntry, 'utf-8');
18341842
}
18351843

18361844
// Invalidate cache for this file so it gets re-indexed with new content
@@ -1969,9 +1977,9 @@ function compileAdvancedFilter(config: AdvancedFilterConfig): CompiledMatcher {
19691977
return (text: string, _level: string) =>
19701978
!(rule.caseSensitive ? text : text.toLowerCase()).includes(pattern);
19711979
case 'level':
1972-
return (_text: string, level: string) => level === rule.value;
1980+
return (_text: string, level: string) => level.toLowerCase() === rule.value.toLowerCase();
19731981
case 'not_level':
1974-
return (_text: string, level: string) => level !== rule.value;
1982+
return (_text: string, level: string) => level.toLowerCase() !== rule.value.toLowerCase();
19751983
default:
19761984
return (_text: string, _level: string) => true;
19771985
}

src/preload/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,13 @@ const api = {
311311
saveNotes: (content: string): Promise<{ success: boolean; error?: string }> =>
312312
ipcRenderer.invoke('save-notes', content),
313313

314+
// File context menu actions
315+
showItemInFolder: (filePath: string): Promise<void> =>
316+
ipcRenderer.invoke('show-item-in-folder', filePath),
317+
318+
readFileContent: (filePath: string): Promise<{ success: boolean; content?: string; sizeMB?: number; error?: string }> =>
319+
ipcRenderer.invoke('read-file-content', filePath),
320+
314321
// Window controls
315322
windowMinimize: (): Promise<void> => ipcRenderer.invoke('window-minimize'),
316323
windowMaximize: (): Promise<void> => ipcRenderer.invoke('window-maximize'),

src/renderer/index.html

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,19 @@ <h2>LOGAN</h2>
347347
</div>
348348
</div>
349349

350+
<!-- Search Results Panel (slide-up from bottom) -->
351+
<div id="search-results-overlay" class="search-results-overlay hidden">
352+
<div id="search-results-panel" class="search-results-panel">
353+
<div id="search-results-resize-handle" class="search-results-resize-handle-top"></div>
354+
<div class="search-results-header">
355+
<span class="search-results-title">Search Results</span>
356+
<span id="search-results-summary" class="search-results-summary"></span>
357+
<button id="btn-search-results-close" class="search-results-close-btn" title="Close (Esc)">&times;</button>
358+
</div>
359+
<div id="search-results-list" class="search-results-list"></div>
360+
</div>
361+
</div>
362+
350363
<!-- Status Bar -->
351364
<footer class="status-bar">
352365
<div class="status-left">
@@ -590,7 +603,8 @@ <h4>Terminal & Notes</h4>
590603
<div class="shortcut-list">
591604
<div class="shortcut-item"><kbd>Ctrl</kbd>+<kbd>`</kbd><span>Toggle terminal panel</span></div>
592605
<div class="shortcut-item"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>N</kbd><span>Toggle notes drawer</span></div>
593-
<div class="shortcut-item"><kbd>Esc</kbd><span>Close terminal/notes (when focused)</span></div>
606+
<div class="shortcut-item"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>R</kbd><span>Toggle search results panel</span></div>
607+
<div class="shortcut-item"><kbd>Esc</kbd><span>Close terminal/notes/search results (when focused)</span></div>
594608
</div>
595609
</div>
596610
<div class="help-section">

0 commit comments

Comments
 (0)