mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-10-01 09:19:34 +05:30
feat(quick-switcher): derive workspace dir from active tab
The explorer panel's explorerCurrentDir is hardcoded to null, so the Quick Switcher's workspace toggle was a no-op. Rather than fix the broken explorer flow, derive the workspace from the active tab's filePath's parent directory — the most reliable source we have without restructuring that panel. deriveWorkspaceDir() handles POSIX and Windows paths (including mixed separators and trailing separators), returns null for untitled / empty inputs so the workspace toggle silently stays off in those cases. 10 new tests cover POSIX, Windows, mixed-separator, trailing separator, UNC, and invalid input paths. Amit Haridas
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Workspace dir resolver for the Quick Switcher overlay.
|
||||
*
|
||||
* Derives a workspace directory from a single file path by returning its
|
||||
* parent directory. Auto-detects path separator (Windows backslash vs
|
||||
* POSIX forward slash).
|
||||
*
|
||||
* Returns null when no usable file path is supplied (untitled tab, no
|
||||
* active tab) — the renderer then surfaces only recent + open tabs in
|
||||
* the Quick Switcher, and the workspace toggle is a no-op.
|
||||
*
|
||||
* @module workspace-dir-resolver
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string|null|undefined} filePath
|
||||
* @returns {string|null} parent directory, or null if not derivable
|
||||
*/
|
||||
function deriveWorkspaceDir(filePath) {
|
||||
if (typeof filePath !== 'string' || filePath.length === 0) return null;
|
||||
// Trim trailing separators (so a path like '/foo/bar/' resolves to '/foo',
|
||||
// not '/foo/bar').
|
||||
let end = filePath.length;
|
||||
while (end > 0 && (filePath[end - 1] === '/' || filePath[end - 1] === '\\')) {
|
||||
end--;
|
||||
}
|
||||
if (end === 0) return null;
|
||||
const trimmed = filePath.slice(0, end);
|
||||
// Find the last separator of either kind — mixed paths are ambiguous
|
||||
// but taking the last one of either kind matches what users mean when
|
||||
// they paste a path with mixed separators.
|
||||
const lastSlash = trimmed.lastIndexOf('/');
|
||||
const lastBack = trimmed.lastIndexOf('\\');
|
||||
const lastSep = Math.max(lastSlash, lastBack);
|
||||
if (lastSep <= 0) return null;
|
||||
return trimmed.slice(0, lastSep);
|
||||
}
|
||||
|
||||
module.exports = { deriveWorkspaceDir };
|
||||
+22
-4
@@ -223,10 +223,15 @@ function getCreateQuickSwitcherOverlay() {
|
||||
let _createInlineAiController;
|
||||
function getCreateInlineAiController() {
|
||||
if (!_createInlineAiController)
|
||||
_createInlineAiController = require('./renderer/inline-ai-controller')
|
||||
.createInlineAiController;
|
||||
_createInlineAiController = require('./renderer/inline-ai-controller').createInlineAiController;
|
||||
return _createInlineAiController;
|
||||
}
|
||||
let _deriveWorkspaceDir;
|
||||
function getDeriveWorkspaceDir() {
|
||||
if (!_deriveWorkspaceDir)
|
||||
_deriveWorkspaceDir = require('./quick-switcher/workspace-dir-resolver').deriveWorkspaceDir;
|
||||
return _deriveWorkspaceDir;
|
||||
}
|
||||
function getPrintPreview() {
|
||||
if (!_PrintPreview) _PrintPreview = require('./print-preview').PrintPreview;
|
||||
return _PrintPreview;
|
||||
@@ -2578,7 +2583,18 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
// v4.13.0 — explorer-driven workspace dir is the next iteration;
|
||||
// for now the workspace toggle is a no-op and we surface only
|
||||
// recent files + open tabs.
|
||||
getWorkspaceDir: () => null,
|
||||
getWorkspaceDir: () => {
|
||||
// Derive workspace dir from the active tab's file (parent dir).
|
||||
// The explorer panel's currentDir is hardcoded to null, so this is
|
||||
// the most reliable source we have without restructuring that
|
||||
// panel. Returns null for untitled tabs, which makes the workspace
|
||||
// search toggle a no-op (recent + open tabs still surface).
|
||||
const derive = getDeriveWorkspaceDir();
|
||||
const active =
|
||||
tabManager.activeTab ||
|
||||
(tabManager.activeTabId && tabManager.tabs.get(tabManager.activeTabId));
|
||||
return active ? derive(active.filePath) : null;
|
||||
},
|
||||
});
|
||||
return quickSwitcherOverlayInstance;
|
||||
}
|
||||
@@ -2593,7 +2609,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
const create = getCreateInlineAiController();
|
||||
inlineAiControllerInstance = create({
|
||||
getEditorView: () => {
|
||||
const active = tabManager.activeTab || (tabManager.activeTabId && tabManager.tabs.get(tabManager.activeTabId));
|
||||
const active =
|
||||
tabManager.activeTab ||
|
||||
(tabManager.activeTabId && tabManager.tabs.get(tabManager.activeTabId));
|
||||
return active ? active.editorView : null;
|
||||
},
|
||||
electronAPI: window.electronAPI,
|
||||
|
||||
Reference in New Issue
Block a user