diff --git a/CHANGELOG.md b/CHANGELOG.md
index 890bfb89..075f4669 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
# Change Log
+## [10.6.0] - 2024-11-06 - [Release notes](https://beta.frontmatter.codes/updates/v10.6.0)
+
+### π¨ Enhancements
+
+- [#878](https://github.com/estruyf/vscode-front-matter/issues/878): Allow the `select all` button to work on other pages when there is a selection present
+- [#882](https://github.com/estruyf/vscode-front-matter/issues/882): Dynamic evaluation of the `node` executable path
+- [#884](https://github.com/estruyf/vscode-front-matter/issues/884): Hide WYSIWYG actions when the file is in git diff mode
+
+### π Fixes
+
+- [#859](https://github.com/estruyf/vscode-front-matter/issues/859): Fix label in the data view dropdown field
+- [#876](https://github.com/estruyf/vscode-front-matter/issues/876): Fix snippet type on the snippet card
+- [#879](https://github.com/estruyf/vscode-front-matter/issues/879): Fix for auto updating last modified date on save
+- [#885](https://github.com/estruyf/vscode-front-matter/issues/885): Fix content relationship for none i18n content
+
## [10.5.1] - 2024-10-23
### π¨ Enhancements
diff --git a/package.json b/package.json
index cfcfab5f..48cb83aa 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"displayName": "Front Matter CMS",
"description": "Front Matter is a CMS that runs within Visual Studio Code. It gives you the power and control of a full-blown CMS while also providing you the flexibility and speed of the static site generator of your choice like: Hugo, Jekyll, Docusaurus, NextJs, Gatsby, and many more...",
"icon": "assets/frontmatter-teal-128x128.png",
- "version": "10.5.1",
+ "version": "10.6.0",
"preview": false,
"publisher": "eliostruyf",
"galleryBanner": {
@@ -31,7 +31,7 @@
"l10n": "./l10n",
"categories": [
"AI",
- "Other"
+ "Visualization"
],
"keywords": [
"Front Matter",
@@ -2421,32 +2421,32 @@
"editor/title": [{
"command": "frontMatter.markup.heading",
"group": "navigation@-133",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.bold",
"group": "navigation@-132",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.italic",
"group": "navigation@-131",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.hyperlink",
"group": "navigation@-130",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.insertSnippet",
"group": "navigation@-129",
- "when": "frontMatter:file:isValid == true && frontMatter:dashboard:snippets:enabled"
+ "when": "frontMatter:file:isValid == true && frontMatter:dashboard:snippets:enabled && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.insertMedia",
"group": "navigation@-128",
- "when": "frontMatter:file:isValid == true"
+ "when": "frontMatter:file:isValid == true && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.i18n.createOrOpen",
@@ -2456,37 +2456,37 @@
{
"command": "frontMatter.markup.options",
"group": "navigation@-126",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.orderedlist",
"group": "1_markup@1",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.unorderedlist",
"group": "1_markup@2",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.tasklist",
"group": "1_markup@3",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.code",
"group": "1_markup@4",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.codeblock",
"group": "1_markup@5",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.blockquote",
"group": "1_markup@6",
- "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
+ "when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.dashboard",
diff --git a/src/commands/Article.ts b/src/commands/Article.ts
index b0e35076..044ef7da 100644
--- a/src/commands/Article.ts
+++ b/src/commands/Article.ts
@@ -52,7 +52,7 @@ export class Article {
*
* @param subscriptions - The array of subscriptions to register the commands with.
*/
- public static async registerCommands(subscriptions: unknown[]) {
+ public static registerCommands(subscriptions: unknown[]) {
subscriptions.push(
commands.registerCommand(COMMAND_NAME.setLastModifiedDate, Article.setLastModifiedDate)
);
@@ -66,6 +66,15 @@ export class Article {
subscriptions.push(commands.registerCommand(COMMAND_NAME.insertSnippet, Article.insertSnippet));
}
+ /**
+ * Registers event listeners for the Article class.
+ *
+ * @param subscriptions - An array to which the event listener will be added.
+ */
+ public static registerListeners(subscriptions: unknown[]) {
+ subscriptions.push(workspace.onWillSaveTextDocument(Article.autoUpdate));
+ }
+
/**
* Sets the article date
*/
@@ -369,15 +378,15 @@ export class Article {
* Article auto updater
* @param event
*/
- public static async autoUpdate(event: TextDocumentWillSaveEvent) {
+ public static autoUpdate(event: TextDocumentWillSaveEvent) {
const document = event.document;
if (document && ArticleHelper.isSupportedFile(document)) {
const autoUpdate = Settings.get(SETTING_AUTO_UPDATE_DATE);
// Is article located in one of the content folders
- const folders = await Folders.getCachedOrFresh();
+ const folders = Folders.getCached();
const documentPath = parseWinPath(document.fileName);
- const folder = folders.find((f) => documentPath.startsWith(f.path));
+ const folder = folders?.find((f) => documentPath.startsWith(f.path));
if (!folder) {
return;
}
diff --git a/src/components/uniforms-frontmatter/SelectField.tsx b/src/components/uniforms-frontmatter/SelectField.tsx
index 05f14200..331de380 100644
--- a/src/components/uniforms-frontmatter/SelectField.tsx
+++ b/src/components/uniforms-frontmatter/SelectField.tsx
@@ -42,6 +42,7 @@ function Select({
...props
}: SelectFieldProps) {
const multiple = fieldType === Array;
+
return (
@@ -84,11 +85,12 @@ function Select({
}}
ref={inputRef}
value={value ?? ''}
+ className='text-[var(--vscode-foreground)] bg-[var(--vscode-list-activeSelectionBackground)] rounded-[2px] active:border-transparent disabled:opacity-40 disabled:cursor-not-allowed focus:outline-none'
style={{ width: '100%', padding: '0.5rem' }}
>
- {(!!placeholder || !required || value === undefined) && !multiple && (
+ {(!required || value === undefined) && !multiple && (
)}
diff --git a/src/dashboardWebView/components/Common/ItemSelection.tsx b/src/dashboardWebView/components/Common/ItemSelection.tsx
index eeda2de4..13f9a99d 100644
--- a/src/dashboardWebView/components/Common/ItemSelection.tsx
+++ b/src/dashboardWebView/components/Common/ItemSelection.tsx
@@ -25,6 +25,9 @@ export const ItemSelection: React.FunctionComponent
= ({
{
+ e.stopPropagation();
+ }}
onChange={() => {
onMultiSelect(filePath);
}}
diff --git a/src/dashboardWebView/components/Header/ActionsBar.tsx b/src/dashboardWebView/components/Header/ActionsBar.tsx
index 612a7f17..8035a773 100644
--- a/src/dashboardWebView/components/Header/ActionsBar.tsx
+++ b/src/dashboardWebView/components/Header/ActionsBar.tsx
@@ -4,8 +4,7 @@ import { CommandLineIcon, PencilIcon, TrashIcon, ChevronDownIcon, XMarkIcon, Eye
import { useRecoilState, useRecoilValue } from 'recoil';
import { MultiSelectedItemsAtom, PagedItems, SelectedItemActionAtom, SelectedMediaFolderSelector, SettingsSelector } from '../../state';
import { ActionsBarItem } from './ActionsBarItem';
-import * as l10n from '@vscode/l10n';
-import { LocalizationKey } from '../../../localization';
+import { LocalizationKey, localize } from '../../../localization';
import { Alert } from '../Modals/Alert';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
@@ -68,8 +67,14 @@ export const ActionsBar: React.FunctionComponent = ({
}, [selectedFiles]);
const selectAllItems = React.useCallback(() => {
- setSelectedFiles([...pagedItems]);
- }, [pagedItems]);
+ const allSelected = [...selectedFiles, ...pagedItems];
+ setSelectedFiles(Array.from(new Set(allSelected)));
+ }, [selectedFiles, pagedItems]);
+
+ const hasAllItemsSelectedOnPage = React.useMemo(() => {
+ const selectedItemsOnPage = selectedFiles.filter((file) => pagedItems.includes(file));
+ return selectedItemsOnPage.length >= pagedItems.length;
+ }, [selectedFiles, pagedItems]);
const languageActions = React.useMemo(() => {
const actions: React.ReactNode[] = [];
@@ -92,7 +97,7 @@ export const ActionsBar: React.FunctionComponent = ({
})
}}>
- {l10n.t(LocalizationKey.commonTranslate)}
+ {localize(LocalizationKey.commonTranslate)}
)
@@ -107,7 +112,7 @@ export const ActionsBar: React.FunctionComponent = ({
className='flex items-center text-[var(--vscode-tab-inactiveForeground)] hover:text-[var(--vscode-tab-activeForeground)]'
>
- {l10n.t(LocalizationKey.commonLanguages)}
+ {localize(LocalizationKey.commonLanguages)}
@@ -163,7 +168,7 @@ export const ActionsBar: React.FunctionComponent = ({
disabled={selectedFiles.length === 0}
>
- {l10n.t(LocalizationKey.commonScripts)}
+ {localize(LocalizationKey.commonScripts)}
@@ -197,10 +202,10 @@ export const ActionsBar: React.FunctionComponent = ({
1}
onClick={viewFile}
- title={l10n.t(LocalizationKey.commonView)}
+ title={localize(LocalizationKey.commonView)}
>
- {l10n.t(LocalizationKey.commonView)}
+ {localize(LocalizationKey.commonView)}
{
@@ -211,10 +216,10 @@ export const ActionsBar: React.FunctionComponent = ({
messageHandler.send(DashboardMessage.rename, selectedFiles[0]);
setSelectedFiles([]);
}}
- title={l10n.t(LocalizationKey.commonRename)}
+ title={localize(LocalizationKey.commonRename)}
>
- {l10n.t(LocalizationKey.commonRename)}
+ {localize(LocalizationKey.commonRename)}
)
}
@@ -228,10 +233,10 @@ export const ActionsBar: React.FunctionComponent = ({
path: selectedFiles[0],
action: 'edit'
})}
- title={l10n.t(LocalizationKey.commonEdit)}
+ title={localize(LocalizationKey.commonEdit)}
>
- {l10n.t(LocalizationKey.commonEdit)}
+ {localize(LocalizationKey.commonEdit)}
>
)
@@ -245,10 +250,10 @@ export const ActionsBar: React.FunctionComponent = ({
className='hover:text-[var(--vscode-statusBarItem-errorBackground)]'
disabled={selectedFiles.length === 0}
onClick={() => setShowAlert(true)}
- title={l10n.t(LocalizationKey.commonDelete)}
+ title={localize(LocalizationKey.commonDelete)}
>
- {l10n.t(LocalizationKey.commonDelete)}
+ {localize(LocalizationKey.commonDelete)}
@@ -258,33 +263,33 @@ export const ActionsBar: React.FunctionComponent = ({
setSelectedFiles([])}
- title={l10n.t(LocalizationKey.dashboardHeaderActionsBarItemsSelected, selectedFiles.length)}
+ title={localize(LocalizationKey.dashboardHeaderActionsBarItemsSelected, selectedFiles.length)}
>
- {l10n.t(LocalizationKey.dashboardHeaderActionsBarItemsSelected, selectedFiles.length)}
+ {localize(LocalizationKey.dashboardHeaderActionsBarItemsSelected, selectedFiles.length)}
)
}
- {l10n.t(LocalizationKey.dashboardHeaderActionsBarSelectAll)}
+ {localize(LocalizationKey.dashboardHeaderActionsBarSelectAll)}
{showAlert && (
setShowAlert(false)}
trigger={onDeleteConfirm}
/>
diff --git a/src/dashboardWebView/components/Header/Filters.tsx b/src/dashboardWebView/components/Header/Filters.tsx
index c0c714e0..78fae729 100644
--- a/src/dashboardWebView/components/Header/Filters.tsx
+++ b/src/dashboardWebView/components/Header/Filters.tsx
@@ -10,7 +10,7 @@ import { LanguageFilter } from '../Filters/LanguageFilter';
export interface IFiltersProps { }
-export const Filters: React.FunctionComponent = (_: React.PropsWithChildren) => {
+export const Filters: React.FunctionComponent = () => {
const [crntFilters, setCrntFilters] = useRecoilState(FiltersAtom);
const [crntTag, setCrntTag] = useRecoilState(TagAtom);
const [crntCategory, setCrntCategory] = useRecoilState(CategoryAtom);
diff --git a/src/dashboardWebView/components/SnippetsView/Item.tsx b/src/dashboardWebView/components/SnippetsView/Item.tsx
index b62be87f..d54e4359 100644
--- a/src/dashboardWebView/components/SnippetsView/Item.tsx
+++ b/src/dashboardWebView/components/SnippetsView/Item.tsx
@@ -183,7 +183,7 @@ export const Item: React.FunctionComponent = ({
{
- snippet.isMediaSnippet ? l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeContent) : l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeMedia)
+ snippet.isMediaSnippet ? l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeMedia) : l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeContent)
}
diff --git a/src/extension.ts b/src/extension.ts
index 49c560bf..8c523e4e 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -14,7 +14,7 @@ import ContentProvider from './providers/ContentProvider';
import { PagesListener } from './listeners/dashboard';
import { ModeSwitch } from './services/ModeSwitch';
import { PagesParser } from './services/PagesParser';
-import { ContentType, Telemetry, Extension } from './helpers';
+import { ContentType, Extension } from './helpers';
import * as l10n from '@vscode/l10n';
import {
Backers,
@@ -121,8 +121,9 @@ export async function activate(context: vscode.ExtensionContext) {
// Register the taxonomy commands
Taxonomy.registerCommands(subscriptions);
- // Register all the article commands
+ // Register all the article commands and listeners
Article.registerCommands(subscriptions);
+ Article.registerListeners(subscriptions);
// Template creation
Template.registerCommands();
@@ -181,9 +182,6 @@ export async function activate(context: vscode.ExtensionContext) {
// Automatically run the command
triggerPageUpdate(`main`);
- // Listener for file edit changes
- subscriptions.push(vscode.workspace.onWillSaveTextDocument(handleAutoDateUpdate));
-
// Listener for file saves
subscriptions.push(PagesListener.saveFileWatcher());
@@ -241,16 +239,13 @@ export async function activate(context: vscode.ExtensionContext) {
// Subscribe all commands
subscriptions.push(PanelView, collapseAll, fmStatusBarItem);
+ // eslint-disable-next-line no-console
console.log(`π₯ππππ π¬πΊπππΎπ π’π¬π² πΊπΌππππΊππΎπ½! π±πΎπΊπ½π ππ πππΊππ πππππππ... π©βπ»π§βπ»π¨βπ»`);
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
export function deactivate() {}
-const handleAutoDateUpdate = (e: vscode.TextDocumentWillSaveEvent) => {
- Article.autoUpdate(e);
-};
-
const triggerPageUpdate = (location: string) => {
Logger.verbose(`Trigger page update: ${location}`);
pageUpdateDebouncer(() => {
diff --git a/src/helpers/CustomScript.ts b/src/helpers/CustomScript.ts
index 33c0e529..79d9aa70 100644
--- a/src/helpers/CustomScript.ts
+++ b/src/helpers/CustomScript.ts
@@ -1,5 +1,5 @@
import { Settings } from './SettingsHelper';
-import { CommandType, EnvironmentType } from './../models/PanelSettings';
+import { CommandType } from './../models/PanelSettings';
import { CustomScript as ICustomScript, ScriptType } from '../models/PanelSettings';
import { window, env as vscodeEnv, ProgressLocation, Uri, commands } from 'vscode';
import { ArticleHelper, Logger, MediaHelpers } from '.';
@@ -13,9 +13,8 @@ import { Dashboard } from '../commands/Dashboard';
import { DashboardCommand } from '../dashboardWebView/DashboardCommand';
import { ParsedFrontMatter } from '../parsers';
import { SETTING_CUSTOM_SCRIPTS } from '../constants';
-import { existsAsync } from '../utils';
-import * as l10n from '@vscode/l10n';
-import { LocalizationKey } from '../localization';
+import { evaluateCommand, existsAsync, getPlatform } from '../utils';
+import { LocalizationKey, localize } from '../localization';
export class CustomScript {
/**
@@ -101,7 +100,7 @@ export class CustomScript {
);
} else {
Notifications.warning(
- l10n.t(LocalizationKey.helpersCustomScriptSingleRunArticleWarning, script.title)
+ localize(LocalizationKey.helpersCustomScriptSingleRunArticleWarning, script.title)
);
}
}
@@ -117,7 +116,7 @@ export class CustomScript {
if (!folders || folders.length === 0) {
Notifications.warning(
- l10n.t(LocalizationKey.helpersCustomScriptBulkRunNoFilesWarning, script.title)
+ localize(LocalizationKey.helpersCustomScriptBulkRunNoFilesWarning, script.title)
);
return;
}
@@ -127,7 +126,7 @@ export class CustomScript {
window.withProgress(
{
location: ProgressLocation.Notification,
- title: l10n.t(LocalizationKey.helpersCustomScriptExecuting, script.title),
+ title: localize(LocalizationKey.helpersCustomScriptExecuting, script.title),
cancellable: false
},
async (_, __) => {
@@ -173,7 +172,7 @@ export class CustomScript {
): Promise {
if (!path) {
Notifications.error(
- l10n.t(LocalizationKey.helpersCustomScriptRunMediaScriptNoFolderWarning, script.title)
+ localize(LocalizationKey.helpersCustomScriptRunMediaScriptNoFolderWarning, script.title)
);
return;
}
@@ -182,7 +181,7 @@ export class CustomScript {
window.withProgress(
{
location: ProgressLocation.Notification,
- title: l10n.t(LocalizationKey.helpersCustomScriptExecuting, script.title),
+ title: localize(LocalizationKey.helpersCustomScriptExecuting, script.title),
cancellable: false
},
async () => {
@@ -309,7 +308,10 @@ export class CustomScript {
throw new Error(`Couldn't update article.`);
}
Notifications.info(
- l10n.t(LocalizationKey.helpersCustomScriptShowOutputFrontMatterSuccess, script.title)
+ localize(
+ LocalizationKey.helpersCustomScriptShowOutputFrontMatterSuccess,
+ script.title
+ )
);
}
} else if (data.fmAction) {
@@ -345,10 +347,12 @@ export class CustomScript {
window
.showInformationMessage(
`${script.title}: ${output}`,
- l10n.t(LocalizationKey.helpersCustomScriptShowOutputCopyOutputAction)
+ localize(LocalizationKey.helpersCustomScriptShowOutputCopyOutputAction)
)
.then((value) => {
- if (value === l10n.t(LocalizationKey.helpersCustomScriptShowOutputCopyOutputAction)) {
+ if (
+ value === localize(LocalizationKey.helpersCustomScriptShowOutputCopyOutputAction)
+ ) {
vscodeEnv.clipboard.writeText(output);
}
});
@@ -356,7 +360,7 @@ export class CustomScript {
}
} else {
Notifications.info(
- l10n.t(LocalizationKey.helpersCustomScriptShowOutputSuccess, script.title)
+ localize(LocalizationKey.helpersCustomScriptShowOutputSuccess, script.title)
);
}
}
@@ -373,7 +377,7 @@ export class CustomScript {
wsPath: string,
args: string
): Promise {
- const osType = os.type();
+ const platform = getPlatform();
// Check the command to use
let command = script.nodeBin || 'node';
@@ -381,6 +385,10 @@ export class CustomScript {
command = script.command;
}
+ if (script.command === CommandType.Node && platform !== 'windows') {
+ command = await evaluateCommand(CommandType.Node);
+ }
+
let scriptPath = join(wsPath, script.script);
if (script.script.includes(WORKSPACE_PLACEHOLDER)) {
scriptPath = Folders.getAbsFilePath(script.script);
@@ -388,19 +396,15 @@ export class CustomScript {
// Check if there is an environments overwrite required
if (script.environments) {
- let crntType: EnvironmentType | null = null;
- if (osType === 'Windows_NT') {
- crntType = 'windows';
- } else if (osType === 'Darwin') {
- crntType = 'macos';
- } else {
- crntType = 'linux';
- }
-
- const environment = script.environments.find((e) => e.type === crntType);
+ const environment = script.environments.find((e) => e.type === platform);
if (environment && environment.script && environment.command) {
if (await CustomScript.validateCommand(environment.command)) {
command = environment.command;
+
+ if (command === CommandType.Node && platform !== 'windows') {
+ command = await evaluateCommand(CommandType.Node);
+ }
+
scriptPath = join(wsPath, environment.script);
if (environment.script.includes(WORKSPACE_PLACEHOLDER)) {
scriptPath = Folders.getAbsFilePath(environment.script);
@@ -414,12 +418,12 @@ export class CustomScript {
throw new Error(`Script not found: ${scriptPath}`);
}
- if (osType === 'Windows_NT' && command.toLowerCase() === 'powershell') {
+ if (platform === 'windows' && command.toLowerCase() === 'powershell') {
command = `${command} -File`;
}
const fullScript = `${command} "${scriptPath}" ${args}`;
- Logger.info(l10n.t(LocalizationKey.helpersCustomScriptExecuting, fullScript));
+ Logger.info(localize(LocalizationKey.helpersCustomScriptExecuting, fullScript));
const output: string = await CustomScript.executeScriptAsync(fullScript, wsPath);
@@ -502,7 +506,7 @@ export class CustomScript {
return true;
} catch (e) {
- Logger.error(l10n.t(LocalizationKey.helpersCustomScriptValidateCommandError, command));
+ Logger.error(localize(LocalizationKey.helpersCustomScriptValidateCommandError, command));
return false;
}
}
diff --git a/src/helpers/DashboardSettings.ts b/src/helpers/DashboardSettings.ts
index d2275227..c26a8477 100644
--- a/src/helpers/DashboardSettings.ts
+++ b/src/helpers/DashboardSettings.ts
@@ -1,5 +1,5 @@
import { GitListener } from './../listeners/general/GitListener';
-import { basename, join } from 'path';
+import { join } from 'path';
import { workspace } from 'vscode';
import { Folders } from '../commands/Folders';
import { Project } from '../commands/Project';
@@ -23,7 +23,6 @@ import {
SETTING_MEDIA_SUPPORTED_MIMETYPES,
SETTING_TAXONOMY_CUSTOM,
SETTING_TEMPLATES_ENABLED,
- SETTING_GIT_ENABLED,
SETTING_DASHBOARD_CONTENT_PAGINATION,
SETTING_SNIPPETS_WRAPPER,
SETTING_DASHBOARD_CONTENT_CARD_DATE,
diff --git a/src/listeners/dashboard/SsgListener.ts b/src/listeners/dashboard/SsgListener.ts
index c7199df8..2b5ad5dd 100644
--- a/src/listeners/dashboard/SsgListener.ts
+++ b/src/listeners/dashboard/SsgListener.ts
@@ -12,7 +12,7 @@ import {
} from '../../constants';
import { SettingsListener } from './SettingsListener';
import { Terminal } from '../../services';
-import { existsAsync, readFileAsync } from '../../utils';
+import { evaluateCommand, existsAsync, getPlatform, readFileAsync } from '../../utils';
import { join } from 'path';
export class SsgListener extends BaseListener {
@@ -170,7 +170,12 @@ export class SsgListener extends BaseListener {
workspace.fs.copy(scriptPath, tempScriptPath, { overwrite: true });
}
- const fullScript = `node "${tempScriptPath.fsPath}" "${contentConfigFile.fsPath}"`;
+ let nodeExecPath = 'node';
+ const platform = getPlatform();
+ if (platform !== 'windows') {
+ nodeExecPath = await evaluateCommand('node');
+ }
+ const fullScript = `${nodeExecPath} "${tempScriptPath.fsPath}" "${contentConfigFile.fsPath}"`;
try {
const result: string = await SsgListener.executeScript(fullScript, wsFolder?.fsPath || '');
diff --git a/src/listeners/panel/FieldsListener.ts b/src/listeners/panel/FieldsListener.ts
index 6ebc62e0..65f673b3 100644
--- a/src/listeners/panel/FieldsListener.ts
+++ b/src/listeners/panel/FieldsListener.ts
@@ -39,17 +39,21 @@ export class FieldsListener extends BaseListener {
return;
}
+ const isLocaleEnabled = await i18n.isLocaleEnabled(data.activePath);
const activeLocale = await i18n.getLocale(data.activePath);
- if (!activeLocale?.locale) {
+ if (isLocaleEnabled && !activeLocale?.locale) {
return;
}
PagesListener.getPagesData(false, async (pages) => {
+ const fuseKeys: Fuse.FuseOptionKey[] = [{ name: 'fmContentType', weight: 1 }];
+
+ if (isLocaleEnabled && data.sameLocale) {
+ fuseKeys.push({ name: 'fmLocale.locale', weight: 1 });
+ }
+
const fuseOptions: Fuse.IFuseOptions = {
- keys: [
- { name: 'fmContentType', weight: 1 },
- ...(data.sameLocale ? [{ name: 'fmLocale.locale', weight: 1 }] : [])
- ],
+ keys: fuseKeys,
findAllMatches: true,
threshold: 0
};
@@ -60,11 +64,14 @@ export class FieldsListener extends BaseListener {
);
const fuseIndex = Fuse.parseIndex(pagesIndex);
const fuse = new Fuse(pages || [], fuseOptions, fuseIndex);
+
+ const andExpression: Fuse.Expression[] = [{ fmContentType: data.type ?? '' }];
+ if (isLocaleEnabled && activeLocale?.locale && data.sameLocale) {
+ andExpression.push({ 'fmLocale.locale': activeLocale.locale });
+ }
+
const results = fuse.search({
- $and: [
- { fmContentType: data.type! },
- ...(data.sameLocale ? [{ 'fmLocale.locale': activeLocale.locale }] : [])
- ]
+ $and: andExpression
});
const pageResults = results.map((page) => page.item);
diff --git a/src/models/ShellSetting.ts b/src/models/ShellSetting.ts
new file mode 100644
index 00000000..05a90dd8
--- /dev/null
+++ b/src/models/ShellSetting.ts
@@ -0,0 +1,3 @@
+export interface ShellSetting {
+ path: string;
+}
diff --git a/src/models/index.ts b/src/models/index.ts
index 82b09148..81684673 100644
--- a/src/models/index.ts
+++ b/src/models/index.ts
@@ -22,6 +22,7 @@ export * from './Mode';
export * from './PanelSettings';
export * from './PostMessageData';
export * from './Project';
+export * from './ShellSetting';
export * from './Snippets';
export * from './SortOrder';
export * from './SortType';
diff --git a/src/services/Terminal.ts b/src/services/Terminal.ts
index fa6b2ff3..4c9aa06c 100644
--- a/src/services/Terminal.ts
+++ b/src/services/Terminal.ts
@@ -1,12 +1,7 @@
import { workspace, window, ThemeIcon, TerminalOptions } from 'vscode';
-import * as os from 'os';
import { Folders } from '../commands';
-import * as l10n from '@vscode/l10n';
-import { LocalizationKey } from '../localization';
-
-interface ShellSetting {
- path: string;
-}
+import { LocalizationKey, localize } from '../localization';
+import { getShellPath } from '../utils';
export class Terminal {
public static readonly terminalName: string = 'Local server';
@@ -15,7 +10,7 @@ export class Terminal {
* Return the shell path for the current platform
*/
public static get shell() {
- const shell: string | { path: string } | undefined = Terminal.getShellPath();
+ const shell: string | { path: string } | undefined = getShellPath();
let shellPath: string | undefined = undefined;
if (typeof shell !== 'string' && !!shell) {
@@ -47,7 +42,7 @@ export class Terminal {
const terminalOptions: TerminalOptions = {
name: Terminal.terminalName,
iconPath: new ThemeIcon('server-environment'),
- message: l10n.t(
+ message: localize(
LocalizationKey.servicesTerminalOpenLocalServerTerminalTerminalOptionMessage
)
};
@@ -90,46 +85,4 @@ export class Terminal {
return localServerTerminal;
}
}
-
- /**
- * Retrieve the automation profile for the current platform
- * @returns
- */
- private static getShellPath(): string | ShellSetting | undefined {
- const platform = Terminal.getPlatform();
- const terminalSettings = workspace.getConfiguration('terminal');
-
- const automationProfile = terminalSettings.get(
- `integrated.automationProfile.${platform}`
- );
- if (!!automationProfile) {
- return automationProfile;
- }
-
- const defaultProfile = terminalSettings.get(`integrated.defaultProfile.${platform}`);
- const profiles = terminalSettings.get<{ [prop: string]: ShellSetting }>(
- `integrated.profiles.${platform}`
- );
-
- if (defaultProfile && profiles && profiles[defaultProfile]) {
- return profiles[defaultProfile];
- }
-
- return terminalSettings.get(`integrated.shell.${platform}`);
- }
-
- /**
- * Get the current platform
- * @returns
- */
- private static getPlatform = (): 'windows' | 'linux' | 'osx' => {
- const platform = os.platform();
- if (platform === 'win32') {
- return 'windows';
- } else if (platform === 'darwin') {
- return 'osx';
- }
-
- return 'linux';
- };
}
diff --git a/src/utils/evaluateCommand.ts b/src/utils/evaluateCommand.ts
new file mode 100644
index 00000000..735c6a5a
--- /dev/null
+++ b/src/utils/evaluateCommand.ts
@@ -0,0 +1,30 @@
+import { exec } from 'child_process';
+import { getShellPath } from '../utils';
+import { Logger } from '../helpers';
+
+/**
+ * Evaluate the command dynamically using `which` command
+ * @param command
+ * @returns
+ */
+export const evaluateCommand = (command: string): Promise => {
+ const shell = getShellPath();
+ let shellPath: string | undefined = undefined;
+ if (typeof shell !== 'string' && !!shell) {
+ shellPath = shell.path;
+ } else {
+ shellPath = shell || undefined;
+ }
+
+ return new Promise((resolve, reject) => {
+ exec(`which ${command}`, { shell: shellPath }, (error, stdout) => {
+ if (error) {
+ Logger.error(`Error evaluating command: ${command}`);
+ reject(error);
+ return;
+ }
+
+ resolve(stdout.trim());
+ });
+ });
+};
diff --git a/src/utils/getPlatform.ts b/src/utils/getPlatform.ts
new file mode 100644
index 00000000..da5b4f77
--- /dev/null
+++ b/src/utils/getPlatform.ts
@@ -0,0 +1,20 @@
+import * as os from 'os';
+
+/**
+ * Determines the current operating system platform.
+ *
+ * @returns {'windows' | 'linux' | 'osx'} - A string representing the platform:
+ * - 'windows' for Windows OS
+ * - 'osx' for macOS
+ * - 'linux' for Linux OS
+ */
+export const getPlatform = (): 'windows' | 'linux' | 'osx' => {
+ const platform = os.platform();
+ if (platform === 'win32') {
+ return 'windows';
+ } else if (platform === 'darwin') {
+ return 'osx';
+ }
+
+ return 'linux';
+};
diff --git a/src/utils/getShellPath.ts b/src/utils/getShellPath.ts
new file mode 100644
index 00000000..62bca2a0
--- /dev/null
+++ b/src/utils/getShellPath.ts
@@ -0,0 +1,36 @@
+import { workspace } from 'vscode';
+import { ShellSetting } from '../models';
+import { getPlatform } from './getPlatform';
+
+/**
+ * Retrieves the shell path configuration based on the current platform and terminal settings.
+ *
+ * This method checks for the following configurations in order:
+ * 1. `integrated.automationProfile.`: Returns the automation profile if it exists.
+ * 2. `integrated.defaultProfile.` and `integrated.profiles.`: Returns the shell setting from the default profile if it exists.
+ * 3. `integrated.shell.`: Returns the shell setting if the above configurations are not found.
+ *
+ * @returns {string | ShellSetting | undefined} The shell path configuration or undefined if not found.
+ */
+export const getShellPath = (): string | ShellSetting | undefined => {
+ const platform = getPlatform();
+ const terminalSettings = workspace.getConfiguration('terminal');
+
+ const automationProfile = terminalSettings.get(
+ `integrated.automationProfile.${platform}`
+ );
+ if (!!automationProfile) {
+ return automationProfile;
+ }
+
+ const defaultProfile = terminalSettings.get(`integrated.defaultProfile.${platform}`);
+ const profiles = terminalSettings.get<{ [prop: string]: ShellSetting }>(
+ `integrated.profiles.${platform}`
+ );
+
+ if (defaultProfile && profiles && profiles[defaultProfile]) {
+ return profiles[defaultProfile];
+ }
+
+ return terminalSettings.get(`integrated.shell.${platform}`);
+};
diff --git a/src/utils/index.ts b/src/utils/index.ts
index f1013c87..49951555 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -1,6 +1,7 @@
export * from './cn';
export * from './copyFileAsync';
export * from './encodeEmoji';
+export * from './evaluateCommand';
export * from './existsAsync';
export * from './fetchWithTimeout';
export * from './fieldWhenClause';
@@ -8,6 +9,8 @@ export * from './flattenObjectKeys';
export * from './getDescriptionField';
export * from './getExtensibilityScripts';
export * from './getLocalizationFile';
+export * from './getPlatform';
+export * from './getShellPath';
export * from './getTitleField';
export * from './getWebviewJsFiles';
export * from './ignoreMsgCommand';