Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9d3eca431 | ||
|
|
486beaf650 | ||
|
|
6e82cf221e | ||
|
|
46b9591859 | ||
|
|
3e76da58f5 | ||
|
|
9d42bd2f97 | ||
|
|
75890ec6e8 | ||
|
|
fb0429e40f | ||
|
|
8db813a661 | ||
|
|
2655be9aae | ||
|
|
fc99756136 | ||
|
|
9159a98dbe |
@@ -1,5 +1,14 @@
|
||||
# Change Log
|
||||
|
||||
## [2.4.0] - 2020-08-16
|
||||
|
||||
- [#21](https://github.com/estruyf/vscode-front-matter/issues/21): Folding provider for Front Matter implemented
|
||||
- [#55](https://github.com/estruyf/vscode-front-matter/issues/55): Highlight Front Matter in Markdown files
|
||||
- [#56](https://github.com/estruyf/vscode-front-matter/issues/56): Action to collapse all Front Matter panel sections at once
|
||||
- [#57](https://github.com/estruyf/vscode-front-matter/issues/57): New action added to provide better writing settings (only for Markdown files)
|
||||
- [#58](https://github.com/estruyf/vscode-front-matter/issues/58): Sections remember their previous state (folded/unfolded)
|
||||
- [#59](https://github.com/estruyf/vscode-front-matter/issues/59): Center layout view toggle action added
|
||||
|
||||
## [2.3.0] - 2020-08-10
|
||||
|
||||
- Refactoring and showing other actions in the base view
|
||||
|
||||
39
README.md
@@ -35,6 +35,7 @@ In version v2.0.0 we released the newly redesigned sidebar panel with improved S
|
||||
<details open="open">
|
||||
<summary>Table of Contents</summary>
|
||||
<ol>
|
||||
<li><a href="#markdown-features">Markdown features</a></li>
|
||||
<li><a href="#the-panel">The panel</a></li>
|
||||
<li><a href="#custom-actions">Custom actions</a></li>
|
||||
<li><a href="#creating-articles-from-templates">Create articles from templates</a></li>
|
||||
@@ -45,6 +46,24 @@ In version v2.0.0 we released the newly redesigned sidebar panel with improved S
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
## Markdown features
|
||||
|
||||
The Front Matter extension tries to make it easy to manage your Markdown pages/content. Within a Markdown page, we allow you to fold the file's Front Matter to be less distracting when writing. Also, do we highlight the Front Matter content to create a visual difference between content and metadata.
|
||||
|
||||
### Front Matter folding
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.4.0/folding.png" alt="Front Matter folding" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
### Front Matter highlighting
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.4.0/fm-highlight.png" alt="Front Matter highlighting" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
> **Info**: If you do not want this feature, you can disable it in the extension settings -> `Highlight Front Matter` or by setting the `frontMatter.content.fmHighlight` setting to `false`.
|
||||
|
||||
## The panel
|
||||
|
||||
The Front Matter panel allows you to perform most of the extension actions by just a click on the button and it shows the SEO statuses of your title, description, and more.
|
||||
@@ -56,7 +75,7 @@ To leverage most of the capabilities of the extension. SEO information and every
|
||||
When you open the panel and the current file is not a Markdown file, it will contain the following sections:
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.3.0/baseview.png" alt="Base view" style="display: inline-block" />
|
||||
<img src="./assets/v2.4.0/baseview.png" alt="Base view" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
> **Info**: both **Global Settings** and **Other Actions** sections are shown for the base view as when a Markdown file is openend.
|
||||
@@ -66,7 +85,7 @@ When you open the Front Matter panel on a Markdown file, you get to see the foll
|
||||
**Global Settings**
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.3.0/global-settings.png.png" alt="Global settings" style="display: inline-block" />
|
||||
<img src="./assets/v2.4.0/global-settings.png" alt="Global settings" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
**SEO Status**
|
||||
@@ -78,7 +97,7 @@ When you open the Front Matter panel on a Markdown file, you get to see the foll
|
||||
**Actions**
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.0.0/actions.png" alt="Actions" style="display: inline-block" />
|
||||
<img src="./assets/v2.4.0/actions.png" alt="Actions" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
**Metadata: Keywords, Tags, Categories**
|
||||
@@ -92,9 +111,11 @@ When you open the Front Matter panel on a Markdown file, you get to see the foll
|
||||
**Other actions**
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.3.0/other-actions.png" alt="Other actions" style="display: inline-block" />
|
||||
<img src="./assets/v2.4.0/other-actions.png" alt="Other actions" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
**Info**: The `Enable write settings` action allow you to make Markdown specific changes to optimize the writing of your articles. It will change settings like the `fontSize`, `lineHeight`, `wordWrap`, `lineNumbers` and more.
|
||||
|
||||
## Custom actions
|
||||
|
||||
Since version `1.15.0`, the extension allows you to create your own custom actions, by running Node.js scripts from your project. In order to use this functionality, you will need to configure the [`frontMatter.custom.scripts`](#frontmattercustomscripts) setting for your project.
|
||||
@@ -373,6 +394,16 @@ Specify if you want to automatically update the modification date of your markdo
|
||||
}
|
||||
```
|
||||
|
||||
### `frontMatter.content.fmHighlight`
|
||||
|
||||
Specify if you want to highlight the Front Matter in the Markdown file. Default: `true`.
|
||||
|
||||
```json
|
||||
{
|
||||
"frontMatter.content.fmHighlight": true
|
||||
}
|
||||
```
|
||||
|
||||
## Feedback / issues / ideas
|
||||
|
||||
Please submit them via creating an issue in the project repository: [issue list](https://github.com/estruyf/vscode-front-matter/issues).
|
||||
|
||||
4
assets/icons/close-dark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="32px" height="32px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#F3EFF5">
|
||||
<path d="M9 9H4v1h5V9z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3l1-1h7l1 1v7l-1 1h-2v2l-1 1H3l-1-1V6l1-1h2V3zm1 2h4l1 1v4h2V3H6v2zm4 1H3v7h7V6z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 277 B |
4
assets/icons/close-light.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="32px" height="32px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentcolor">
|
||||
<path d="M9 9H4v1h5V9z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3l1-1h7l1 1v7l-1 1h-2v2l-1 1H3l-1-1V6l1-1h2V3zm1 2h4l1 1v4h2V3H6v2zm4 1H3v7h7V6z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 282 B |
@@ -278,10 +278,21 @@
|
||||
.ext_link_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ext_link_block svg {
|
||||
margin-right: .5rem;
|
||||
display: block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
}
|
||||
|
||||
.ext_link_block button span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ext_link_block button,
|
||||
@@ -301,6 +312,16 @@
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ext_link_block button.active {
|
||||
color: var(--vscode-button-foreground);
|
||||
background: var(--vscode-button-background);
|
||||
}
|
||||
.ext_link_block button.active:hover {
|
||||
cursor: pointer;
|
||||
background: var(--vscode-button-hoverBackground);
|
||||
}
|
||||
|
||||
.ext_link_block a:hover,
|
||||
|
||||
BIN
assets/v2.4.0/actions.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
assets/v2.4.0/baseview.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
assets/v2.4.0/fm-highlight.png
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
assets/v2.4.0/folding.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/v2.4.0/global-settings.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/v2.4.0/other-actions.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
8
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vscode-front-matter",
|
||||
"version": "2.3.0",
|
||||
"version": "2.4.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -3565,9 +3565,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"pbkdf2": {
|
||||
|
||||
67
package.json
@@ -3,7 +3,7 @@
|
||||
"displayName": "Front Matter",
|
||||
"description": "Simplifies working with front matter of your articles. Useful extension when you are using a static site generator like: Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...",
|
||||
"icon": "assets/front-matter.png",
|
||||
"version": "2.3.0",
|
||||
"version": "2.4.0",
|
||||
"preview": false,
|
||||
"publisher": "eliostruyf",
|
||||
"galleryBanner": {
|
||||
@@ -57,6 +57,7 @@
|
||||
"onCommand:frontMatter.unregisterFolder",
|
||||
"onCommand:frontMatter.createContent",
|
||||
"onCommand:frontMatter.init",
|
||||
"onCommand:frontMatter.collapseSections",
|
||||
"onView:frontMatter.explorer"
|
||||
],
|
||||
"main": "./dist/extension",
|
||||
@@ -84,6 +85,31 @@
|
||||
"configuration": {
|
||||
"title": "Front Matter: Configuration",
|
||||
"properties": {
|
||||
"frontMatter.content.autoUpdateDate": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Specify if you want to automatically update the modified date of your article/page."
|
||||
},
|
||||
"frontMatter.content.fmHighlight": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Specify if you want to highlight the Front Matter in the Markdown file."
|
||||
},
|
||||
"frontMatter.content.folders": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"markdownDescription": "This array of folders defines where the extension can easily create new content by running the create article command."
|
||||
},
|
||||
"frontMatter.custom.scripts": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"markdownDescription": "Specify the path to a Node.js script to execute. The current file path will be provided as an argument."
|
||||
},
|
||||
"frontMatter.panel.freeform": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"markdownDescription": "Specifies if you want to allow yourself from entering unknown tags/categories in the tag picker (when enabled, you will have the option to store them afterwards). Default: true."
|
||||
},
|
||||
"frontMatter.taxonomy.dateField": {
|
||||
"type": "string",
|
||||
"default": "date",
|
||||
@@ -94,11 +120,6 @@
|
||||
"default": "lastmod",
|
||||
"description": "Specifies the modified date field name to use in your Front Matter"
|
||||
},
|
||||
"frontMatter.content.autoUpdateDate": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Specify if you want to automatically update the modified date of your article/page."
|
||||
},
|
||||
"frontMatter.taxonomy.tags": {
|
||||
"type": "array",
|
||||
"description": "Specifies the tags which can be used in the Front Matter"
|
||||
@@ -175,21 +196,6 @@
|
||||
"type": "string",
|
||||
"default": "yyyy-MM-dd",
|
||||
"description": "Specify the prefix you want to add for your new article filenames."
|
||||
},
|
||||
"frontMatter.panel.freeform": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"markdownDescription": "Specifies if you want to allow yourself from entering unknown tags/categories in the tag picker (when enabled, you will have the option to store them afterwards). Default: true."
|
||||
},
|
||||
"frontMatter.custom.scripts": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"markdownDescription": "Specify the path to a Node.js script to execute. The current file path will be provided as an argument."
|
||||
},
|
||||
"frontMatter.content.folders": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"markdownDescription": "This array of folders defines where the extension can easily create new content by running the create article command."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -268,6 +274,15 @@
|
||||
"command": "frontMatter.createTemplate",
|
||||
"title": "Create a template from current file",
|
||||
"category": "Front matter"
|
||||
},
|
||||
{
|
||||
"command": "frontMatter.collapseSections",
|
||||
"title": "Collapse sections",
|
||||
"category": "Front matter",
|
||||
"icon": {
|
||||
"light": "assets/icons/close-light.svg",
|
||||
"dark": "assets/icons/close-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -296,6 +311,16 @@
|
||||
{
|
||||
"command": "frontMatter.createTemplate",
|
||||
"when": "!frontMatterCanInit"
|
||||
},
|
||||
{
|
||||
"command": "frontMatter.collapseSections",
|
||||
"when": "false"
|
||||
}
|
||||
],
|
||||
"view/title": [
|
||||
{
|
||||
"command": "frontMatter.collapseSections",
|
||||
"group": "navigation"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -20,5 +20,6 @@ export const COMMAND_NAME = {
|
||||
registerFolder: getCommandName("registerFolder"),
|
||||
unregisterFolder: getCommandName("unregisterFolder"),
|
||||
createContent: getCommandName("createContent"),
|
||||
createTemplate: getCommandName("createTemplate")
|
||||
createTemplate: getCommandName("createTemplate"),
|
||||
collapseSections: getCommandName("collapseSections"),
|
||||
};
|
||||
@@ -7,7 +7,6 @@ export const SETTING_TAXONOMY_CATEGORIES = "taxonomy.categories";
|
||||
export const SETTING_DATE_FORMAT = "taxonomy.dateFormat";
|
||||
export const SETTING_DATE_FIELD = "taxonomy.dateField";
|
||||
export const SETTING_MODIFIED_FIELD = "taxonomy.modifiedField";
|
||||
export const SETTING_AUTO_UPDATE_DATE = "content.autoUpdateDate";
|
||||
|
||||
export const SETTING_SLUG_PREFIX = "taxonomy.slugPrefix";
|
||||
export const SETTING_SLUG_SUFFIX = "taxonomy.slugSuffix";
|
||||
@@ -30,4 +29,6 @@ export const SETTING_PANEL_FREEFORM = "panel.freeform";
|
||||
|
||||
export const SETTING_CUSTOM_SCRIPTS = "custom.scripts";
|
||||
|
||||
export const SETTINGS_CONTENT_FOLDERS = "content.folders";
|
||||
export const SETTING_AUTO_UPDATE_DATE = "content.autoUpdateDate";
|
||||
export const SETTINGS_CONTENT_FOLDERS = "content.folders";
|
||||
export const SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT = "content.fmHighlight";
|
||||
@@ -5,6 +5,7 @@ import { Project } from './commands/Project';
|
||||
import { Template } from './commands/Template';
|
||||
import { COMMAND_NAME } from './constants/Extension';
|
||||
import { TaxonomyType } from './models';
|
||||
import { MarkdownFoldingProvider } from './providers/MarkdownFoldingProvider';
|
||||
import { TagType } from './viewpanel/TagType';
|
||||
import { ExplorerView } from './webview/ExplorerView';
|
||||
|
||||
@@ -13,6 +14,8 @@ let statusDebouncer: { (fnc: any, time: number): void; };
|
||||
let editDebounce: { (fnc: any, time: number): void; };
|
||||
let collection: vscode.DiagnosticCollection;
|
||||
|
||||
const mdSelector: vscode.DocumentSelector = { language: 'markdown', scheme: 'file' };
|
||||
|
||||
export async function activate({ subscriptions, extensionUri }: vscode.ExtensionContext) {
|
||||
collection = vscode.languages.createDiagnosticCollection('frontMatter');
|
||||
|
||||
@@ -23,6 +26,9 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
}
|
||||
});
|
||||
|
||||
// Folding the front matter of markdown files
|
||||
vscode.languages.registerFoldingRangeProvider(mdSelector, new MarkdownFoldingProvider());
|
||||
|
||||
let insertTags = vscode.commands.registerCommand(COMMAND_NAME.insertTags, async () => {
|
||||
await vscode.commands.executeCommand('workbench.view.extension.frontmatter-explorer');
|
||||
await vscode.commands.executeCommand('workbench.action.focusSideBar');
|
||||
@@ -68,7 +74,7 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
if (folderPath) {
|
||||
Template.create(folderPath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let createTemplate = vscode.commands.registerCommand(COMMAND_NAME.createTemplate, Template.generate);
|
||||
|
||||
@@ -91,6 +97,11 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
Template.init();
|
||||
const projectInit = vscode.commands.registerCommand(COMMAND_NAME.init, Project.init);
|
||||
|
||||
// Collapse all sections in the webview
|
||||
const collapseAll = vscode.commands.registerCommand(COMMAND_NAME.collapseSections, () => {
|
||||
ExplorerView.getInstance()?.collapseAll();
|
||||
});
|
||||
|
||||
// Things to do when configuration changes
|
||||
vscode.workspace.onDidChangeConfiguration(() => {
|
||||
Template.init();
|
||||
@@ -132,7 +143,8 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
|
||||
registerFolder,
|
||||
unregisterFolder,
|
||||
createContent,
|
||||
projectInit
|
||||
projectInit,
|
||||
collapseAll
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ export interface PanelSettings {
|
||||
isInitialized: boolean;
|
||||
modifiedDateUpdate: boolean;
|
||||
contentInfo: FolderInfo[] | null;
|
||||
writingSettingsEnabled: boolean;
|
||||
fmHighlighting: boolean;
|
||||
}
|
||||
|
||||
export interface SEO {
|
||||
|
||||
13
src/providers/FrontMatterDecorationProvider.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { TextEditorDecorationType, window, ColorThemeKind } from "vscode";
|
||||
|
||||
export class FrontMatterDecorationProvider {
|
||||
|
||||
get(): TextEditorDecorationType {
|
||||
const colorThemeKind = window.activeColorTheme.kind;
|
||||
|
||||
return window.createTextEditorDecorationType({
|
||||
backgroundColor: colorThemeKind === ColorThemeKind.Dark ? "#ffffff14" : "#00000014",
|
||||
isWholeLine: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
57
src/providers/MarkdownFoldingProvider.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { workspace } from 'vscode';
|
||||
import { CancellationToken, FoldingContext, FoldingRange, FoldingRangeKind, FoldingRangeProvider, Range, TextDocument, window, Position } from 'vscode';
|
||||
import { CONFIG_KEY, SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT } from '../constants';
|
||||
import { FrontMatterDecorationProvider } from './FrontMatterDecorationProvider';
|
||||
|
||||
export class MarkdownFoldingProvider implements FoldingRangeProvider {
|
||||
private static start: number | null = null;
|
||||
private static end: number | null = null;
|
||||
private static endLine: number | null = null;
|
||||
|
||||
public async provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken): Promise<FoldingRange[]> {
|
||||
const ranges: FoldingRange[] = [];
|
||||
|
||||
const lines = document.getText().split('\n');
|
||||
let start: number | null = null;
|
||||
let end: number | null = null;
|
||||
|
||||
MarkdownFoldingProvider.start = null;
|
||||
MarkdownFoldingProvider.end = null;
|
||||
MarkdownFoldingProvider.endLine = null;
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line.startsWith('---')) {
|
||||
if (i === 0 && start === null) {
|
||||
start = i;
|
||||
MarkdownFoldingProvider.start = start;
|
||||
} else if (start !== null && end === null) {
|
||||
end = i;
|
||||
MarkdownFoldingProvider.end = end;
|
||||
MarkdownFoldingProvider.endLine = line.length;
|
||||
|
||||
MarkdownFoldingProvider.triggerHighlighting();
|
||||
|
||||
ranges.push(new FoldingRange(start, end, FoldingRangeKind.Region));
|
||||
return ranges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
public static triggerHighlighting() {
|
||||
const config = workspace.getConfiguration(CONFIG_KEY);
|
||||
const fmHighlight = config.get<boolean>(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT);
|
||||
|
||||
if (MarkdownFoldingProvider.start !== null && MarkdownFoldingProvider.end !== null && MarkdownFoldingProvider.endLine !== null) {
|
||||
const range = new Range(new Position(MarkdownFoldingProvider.start, 0), new Position(MarkdownFoldingProvider.end, MarkdownFoldingProvider.endLine));
|
||||
|
||||
if (fmHighlight) {
|
||||
const decoration = new FrontMatterDecorationProvider().get();
|
||||
window.activeTextEditor?.setDecorations(decoration, [range]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,5 +3,6 @@ export enum Command {
|
||||
metadata = "metadata",
|
||||
settings = "settings",
|
||||
focusOnTags = "focusOnTags",
|
||||
focusOnCategories = "focusOnCategories"
|
||||
focusOnCategories = "focusOnCategories",
|
||||
closeSections = "closeSections",
|
||||
}
|
||||
@@ -16,5 +16,8 @@ export enum CommandToCode {
|
||||
initProject = "init-project",
|
||||
createContent = "create-content",
|
||||
updateModifiedUpdating = "update-modified-updates",
|
||||
updateFmHighlight = "update-fm-highlight",
|
||||
createTemplate = "create-template",
|
||||
toggleCenterMode = "toggle-center-mode",
|
||||
toggleWritingSettings = "toggle-writing-settings",
|
||||
}
|
||||
@@ -43,7 +43,7 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React
|
||||
settings && metadata && <Actions metadata={metadata} settings={settings} />
|
||||
}
|
||||
|
||||
<Collapsible title="Metadata" className={`inherit z-20`}>
|
||||
<Collapsible id={`tags`} title="Metadata" className={`inherit z-20`}>
|
||||
{
|
||||
<TagPicker type={TagType.keywords}
|
||||
icon={<SymbolKeywordIcon />}
|
||||
@@ -78,7 +78,7 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React
|
||||
}
|
||||
</Collapsible>
|
||||
|
||||
<OtherActions isFile={true} />
|
||||
<OtherActions settings={settings} isFile={true} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
16
src/viewpanel/components/ActionButton.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IActionButtonProps {
|
||||
title: string;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
onClick: (e: React.SyntheticEvent<HTMLButtonElement>) => void;
|
||||
}
|
||||
|
||||
export const ActionButton: React.FunctionComponent<IActionButtonProps> = ({className, onClick, disabled,title}: React.PropsWithChildren<IActionButtonProps>) => {
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={onClick} className={className || ""} disabled={disabled}>{title}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { PanelSettings } from '../../models/PanelSettings';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
import { Collapsible } from './Collapsible';
|
||||
import { CustomScript } from './CustomScript';
|
||||
import { DateAction } from './DateAction';
|
||||
@@ -19,8 +22,11 @@ export const Actions: React.FunctionComponent<IActionsProps> = (props: React.Pro
|
||||
}
|
||||
|
||||
return (
|
||||
<Collapsible title="Actions">
|
||||
<Collapsible id={`actions`} title="Actions">
|
||||
<div className={`article__actions`}>
|
||||
|
||||
<ActionButton onClick={() => MessageHelper.sendMessage(CommandToCode.toggleCenterMode)} title={`Toggle center mode`} />
|
||||
|
||||
{ metadata && metadata.title && <SlugAction value={metadata.title} crntValue={metadata.slug} slugOpts={settings.slug} /> }
|
||||
|
||||
<DateAction />
|
||||
|
||||
@@ -23,9 +23,9 @@ export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: Re
|
||||
return (
|
||||
<div className="frontmatter">
|
||||
<div className={`ext_actions`}>
|
||||
<GlobalSettings settings={settings} />
|
||||
<GlobalSettings settings={settings} isBase />
|
||||
|
||||
<Collapsible title="Actions">
|
||||
<Collapsible id={`base_actions`} title="Actions">
|
||||
<div className={`base__actions`}>
|
||||
<button onClick={initProject} disabled={settings?.isInitialized}>Initialize project</button>
|
||||
<button onClick={createContent} disabled={!settings?.isInitialized}>Create new content</button>
|
||||
@@ -34,7 +34,7 @@ export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: Re
|
||||
|
||||
{
|
||||
settings?.contentInfo && (
|
||||
<Collapsible title="Content information">
|
||||
<Collapsible id={`base_content`} title="Content information">
|
||||
<div className="base__information">
|
||||
{
|
||||
settings.contentInfo.map(folder => (
|
||||
@@ -48,7 +48,7 @@ export const BaseView: React.FunctionComponent<IBaseViewProps> = ({settings}: Re
|
||||
)
|
||||
}
|
||||
|
||||
<OtherActions isFile={false} />
|
||||
<OtherActions settings={settings} isFile={false} isBase />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { Command } from '../Command';
|
||||
import { VsCollapsible } from './VscodeComponents';
|
||||
|
||||
export interface ICollapsibleProps {
|
||||
id: string;
|
||||
title: string;
|
||||
className?: string;
|
||||
sendUpdate?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export const Collapsible: React.FunctionComponent<ICollapsibleProps> = ({children, title, sendUpdate, className}: React.PropsWithChildren<ICollapsibleProps>) => {
|
||||
const [ isOpen, setIsOpen ] = React.useState(true);
|
||||
export const Collapsible: React.FunctionComponent<ICollapsibleProps> = ({id, children, title, sendUpdate, className}: React.PropsWithChildren<ICollapsibleProps>) => {
|
||||
const [ isOpen, setIsOpen ] = React.useState(false);
|
||||
const collapseKey = `collapse-${id}`;
|
||||
|
||||
const updateStorage = (value: boolean) => {
|
||||
window.localStorage.setItem(collapseKey, value.toString());
|
||||
}
|
||||
|
||||
// This is a work around for a lit-element issue of duplicate slot names
|
||||
const triggerClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||
@@ -17,11 +25,29 @@ export const Collapsible: React.FunctionComponent<ICollapsibleProps> = ({childre
|
||||
if (sendUpdate) {
|
||||
sendUpdate(!prev);
|
||||
}
|
||||
|
||||
updateStorage(!prev);
|
||||
return !prev;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const collapsed = window.localStorage.getItem(collapseKey);
|
||||
if (collapsed === null || collapsed === 'true') {
|
||||
setIsOpen(true);
|
||||
updateStorage(true);
|
||||
}
|
||||
|
||||
window.addEventListener('message', event => {
|
||||
const message = event.data;
|
||||
if (message.command === Command.closeSections) {
|
||||
setIsOpen(false);
|
||||
updateStorage(false);
|
||||
}
|
||||
});
|
||||
}, ['']);
|
||||
|
||||
return (
|
||||
<VsCollapsible title={title} onClick={triggerClick} open={isOpen}>
|
||||
<div className={`section collapsible__body ${className || ""}`} slot="body">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface ICustomScriptProps {
|
||||
title: string;
|
||||
@@ -14,8 +15,6 @@ export const CustomScript: React.FunctionComponent<ICustomScriptProps> = ({title
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={runCustomScript}>{title}</button>
|
||||
</div>
|
||||
<ActionButton onClick={runCustomScript} title={title} />
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface IDateActionProps {}
|
||||
|
||||
@@ -16,12 +17,8 @@ export const DateAction: React.FunctionComponent<IDateActionProps> = (props: Rea
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`article__action`}>
|
||||
<button onClick={setDate}>Set publish date</button>
|
||||
</div>
|
||||
<div className={`article__action`}>
|
||||
<button onClick={setLastMod}>Set modified date</button>
|
||||
</div>
|
||||
<ActionButton onClick={setDate} title={`Set publish date`} />
|
||||
<ActionButton onClick={setLastMod} title={`Set modified date`} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -7,20 +7,28 @@ import { VsCheckbox } from './VscodeComponents';
|
||||
|
||||
export interface IGlobalSettingsProps {
|
||||
settings: PanelSettings | undefined;
|
||||
isBase?: boolean;
|
||||
}
|
||||
|
||||
export const GlobalSettings: React.FunctionComponent<IGlobalSettingsProps> = ({settings}: React.PropsWithChildren<IGlobalSettingsProps>) => {
|
||||
const { modifiedDateUpdate } = settings || {};
|
||||
export const GlobalSettings: React.FunctionComponent<IGlobalSettingsProps> = ({settings, isBase}: React.PropsWithChildren<IGlobalSettingsProps>) => {
|
||||
const { modifiedDateUpdate, fmHighlighting } = settings || {};
|
||||
|
||||
const onCheck = () => {
|
||||
const onDateCheck = () => {
|
||||
MessageHelper.sendMessage(CommandToCode.updateModifiedUpdating, !modifiedDateUpdate);
|
||||
};
|
||||
|
||||
const onHighlightCheck = () => {
|
||||
MessageHelper.sendMessage(CommandToCode.updateFmHighlight, !fmHighlighting);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Collapsible title="Global settings">
|
||||
<Collapsible id={`${isBase ? "base_" : ""}settings`} title="Global settings">
|
||||
<div className={`base__actions`}>
|
||||
<VsCheckbox label="Auto-update modified date" checked={modifiedDateUpdate} onClick={onCheck} />
|
||||
<VsCheckbox label="Auto-update modified date" checked={modifiedDateUpdate} onClick={onDateCheck} />
|
||||
</div>
|
||||
<div className={`base__actions`}>
|
||||
<VsCheckbox label="Highlight Front Matter" checked={fmHighlighting} onClick={onHighlightCheck} />
|
||||
</div>
|
||||
</Collapsible>
|
||||
</>
|
||||
|
||||
9
src/viewpanel/components/Icons/WritingIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IWritingIconProps {}
|
||||
|
||||
export const WritingIcon: React.FunctionComponent<IWritingIconProps> = (props: React.PropsWithChildren<IWritingIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M7.223 10.933c.326.192.699.29 1.077.282a2.159 2.159 0 0 0 1.754-.842 3.291 3.291 0 0 0 .654-2.113 2.886 2.886 0 0 0-.576-1.877 1.99 1.99 0 0 0-1.634-.733 2.294 2.294 0 0 0-1.523.567V3.475h-.991V11.1h.995v-.344c.076.066.158.125.244.177zM7.85 6.7c.186-.079.388-.113.59-.1a1.08 1.08 0 0 1 .896.428c.257.363.382.802.357 1.245a2.485 2.485 0 0 1-.4 1.484 1.133 1.133 0 0 1-.96.508 1.224 1.224 0 0 1-.976-.417A1.522 1.522 0 0 1 6.975 8.8v-.6a1.722 1.722 0 0 1 .393-1.145c.13-.154.296-.276.482-.355zM3.289 5.675a3.03 3.03 0 0 0-.937.162 2.59 2.59 0 0 0-.8.4l-.1.077v1.2l.423-.359a2.1 2.1 0 0 1 1.366-.572.758.758 0 0 1 .661.282c.15.232.23.503.231.779L2.9 7.825a2.6 2.6 0 0 0-1.378.575 1.65 1.65 0 0 0-.022 2.336 1.737 1.737 0 0 0 1.253.454 1.96 1.96 0 0 0 1.107-.332c.102-.068.197-.145.286-.229v.444h.941V7.715a2.193 2.193 0 0 0-.469-1.5 1.687 1.687 0 0 0-1.329-.54zm.857 3.041c.02.418-.12.829-.391 1.148a1.221 1.221 0 0 1-.955.422.832.832 0 0 1-.608-.2.833.833 0 0 1 0-1.091c.281-.174.6-.277.93-.3l1.02-.148.004.169zm8.313 2.317c.307.13.64.193.973.182.495.012.983-.114 1.41-.365l.123-.075.013-.007V9.615l-.446.32c-.316.224-.696.34-1.084.329A1.3 1.3 0 0 1 12.4 9.8a1.975 1.975 0 0 1-.4-1.312 2.01 2.01 0 0 1 .453-1.381A1.432 1.432 0 0 1 13.6 6.6a1.8 1.8 0 0 1 .971.279l.43.265V5.97l-.17-.073a2.9 2.9 0 0 0-1.17-.247 2.52 2.52 0 0 0-1.929.817 2.9 2.9 0 0 0-.747 2.049c-.028.707.21 1.4.67 1.939.222.249.497.446.804.578z"/></svg>
|
||||
);
|
||||
};
|
||||
15
src/viewpanel/components/OtherActionButton.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IOtherActionButtonProps {
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
onClick: (e: React.SyntheticEvent<HTMLButtonElement>) => void;
|
||||
}
|
||||
|
||||
export const OtherActionButton: React.FunctionComponent<IOtherActionButtonProps> = ({ className, disabled, onClick, children}: React.PropsWithChildren<IOtherActionButtonProps>) => {
|
||||
return (
|
||||
<div className={`ext_link_block`}>
|
||||
<button onClick={onClick} className={className || ""} disabled={disabled}>{children}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { PanelSettings } from '../../models';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { Collapsible } from './Collapsible';
|
||||
@@ -7,12 +8,16 @@ import { FileIcon } from './Icons/FileIcon';
|
||||
import { FolderOpenedIcon } from './Icons/FolderOpenedIcon';
|
||||
import { SettingsIcon } from './Icons/SettingsIcon';
|
||||
import { TemplateIcon } from './Icons/TemplateIcon';
|
||||
import { WritingIcon } from './Icons/WritingIcon';
|
||||
import { OtherActionButton } from './OtherActionButton';
|
||||
|
||||
export interface IOtherActionsProps {
|
||||
isFile: boolean;
|
||||
settings: PanelSettings | undefined;
|
||||
isBase?: boolean;
|
||||
}
|
||||
|
||||
export const OtherActions: React.FunctionComponent<IOtherActionsProps> = ({isFile}: React.PropsWithChildren<IOtherActionsProps>) => {
|
||||
export const OtherActions: React.FunctionComponent<IOtherActionsProps> = ({isFile, settings, isBase}: React.PropsWithChildren<IOtherActionsProps>) => {
|
||||
|
||||
const openSettings = () => {
|
||||
MessageHelper.sendMessage(CommandToCode.openSettings);
|
||||
@@ -30,27 +35,25 @@ export const OtherActions: React.FunctionComponent<IOtherActionsProps> = ({isFil
|
||||
MessageHelper.sendMessage(CommandToCode.createTemplate);
|
||||
};
|
||||
|
||||
const toggleWritingSettings = () => {
|
||||
MessageHelper.sendMessage(CommandToCode.toggleWritingSettings);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Collapsible title="Other actions" className={`other_actions`}>
|
||||
<div className="ext_link_block">
|
||||
<button onClick={createAsTemplate} disabled={!isFile}><TemplateIcon /> Create as template</button>
|
||||
</div>
|
||||
<Collapsible id={`${isBase ? "base_" : ""}other_actions`} title="Other actions" className={`other_actions`}>
|
||||
<OtherActionButton className={settings?.writingSettingsEnabled ? "active" : ""} onClick={toggleWritingSettings} disabled={typeof settings?.writingSettingsEnabled === "undefined"}><WritingIcon /> <span>{settings?.writingSettingsEnabled ? "Writing settings enabled" : "Enable writing settings"}</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={createAsTemplate} disabled={!isFile}><TemplateIcon /> <span>Create as template</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={openSettings}><SettingsIcon /> <span>Open settings</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={openFile} disabled={!isFile}><FileIcon /> <span>Reveal file in folder</span></OtherActionButton>
|
||||
|
||||
<OtherActionButton onClick={openProject}><FolderOpenedIcon /> <span>Reveal project folder</span></OtherActionButton>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openSettings}><SettingsIcon /> Open settings</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openFile} disabled={!isFile}><FileIcon /> Reveal file in folder</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openProject}><FolderOpenedIcon /> Reveal project folder</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<a href="https://github.com/estruyf/vscode-front-matter/issues" title="Open an issue on GitHub"><BugIcon /> Report an issue</a>
|
||||
<a href="https://github.com/estruyf/vscode-front-matter/issues" title="Open an issue on GitHub"><BugIcon /> <span>Report an issue</span></a>
|
||||
</div>
|
||||
</Collapsible>
|
||||
</>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface IPublishActionProps {
|
||||
draft: boolean;
|
||||
@@ -16,8 +17,6 @@ export const PublishAction: React.FunctionComponent<IPublishActionProps> = (prop
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={publish} className={`${draft ? "" : "secondary"}`}>{draft ? "Publish" : "Revert to draft"}</button>
|
||||
</div>
|
||||
<ActionButton onClick={publish} className={`${draft ? "" : "secondary"}`} title={draft ? "Publish" : "Revert to draft"} />
|
||||
);
|
||||
};
|
||||
@@ -88,7 +88,7 @@ export const SeoStatus: React.FunctionComponent<ISeoStatusProps> = (props: React
|
||||
}, [title, data[descriptionField], data?.articleDetails?.wordCount]);
|
||||
|
||||
return (
|
||||
<Collapsible title="SEO Status" sendUpdate={(value) => setIsOpen(value)}>
|
||||
<Collapsible id={`seo`} title="SEO Status" sendUpdate={(value) => setIsOpen(value)}>
|
||||
{ renderContent() }
|
||||
</Collapsible>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { SlugHelper } from '../../helpers/SlugHelper';
|
||||
import { Slug } from '../../models/PanelSettings';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import { ActionButton } from './ActionButton';
|
||||
|
||||
export interface ISlugActionProps {
|
||||
value: string;
|
||||
@@ -21,8 +22,6 @@ export const SlugAction: React.FunctionComponent<ISlugActionProps> = (props: Rea
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`article__action`}>
|
||||
<button onClick={optimize} disabled={crntValue === slug}>Optimize slug</button>
|
||||
</div>
|
||||
<ActionButton onClick={optimize} disabled={crntValue === slug} title={`Optimize slug`} />
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Template } from './../commands/Template';
|
||||
import { SETTING_AUTO_UPDATE_DATE, SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME } from './../constants/settings';
|
||||
import { SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, SETTING_AUTO_UPDATE_DATE, SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME } from './../constants/settings';
|
||||
import * as os from 'os';
|
||||
import { PanelSettings, CustomScript } from './../models/PanelSettings';
|
||||
import { CancellationToken, Disposable, Uri, Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext, window, workspace, commands, env as vscodeEnv } from "vscode";
|
||||
@@ -152,6 +152,15 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
case CommandToCode.updateModifiedUpdating:
|
||||
this.updateModifiedUpdating(msg.data || false);
|
||||
break;
|
||||
case CommandToCode.toggleWritingSettings:
|
||||
this.toggleWritingSettings();
|
||||
break;
|
||||
case CommandToCode.updateFmHighlight:
|
||||
this.updateFmHighlight((msg.data !== null && msg.data !== undefined) ? msg.data : false);
|
||||
break;
|
||||
case CommandToCode.toggleCenterMode:
|
||||
await commands.executeCommand(`workbench.action.toggleCenteredLayout`);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -201,6 +210,13 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger all sections to close
|
||||
*/
|
||||
public collapseAll() {
|
||||
this.postWebviewMessage({ command: Command.closeSections });
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a custom script
|
||||
* @param msg
|
||||
@@ -269,7 +285,9 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
scripts: config.get(SETTING_CUSTOM_SCRIPTS),
|
||||
isInitialized: await Template.isInitialized(),
|
||||
contentInfo: await Folders.getInfo() || null,
|
||||
modifiedDateUpdate: config.get(SETTING_AUTO_UPDATE_DATE) || false
|
||||
modifiedDateUpdate: config.get(SETTING_AUTO_UPDATE_DATE) || false,
|
||||
writingSettingsEnabled: this.isWritingSettingsEnabled() || false,
|
||||
fmHighlighting: config.get(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT),
|
||||
} as PanelSettings
|
||||
});
|
||||
}
|
||||
@@ -383,6 +401,57 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the writing settings
|
||||
*/
|
||||
private async toggleWritingSettings() {
|
||||
const config = workspace.getConfiguration("", { languageId: "markdown" });
|
||||
const enabled = this.isWritingSettingsEnabled();
|
||||
|
||||
await config.update("editor.fontSize", enabled ? undefined : 14, false, true);
|
||||
await config.update("editor.lineHeight", enabled ? undefined : 26, false, true);
|
||||
await config.update("editor.wordWrap", enabled ? undefined : "wordWrapColumn", false, true);
|
||||
await config.update("editor.wordWrapColumn", enabled ? undefined : 64, false, true);
|
||||
await config.update("editor.lineNumbers", enabled ? undefined : "off", false, true);
|
||||
await config.update("editor.quickSuggestions", enabled ? undefined : false, false, true);
|
||||
await config.update("editor.minimap.enabled", enabled ? undefined : false, false, true);
|
||||
|
||||
this.getSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the writing settings are enabled
|
||||
*/
|
||||
private isWritingSettingsEnabled() {
|
||||
const config = workspace.getConfiguration("", { languageId: "markdown" });
|
||||
|
||||
const fontSize = config.get("editor.fontSize");
|
||||
const lineHeight = config.get("editor.lineHeight");
|
||||
const wordWrap = config.get("editor.wordWrap");
|
||||
const wordWrapColumn = config.get("editor.wordWrapColumn");
|
||||
const lineNumbers = config.get("editor.lineNumbers");
|
||||
const quickSuggestions = config.get<boolean>("editor.quickSuggestions");
|
||||
|
||||
return fontSize && lineHeight && wordWrap && wordWrapColumn && lineNumbers && quickSuggestions !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the Front Matter highlighting
|
||||
*/
|
||||
private async updateFmHighlight(autoUpdate: boolean) {
|
||||
const config = workspace.getConfiguration(CONFIG_KEY);
|
||||
await config.update(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, autoUpdate);
|
||||
this.getSettings();
|
||||
|
||||
if (ArticleHelper.isMarkdownFile()) {
|
||||
// To unset the decorations, we need to reload the whole document/instance
|
||||
commands.executeCommand(`workbench.action.reloadWindow`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the modified auto-update setting
|
||||
*/
|
||||
private async updateModifiedUpdating(autoUpdate: boolean) {
|
||||
const config = workspace.getConfiguration(CONFIG_KEY);
|
||||
await config.update(SETTING_AUTO_UPDATE_DATE, autoUpdate);
|
||||
@@ -397,7 +466,9 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
this.panel!.webview.postMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a unique nonce
|
||||
*/
|
||||
private getNonce() {
|
||||
let text = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||