Compare commits

...

9 Commits

Author SHA1 Message Date
Elio Struyf
6395e471f0 2.5.1 2021-08-23 08:51:09 +02:00
Elio Struyf
59f0351b79 Fix typo 2021-08-23 08:50:59 +02:00
Elio Struyf
1b16fa69d0 Update docs 2021-08-21 10:23:54 +02:00
Elio Struyf
e8f67590bc Updated image 2021-08-19 14:22:22 +02:00
Elio Struyf
b34a8feb63 changelog update 2021-08-19 14:09:02 +02:00
Elio Struyf
fcbca1e48a Fix typo 2021-08-19 14:08:44 +02:00
Elio Struyf
4585790b45 updated changelog 2021-08-19 14:08:00 +02:00
Elio Struyf
445b64a2ec 2.5.0 2021-08-19 14:07:47 +02:00
Elio Struyf
5d18d09b72 #60 - site preview + refactoring 2021-08-19 13:34:15 +02:00
39 changed files with 545 additions and 55 deletions

View File

@@ -1,5 +1,14 @@
# Change Log
## [2.5.1] - 2020-08-23
- Fix typo in the `package.json` file for the preview command
## [2.5.0] - 2020-08-19
- Moved the center layout button to the other actions section
- [#60](https://github.com/estruyf/vscode-front-matter/issues/60): Added the ability to open a site preview in VS Code
## [2.4.1] - 2020-08-16
- Better editor highlighting functionality

View File

@@ -1,6 +1,6 @@
<h1 align="center">
<a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter">
<img alt="Front Matter" src="./assets/front-matter.png">
<img alt="Front Matter" src="./assets/frontmatter-128x128.png">
</a>
</h1>
@@ -24,12 +24,22 @@ This VSCode extension simplifies working with your markdown articles' front matt
The extension will automatically verify if your title and description are SEO compliant. If this would not be the case, it will give you a warning.
<p align="center">
<img src="./assets/v2.5.0/site-preview.png" alt="Site preview" style="display: inline-block" />
</p>
> If you see something missing in your article creation flow, please feel free to reach out.
**Version 2**
In version v2.0.0 we released the newly redesigned sidebar panel with improved SEO support. This extension makes it the only extension to manage your Markdown pages for your static sites in Visual Studio Code.
<p align="center" style="margin-top: 2rem;">
<a href="https://www.producthunt.com/posts/front-matter?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-front-matter" target="_blank">
<img src="https://api.producthunt.com/widgets/embed-image/v1/featured.png?post_id=309033&theme=dark" alt="Front Matter - Managing your static sites straight from within VS Code | Product Hunt" style="width: 250px; height: 40px;" />
</a>
</p>
<h2 id="table-of-contents">Table of Contents</h2>
<details open="open">
@@ -37,7 +47,8 @@ In version v2.0.0 we released the newly redesigned sidebar panel with improved S
<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="#site-preview">Site preview</a></li>
<li><a href="#custom-actions">Custom actions/scripts</a></li>
<li><a href="#creating-articles-from-templates">Create articles from templates</a></li>
<li><a href="#syntax-highlighting-for-hugo-shortcodes">Syntax highlighting for Hugo Shortcodes</a></li>
<li><a href="#available-commands">Available commands</a></li>
@@ -75,7 +86,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.4.0/baseview.png" alt="Base view" style="display: inline-block" />
<img src="./assets/v2.5.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.
@@ -85,7 +96,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.4.0/global-settings.png" alt="Global settings" style="display: inline-block" />
<img src="./assets/v2.5.0/global-settings.png" alt="Global settings" style="display: inline-block" />
</p>
**SEO Status**
@@ -97,9 +108,11 @@ 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.4.0/actions.png" alt="Actions" style="display: inline-block" />
<img src="./assets/v2.5.0/actions.png" alt="Actions" style="display: inline-block" />
</p>
> **Info**: To gain the `open preview` button to show up, you will need to first set the `local preview URL`. You can do this within the `Global Settings` section or by updating the `frontMatter.preview.host` setting.
**Metadata: Keywords, Tags, Categories**
<p align="center">
@@ -111,11 +124,23 @@ 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.4.0/other-actions.png" alt="Other actions" style="display: inline-block" />
<img src="./assets/v2.5.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.
## Site preview
The Markdown preview is not consistently delivering the same result as the one you will see on your site. The Front Matter extension provides you a way to show the site result. For this, you will first have to set the `frontMatter.preview.host` setting. You can perform it from the `Global Settings` section in the panel or in your `settings.json` file to set the setting.
For example, with Hugo, the local server spins up on `http://localhost:1313`. When you set this URL as the value of the `frontMatter.preview.host` setting. You can click on the `open preview` button and the site preview will be shown.
<p align="center">
<img src="./assets/v2.5.0/site-preview.png" alt="Site preview" style="display: inline-block" />
</p>
> **Important**: Be sure to spin up your local server. This is an action the extension currently doesn't do for you. If you want, you create yourself a custom action in order to start it.
## 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.
@@ -241,6 +266,10 @@ You can also specify a prefix and suffix, which can be added to the slug if you
> **Info**: At the moment, the extension only supports English stopwords.
**Front Matter: Preview article**
Opens the site preview for the current article. More information about it can be found in the [site preview](#site-preview) section.
### Usage
- Start by opening the command prompt:
@@ -404,12 +433,34 @@ Specify if you want to highlight the Front Matter in the Markdown file. Default:
}
```
### `frontMatter.preview.host`
Specify the host URL (example: http://localhost:1313) to be used when opening the preview.
```json
{
"frontMatter.preview.host": ""
}
```
### `frontMatter.preview.pathName`
Specify the path you want to add after the host and before your slug. This can be used for instance to include the year/month like: `yyyy/MM` (if not set via the slug). The date will be generated based on the article its date field value.
```json
{
"frontMatter.preview.pathName": ""
}
```
> **Important**: As the value will be formatted with the article's date, it will try to convert all characters you enter. In case you wan to skip some characters or all of them, you need to wrap that part between two single quotes. Example: `"'blog/'yyyy/MM"` will result in: `blog/2021/08`.
## Feedback / issues / ideas
Please submit them via creating an issue in the project repository: [issue list](https://github.com/estruyf/vscode-front-matter/issues).
<p align="center">
<a href="#">
<img src="https://estruyf-github.azurewebsites.net/api/VisitorHit?user=estruyf&repo=vscode-front-matter&countColor=%23F05450&labelColor=%230E131F" />
<a href="https://visitorbadge.io">
<img src="https://estruyf-github.azurewebsites.net/api/VisitorHit?user=estruyf&repo=vscode-front-matter&countColor=%23F05450&labelColor=%230E131F" height="25px" />
</a>
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 28 28" style="enable-background:new 0 0 28 28;" xml:space="preserve">
<style type="text/css">
.st0{enable-background:new ;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
.st3{fill:none;}
</style>
<g class="st0">
<path class="st1" d="M4,11.4H2.2V2.9h3.2v2H4v1.2h1.3V8H4V11.4z"/>
<path class="st1" d="M10.9,11.4H9l-0.9-3c0-0.1,0-0.1,0-0.2C8,8.1,8,8,7.9,7.8v0.6v3H6.1V2.9H8c0.8,0,1.4,0.2,1.9,0.6
c0.5,0.5,0.8,1.3,0.8,2.2c0,1-0.4,1.7-1.1,2.1L10.9,11.4z M8,6.8h0.1c0.2,0,0.4-0.1,0.5-0.3C8.7,6.3,8.8,6,8.8,5.7
c0-0.6-0.3-1-0.8-1l0,0V6.8z"/>
<path class="st1" d="M16.5,7.2c0,1.3-0.2,2.4-0.7,3.2c-0.5,0.8-1.1,1.2-1.8,1.2s-1.2-0.3-1.7-0.9c-0.6-0.8-0.9-2-0.9-3.5
s0.3-2.7,0.9-3.5c0.5-0.6,1-0.9,1.7-0.9c0.8,0,1.4,0.4,1.9,1.2C16.2,4.7,16.5,5.8,16.5,7.2z M14.6,7.2c0-1.5-0.2-2.3-0.7-2.3
c-0.2,0-0.4,0.2-0.5,0.6s-0.2,0.9-0.2,1.7c0,0.7,0.1,1.3,0.2,1.7c0.1,0.4,0.3,0.6,0.5,0.6s0.4-0.2,0.5-0.6
C14.5,8.4,14.6,7.9,14.6,7.2z"/>
<path class="st1" d="M17.2,11.4V2.9H19l0.9,3C20,6,20,6.2,20.1,6.5c0.1,0.2,0.1,0.5,0.2,0.8L20.5,8c-0.1-0.7-0.1-1.4-0.2-1.9
s-0.1-1-0.1-1.3V2.9H22v8.5h-1.7l-0.9-3.1c-0.1-0.3-0.2-0.6-0.3-0.9S19,6.8,18.9,6.6c0,0.6,0.1,1.1,0.1,1.6c0,0.4,0,0.8,0,1.2v2.2
h-1.8V11.4z"/>
<path class="st1" d="M25.3,11.4h-1.8V4.9h-1v-2h3.9v2h-1.1V11.4z"/>
</g>
<rect class="st2" width="28" height="28"/>
<g class="st0">
<path class="st1" d="M2.9,17h0.9l0.6,3c0.1,0.4,0.2,0.8,0.2,1.2c0.1,0.4,0.1,0.8,0.2,1.2c0-0.1,0-0.1,0-0.1v-0.1L5,21.3l0.1-0.8
L5.2,20l0.6-3h0.9l0.7,7.5h-1l-0.2-2.6c0-0.1,0-0.2,0-0.3s0-0.2,0-0.2v-1v-0.9l0,0c0,0,0,0,0-0.1v0.2c0,0.2,0,0.3-0.1,0.5
s0,0.2-0.1,0.3l-0.1,0.7v0.3l-0.6,3.3H4.5l-0.6-2.8c-0.1-0.4-0.2-0.8-0.2-1.1c-0.1-0.4-0.1-0.8-0.2-1.2l-0.3,5.2h-1L2.9,17z"/>
<path class="st1" d="M9.3,17h0.8l1.6,7.5h-1L10.4,23H8.9l-0.3,1.5h-1L9.3,17z M10.3,22.2L10,21c-0.1-0.8-0.3-1.7-0.4-2.6
c0,0.5-0.1,0.9-0.2,1.4c-0.1,0.5-0.2,1-0.3,1.5l-0.2,1L10.3,22.2L10.3,22.2z"/>
<path class="st1" d="M11.5,17h3.3v0.9h-1.1v6.7h-1v-6.7h-1.2V17z"/>
<path class="st1" d="M14.8,17h3.3v0.9H17v6.7h-1v-6.7h-1.2V17z"/>
<path class="st1" d="M18.7,17h2.7v0.9h-1.7v2.4h1.5v0.9h-1.5v2.6h1.7v0.9h-2.7V17z"/>
<path class="st1" d="M22.3,17h1.3c0.6,0,1,0.1,1.2,0.4c0.3,0.3,0.5,0.9,0.5,1.6c0,0.5-0.1,1-0.3,1.3c-0.2,0.3-0.4,0.5-0.8,0.6
l1.4,3.7h-1l-1.4-3.7v3.7h-1L22.3,17L22.3,17z M23.3,20.3c0.4,0,0.7-0.1,0.8-0.3c0.2-0.2,0.2-0.5,0.2-0.9c0-0.2,0-0.4-0.1-0.6
s-0.1-0.3-0.2-0.4s-0.2-0.2-0.3-0.2c-0.1,0-0.3-0.1-0.4-0.1h-0.2v2.5H23.3z"/>
</g>
<rect x="-33.5" y="14" class="st3" width="8.6" height="14"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 28 28" style="color:#ad0670" xml:space="preserve">
<style type="text/css">
.st1 {
fill: none;
stroke: #ad0670;
stroke-width: 2;
stroke-miterlimit: 10;
}
</style>
<g class="st0">
<path fill="currentcolor" d="M4,11.4H2.2V2.9h3.2v2H4v1.2h1.3V8H4V11.4z" />
<path fill="currentcolor" d="M10.9,11.4H9l-0.9-3c0-0.1,0-0.1,0-0.2C8,8.1,8,8,7.9,7.8l0,0.6v3H6.1V2.9H8c0.8,0,1.4,0.2,1.9,0.6
c0.5,0.5,0.8,1.3,0.8,2.2c0,1-0.4,1.7-1.1,2.1L10.9,11.4z M8,6.8h0.1c0.2,0,0.4-0.1,0.5-0.3C8.7,6.3,8.8,6,8.8,5.7
c0-0.6-0.3-1-0.8-1H8V6.8z" />
<path fill="currentcolor" d="M16.5,7.2c0,1.3-0.2,2.4-0.7,3.2c-0.5,0.8-1.1,1.2-1.8,1.2c-0.7,0-1.2-0.3-1.7-0.9c-0.6-0.8-0.9-2-0.9-3.5
c0-1.5,0.3-2.7,0.9-3.5c0.5-0.6,1-0.9,1.7-0.9c0.8,0,1.4,0.4,1.9,1.2C16.2,4.7,16.5,5.8,16.5,7.2z M14.6,7.2c0-1.5-0.2-2.3-0.7-2.3
c-0.2,0-0.4,0.2-0.5,0.6c-0.1,0.4-0.2,0.9-0.2,1.7c0,0.7,0.1,1.3,0.2,1.7c0.1,0.4,0.3,0.6,0.5,0.6c0.2,0,0.4-0.2,0.5-0.6
C14.5,8.4,14.6,7.9,14.6,7.2z" />
<path fill="currentcolor" d="M17.2,11.4V2.9H19l0.9,3C20,6,20,6.2,20.1,6.5c0.1,0.2,0.1,0.5,0.2,0.8L20.5,8c-0.1-0.7-0.1-1.4-0.2-1.9s-0.1-1-0.1-1.3
V2.9H22v8.5h-1.7l-0.9-3.1c-0.1-0.3-0.2-0.6-0.3-0.9s-0.1-0.6-0.2-0.8c0,0.6,0.1,1.1,0.1,1.6c0,0.4,0,0.8,0,1.2v2.2H17.2z" />
<path fill="currentcolor" d="M25.3,11.4h-1.8V4.9h-1v-2h3.9v2h-1.1V11.4z" />
</g>
<rect class="st1" width="28" height="28" />
<g class="st0">
<path fill="currentcolor" d="M2.9,17h0.9L4.4,20c0.1,0.4,0.2,0.8,0.2,1.2c0.1,0.4,0.1,0.8,0.2,1.2c0-0.1,0-0.1,0-0.1c0,0,0-0.1,0-0.1L5,21.3l0.1-0.8
L5.2,20l0.6-3h0.9l0.7,7.5h-1l-0.2-2.6c0-0.1,0-0.2,0-0.3s0-0.2,0-0.2l0-1l0-0.9c0,0,0,0,0,0c0,0,0,0,0-0.1l0,0.2
c0,0.2,0,0.3-0.1,0.5s0,0.2-0.1,0.3l-0.1,0.7l0,0.3l-0.6,3.3H4.5l-0.6-2.8c-0.1-0.4-0.2-0.8-0.2-1.1c-0.1-0.4-0.1-0.8-0.2-1.2
l-0.3,5.2h-1L2.9,17z" />
<path fill="currentcolor" d="M9.3,17h0.8l1.6,7.5h-1L10.4,23H8.9l-0.3,1.5h-1L9.3,17z M10.3,22.2L10,21c-0.1-0.8-0.3-1.7-0.4-2.6c0,0.5-0.1,0.9-0.2,1.4
c-0.1,0.5-0.2,1-0.3,1.5l-0.2,1H10.3z" />
<path fill="currentcolor" d="M11.5,17h3.3v0.9h-1.1v6.7h-1v-6.7h-1.2V17z" />
<path fill="currentcolor" d="M14.8,17h3.3v0.9H17v6.7h-1v-6.7h-1.2V17z" />
<path fill="currentcolor" d="M18.7,17h2.7v0.9h-1.7v2.4h1.5v0.9h-1.5v2.6h1.7v0.9h-2.7V17z" />
<path fill="currentcolor" d="M22.3,17h1.3c0.6,0,1,0.1,1.2,0.4c0.3,0.3,0.5,0.9,0.5,1.6c0,0.5-0.1,1-0.3,1.3c-0.2,0.3-0.4,0.5-0.8,0.6l1.4,3.7h-1
l-1.4-3.7v3.7h-1V17z M23.3,20.3c0.4,0,0.7-0.1,0.8-0.3c0.2-0.2,0.2-0.5,0.2-0.9c0-0.2,0-0.4-0.1-0.6s-0.1-0.3-0.2-0.4
s-0.2-0.2-0.3-0.2c-0.1,0-0.3-0.1-0.4-0.1h-0.2V20.3z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
assets/frontmatter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -268,6 +268,14 @@
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.base__action label {
display: block;
}
.base__action input {
width: 100% !important;
}
.seo__status__details ul > * + *,
.ext_settings > * + * {
--tw-space-y-reverse: 0;

BIN
assets/v2.5.0/actions.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
assets/v2.5.0/baseview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "vscode-front-matter",
"version": "2.4.1",
"version": "2.5.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -2,8 +2,8 @@
"name": "vscode-front-matter",
"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.4.1",
"icon": "assets/frontmatter-128x128.png",
"version": "2.5.1",
"preview": false,
"publisher": "eliostruyf",
"galleryBanner": {
@@ -58,6 +58,7 @@
"onCommand:frontMatter.createContent",
"onCommand:frontMatter.init",
"onCommand:frontMatter.collapseSections",
"onCommand:frontMatter.preview",
"onView:frontMatter.explorer"
],
"main": "./dist/extension",
@@ -110,6 +111,16 @@
"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.preview.host": {
"type": "string",
"default": "",
"markdownDescription": "Specify the host URL (example: http://localhost:1313) to be used when opening the preview."
},
"frontMatter.preview.pathName": {
"type": "string",
"default": "",
"markdownDescription": "Specify the path you want to add after the host and before your slug. This can be used for instance to include the year/month like: `yyyy/MM`. The date will be generated based on the article its date field value."
},
"frontMatter.taxonomy.dateField": {
"type": "string",
"default": "date",
@@ -283,6 +294,11 @@
"light": "assets/icons/close-light.svg",
"dark": "assets/icons/close-dark.svg"
}
},
{
"command": "frontMatter.preview",
"title": "Preview article",
"category": "Front matter"
}
],
"menus": {
@@ -312,6 +328,10 @@
"command": "frontMatter.createTemplate",
"when": "!frontMatterCanInit"
},
{
"command": "frontMatter.preview",
"when": "frontMatterCanOpenPreview"
},
{
"command": "frontMatter.collapseSections",
"when": "false"

View File

@@ -18,13 +18,13 @@ export class Article {
* @param type
*/
public static async insert(type: TaxonomyType) {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
const article = ArticleHelper.getFrontMatter(editor);
const article = Article.getCurrent();
if (!article) {
return;
}
@@ -101,7 +101,7 @@ export class Article {
* @param article
*/
public static updateDate(article: matter.GrayMatterFile<string>, forceCreate: boolean = false) {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const dateFormat = config.get(SETTING_DATE_FORMAT) as string;
const dateField = config.get(SETTING_DATE_FIELD) as string || "date";
const modField = config.get(SETTING_MODIFIED_FIELD) as string || "date";
@@ -116,7 +116,7 @@ export class Article {
* Sets the article lastmod date
*/
public static async setLastModifiedDate() {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
@@ -148,7 +148,7 @@ export class Article {
* Generate the slug based on the article title
*/
public static async generateSlug() {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const prefix = config.get(SETTING_SLUG_PREFIX) as string;
const suffix = config.get(SETTING_SLUG_SUFFIX) as string;
const updateFileName = config.get(SETTING_SLUG_UPDATE_FILE_NAME) as string;
@@ -231,7 +231,7 @@ export class Article {
const editor = vscode.window.activeTextEditor;
if (txtChanges.length > 0 && editor && ArticleHelper.isMarkdownFile()) {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const autoUpdate = config.get(SETTING_AUTO_UPDATE_DATE);
if (autoUpdate) {
@@ -251,6 +251,23 @@ export class Article {
}
}
/**
* Get the current article
*/
private static getCurrent(): matter.GrayMatterFile<string> | undefined {
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
const article = ArticleHelper.getFrontMatter(editor);
if (!article) {
return;
}
return article;
}
/**
* Update the article date and return it
* @param article

View File

@@ -6,6 +6,7 @@ import uniqBy = require("lodash.uniqby");
import { Template } from "./Template";
import { Notifications } from "../helpers/Notifications";
import { CONTEXT } from "../constants/context";
import { SettingsHelper } from "../helpers";
export class Folders {
@@ -151,7 +152,7 @@ export class Folders {
* @returns
*/
private static get() {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const folders: ContentFolder[] = config.get(SETTINGS_CONTENT_FOLDERS) as ContentFolder[];
return folders;
}
@@ -161,7 +162,7 @@ export class Folders {
* @param folders
*/
private static async update(folders: ContentFolder[]) {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
await config.update(SETTINGS_CONTENT_FOLDERS, folders);
}
}

137
src/commands/Preview.ts Normal file
View File

@@ -0,0 +1,137 @@
import { SETTING_PREVIEW_HOST, SETTING_PREVIEW_PATHNAME } from './../constants/settings';
import { ArticleHelper } from './../helpers/ArticleHelper';
import { join } from "path";
import { commands, env, Uri, ViewColumn, window } from "vscode";
import { SettingsHelper } from '../helpers';
import { PreviewSettings } from '../models';
import { format } from 'date-fns';
import { CONTEXT } from '../constants/context';
export class Preview {
/** 
* Init the preview
*/
public static async init() {
const settings = Preview.getSettings();
await commands.executeCommand('setContext', CONTEXT.canOpenPreview, !!settings.host);
}
/**
* Open the markdown preview in the editor
*/
public static async open(extensionPath: string) {
const settings = Preview.getSettings();
if (!settings.host) {
return;
}
const editor = window.activeTextEditor;
const article = editor ? ArticleHelper.getFrontMatter(editor) : null;
let slug = article?.data ? article.data.slug : "";
if (settings.pathname) {
const articleDate = ArticleHelper.getDate(article);
try {
slug = join(format(articleDate || new Date(), settings.pathname), slug);
} catch (error) {
slug = join(settings.pathname, slug);
}
}
// Create the preview webview
const webView = window.createWebviewPanel(
'frontMatterPreview',
'FrontMatter Preview',
{
viewColumn: ViewColumn.Beside,
preserveFocus: true
},
{
enableScripts: true
}
);
webView.iconPath = {
dark: Uri.file(join(extensionPath, 'assets/frontmatter-dark.svg')),
light: Uri.file(join(extensionPath, 'assets/frontmatter.svg'))
}
const localhostUrl = await env.asExternalUri(
Uri.parse(settings.host)
);
const cspSource = webView.webview.cspSource;
webView.webview.html = `<!DOCTYPE html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; frame-src ${localhostUrl} ${cspSource} http: https:; img-src ${localhostUrl} ${cspSource} http: https:; script-src ${localhostUrl} ${cspSource} 'unsafe-inline'; style-src ${localhostUrl} ${cspSource} 'self' 'unsafe-inline' http: https:;"
/>
<style>
html,body {
margin: 0;
padding: 0;
background: white;
height: 100%;
width: 100%;
}
body {
margin: 0;
padding: 0;
}
iframe {
width: 100%;
height: calc(100% - 30px);
border: 0;
margin-top: 30px;
}
.slug {
width: 100%;
position: fixed;
height: 30px;
display: flex;
align-items: center;
background-color: var(--vscode-editor-background);
border-bottom: 1px solid var(--vscode-focusBorder);
}
input {
color: var(--vscode-editor-foreground);
padding: 0.25rem 0.5rem;
background: none;
border: 0;
width: 100%;
}
</style>
</head>
<body>
<div class="slug">
<input type="text" value="${join(localhostUrl.toString(), slug)}" disabled />
</div>
<iframe src="${join(localhostUrl.toString(), slug)}" >
</body>
</html>`;
}
/**
* Retrieve all settings related to the preview command
*/
public static getSettings(): PreviewSettings {
const config = SettingsHelper.getConfig();
const host = config.get<string>(SETTING_PREVIEW_HOST);
const pathname = config.get<string>(SETTING_PREVIEW_PATHNAME);
return {
host,
pathname
};
}
}

View File

@@ -22,7 +22,7 @@ export class Settings {
});
if (newOption) {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const configSetting = type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES;
let options = config.get(configSetting) as string[];
if (!options) {
@@ -72,7 +72,7 @@ export class Settings {
* Export the tags/categories front matter to the user settings
*/
public static async export() {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
// Retrieve all the Markdown files
const allMdFiles = await FilesHelper.getMdFiles();
@@ -155,8 +155,6 @@ export class Settings {
* Remap a tag or category to a new one
*/
public static async remap() {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const taxType = await vscode.window.showQuickPick([
"Tag",
"Category"

View File

@@ -1,7 +1,6 @@
import { SETTING_SEO_DESCRIPTION_FIELD, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH } from './../constants/settings';
import * as vscode from 'vscode';
import { CONFIG_KEY } from '../constants';
import { ArticleHelper, SeoHelper } from '../helpers';
import { ArticleHelper, SeoHelper, SettingsHelper } from '../helpers';
import { ExplorerView } from '../webview/ExplorerView';
export class StatusListener {
@@ -38,7 +37,7 @@ export class StatusListener {
collection.clear();
// Retrieve the SEO config properties
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const titleLength = config.get(SETTING_SEO_TITLE_LENGTH) as number || -1;
const descLength = config.get(SETTING_SEO_DESCRIPTION_LENGTH) as number || -1;
const fieldName = config.get(SETTING_SEO_DESCRIPTION_FIELD) as string || "description";

View File

@@ -4,7 +4,7 @@ import * as fs from 'fs';
import { CONFIG_KEY, SETTING_TEMPLATES_FOLDER, SETTING_TEMPLATES_PREFIX } from '../constants';
import { format } from 'date-fns';
import sanitize from '../helpers/Sanitize';
import { ArticleHelper } from '../helpers';
import { ArticleHelper, SettingsHelper } from '../helpers';
import { Article } from '.';
import { Notifications } from '../helpers/Notifications';
import { CONTEXT } from '../constants/context';
@@ -93,7 +93,7 @@ export class Template {
* Create from a template
*/
public static async create(folderPath: string) {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const folder = config.get<string>(SETTING_TEMPLATES_FOLDER);
const prefix = config.get<string>(SETTING_TEMPLATES_PREFIX);
@@ -188,7 +188,7 @@ export class Template {
* Get the folder settings
*/
public static getSettings() {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const folder = config.get<string>(SETTING_TEMPLATES_FOLDER);
return folder;
}

View File

@@ -22,4 +22,5 @@ export const COMMAND_NAME = {
createContent: getCommandName("createContent"),
createTemplate: getCommandName("createTemplate"),
collapseSections: getCommandName("collapseSections"),
preview: getCommandName("preview"),
};

View File

@@ -2,5 +2,6 @@
export const CONTEXT = {
canInit: "frontMatterCanInit",
canOpenPreview: "frontMatterCanOpenPreview",
registeredFolders: 'frontMatter.registeredFolders'
};

View File

@@ -27,6 +27,9 @@ export const SETTING_TEMPLATES_PREFIX = "templates.prefix";
export const SETTING_PANEL_FREEFORM = "panel.freeform";
export const SETTING_PREVIEW_HOST = "preview.host";
export const SETTING_PREVIEW_PATHNAME = "preview.pathName";
export const SETTING_CUSTOM_SCRIPTS = "custom.scripts";
export const SETTING_AUTO_UPDATE_DATE = "content.autoUpdateDate";

View File

@@ -1,6 +1,7 @@
import * as vscode from 'vscode';
import { Article, Settings, StatusListener } from './commands';
import { Folders } from './commands/Folders';
import { Preview } from './commands/Preview';
import { Project } from './commands/Project';
import { Template } from './commands/Template';
import { COMMAND_NAME } from './constants/Extension';
@@ -16,7 +17,7 @@ let collection: vscode.DiagnosticCollection;
const mdSelector: vscode.DocumentSelector = { language: 'markdown', scheme: 'file' };
export async function activate({ subscriptions, extensionUri }: vscode.ExtensionContext) {
export async function activate({ subscriptions, extensionUri, extensionPath }: vscode.ExtensionContext) {
collection = vscode.languages.createDiagnosticCollection('frontMatter');
const explorerSidebar = ExplorerView.getInstance(extensionUri);
@@ -105,6 +106,7 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
// Things to do when configuration changes
vscode.workspace.onDidChangeConfiguration(() => {
Template.init();
Preview.init();
Folders.updateVsCodeCtx();
});
@@ -128,6 +130,10 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
// Listener for setting changes
subscriptions.push(vscode.workspace.onDidChangeConfiguration(MarkdownFoldingProvider.triggerHighlighting));
// Webview for preview
Preview.init();
subscriptions.push(vscode.commands.registerCommand('frontMatter.preview', () => Preview.open(extensionPath) ));
// Subscribe all commands
subscriptions.push(
insertTags,

View File

@@ -1,9 +1,11 @@
import * as vscode from 'vscode';
import * as matter from "gray-matter";
import * as fs from "fs";
import { CONFIG_KEY, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES } from '../constants';
import { CONFIG_KEY, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES } from '../constants';
import { DumpOptions } from 'js-yaml';
import { TomlEngine, getFmLanguage, getFormatOpts } from './TomlEngine';
import { SettingsHelper } from '.';
import { parse } from 'date-fns';
export class ArticleHelper {
@@ -54,7 +56,7 @@ export class ArticleHelper {
* @param article
*/
public static async update(editor: vscode.TextEditor, article: matter.GrayMatterFile<string>) {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const removeQuotes = config.get(SETTING_REMOVE_QUOTES) as string[];
let newMarkdown = this.stringifyFrontMatter(article.content, article.data);
@@ -80,7 +82,7 @@ export class ArticleHelper {
* @param data
*/
public static stringifyFrontMatter(content: string, data: any) {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const indentArray = config.get(SETTING_INDENT_ARRAY) as boolean;
const language = getFmLanguage();
@@ -104,4 +106,28 @@ export class ArticleHelper {
const editor = vscode.window.activeTextEditor;
return (editor && editor.document && (editor.document.languageId.toLowerCase() === "markdown" || editor.document.languageId.toLowerCase() === "mdx"));
}
/**
* Get date from front matter
*/
public static getDate(article: matter.GrayMatterFile<string> | null) {
if (!article) {
return;
}
const config = SettingsHelper.getConfig();
const dateFormat = config.get(SETTING_DATE_FORMAT) as string;
const dateField = config.get(SETTING_DATE_FIELD) as string || "date";
if (typeof article.data[dateField] !== "undefined") {
if (dateFormat && typeof dateFormat === "string") {
const date = parse(article.data[dateField], dateFormat, new Date());
return date;
} else {
const date = new Date(article.data[dateField]);
return date;
}
}
return;
}
}

View File

@@ -4,6 +4,10 @@ import { SETTING_TAXONOMY_TAGS, SETTING_TAXONOMY_CATEGORIES, CONFIG_KEY } from '
export class SettingsHelper {
public static getConfig(): vscode.WorkspaceConfiguration {
return vscode.workspace.getConfiguration(CONFIG_KEY);
}
/**
* Return the taxonomy settings
*

View File

@@ -1,9 +1,10 @@
import * as vscode from 'vscode';
import * as toml from '@iarna/toml';
import { CONFIG_KEY, SETTING_FRONTMATTER_TYPE } from '../constants';
import { SETTING_FRONTMATTER_TYPE } from '../constants';
import { SettingsHelper } from '.';
export const getFmLanguage = (): string => {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const language = config.get(SETTING_FRONTMATTER_TYPE) as string || "YAML";
return language.toLowerCase();
};

View File

@@ -11,6 +11,7 @@ export interface PanelSettings {
contentInfo: FolderInfo[] | null;
writingSettingsEnabled: boolean;
fmHighlighting: boolean;
preview: PreviewSettings;
}
export interface SEO {
@@ -34,4 +35,9 @@ export interface CustomScript {
title: string;
script: string;
nodeBin?: string;
}
export interface PreviewSettings {
host: string | undefined;
pathname: string | undefined;
}

View File

@@ -1,6 +1,7 @@
import { TextEditorDecorationType, workspace } from 'vscode';
import { TextEditorDecorationType } from 'vscode';
import { CancellationToken, FoldingContext, FoldingRange, FoldingRangeKind, FoldingRangeProvider, Range, TextDocument, window, Position } from 'vscode';
import { CONFIG_KEY, SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT } from '../constants';
import { SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT } from '../constants';
import { SettingsHelper } from '../helpers';
import { FrontMatterDecorationProvider } from './FrontMatterDecorationProvider';
export class MarkdownFoldingProvider implements FoldingRangeProvider {
@@ -43,7 +44,7 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider {
}
public static triggerHighlighting() {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const fmHighlight = config.get<boolean>(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT);
if (MarkdownFoldingProvider.start !== null && MarkdownFoldingProvider.end !== null && MarkdownFoldingProvider.endLine !== null) {

View File

@@ -20,4 +20,6 @@ export enum CommandToCode {
createTemplate = "create-template",
toggleCenterMode = "toggle-center-mode",
toggleWritingSettings = "toggle-writing-settings",
openPreview = "open-preview",
updatePreviewUrl = "update-preview-url",
}

View File

@@ -1,11 +1,9 @@
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';
import { Preview } from './Preview';
import { PublishAction } from './PublishAction';
import { SlugAction } from './SlugAction';
@@ -25,10 +23,10 @@ export const Actions: React.FunctionComponent<IActionsProps> = (props: React.Pro
<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} /> }
{ settings?.preview?.host && <Preview slug={metadata.slug} /> }
<DateAction />
{ metadata && typeof metadata.draft !== undefined && <PublishAction draft={metadata.draft} />}

View File

@@ -2,8 +2,9 @@ import * as React from 'react';
import { PanelSettings } from '../../models';
import { CommandToCode } from '../CommandToCode';
import { MessageHelper } from '../helper/MessageHelper';
import { useDebounce } from '../hooks/useDebounce';
import { Collapsible } from './Collapsible';
import { VsCheckbox } from './VscodeComponents';
import { VsCheckbox, VsLabel } from './VscodeComponents';
export interface IGlobalSettingsProps {
settings: PanelSettings | undefined;
@@ -12,6 +13,9 @@ export interface IGlobalSettingsProps {
export const GlobalSettings: React.FunctionComponent<IGlobalSettingsProps> = ({settings, isBase}: React.PropsWithChildren<IGlobalSettingsProps>) => {
const { modifiedDateUpdate, fmHighlighting } = settings || {};
const [ previewUrl, setPreviewUrl ] = React.useState<string>("");
const [ isDirty, setIsDirty ] = React.useState<boolean>(false);
const debouncePreviewUrl = useDebounce(previewUrl, 1000);
const onDateCheck = () => {
MessageHelper.sendMessage(CommandToCode.updateModifiedUpdating, !modifiedDateUpdate);
@@ -21,15 +25,44 @@ export const GlobalSettings: React.FunctionComponent<IGlobalSettingsProps> = ({s
MessageHelper.sendMessage(CommandToCode.updateFmHighlight, !fmHighlighting);
};
const previewChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setIsDirty(true);
setPreviewUrl(e.currentTarget.value);
};
React.useEffect(() => {
if (settings?.preview.host) {
setPreviewUrl(settings.preview.host);
}
}, [settings?.preview.host]);
React.useEffect(() => {
if (isDirty) {
console.log(debouncePreviewUrl);
setIsDirty(false);
MessageHelper.sendMessage(CommandToCode.updatePreviewUrl, debouncePreviewUrl);
}
}, [debouncePreviewUrl]);
return (
<>
<Collapsible id={`${isBase ? "base_" : ""}settings`} title="Global settings">
<div className={`base__actions`}>
<Collapsible id={`${isBase ? "base_" : ""}settings`} className={`base__actions`} title="Global settings">
<div className={`base__action`}>
<VsLabel>Modified date</VsLabel>
<VsCheckbox label="Auto-update modified date" checked={modifiedDateUpdate} onClick={onDateCheck} />
</div>
<div className={`base__actions`}>
<div className={`base__action`}>
<VsLabel>Front Matter highlight</VsLabel>
<VsCheckbox label="Highlight Front Matter" checked={fmHighlighting} onClick={onHighlightCheck} />
</div>
<div className={`base__action`}>
<VsLabel>Local preview</VsLabel>
<input
type={`text`}
placeholder="Example: http://localhost:1313"
value={previewUrl}
onChange={previewChange} />
</div>
</Collapsible>
</>
);

View File

@@ -0,0 +1,12 @@
import * as React from 'react';
export interface ICenterIconProps {}
export const CenterIcon: React.FunctionComponent<ICenterIconProps> = (props: React.PropsWithChildren<ICenterIconProps>) => {
return (
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<rect x="1.2" y="0.6" stroke="currentcolor" strokeMiterlimit="10" width="13.6" height="14.8"/>
<path stroke="currentcolor" d="M2.6,10V9h10.8v1H2.6z M2.6,6h10.8v1H2.6V6z M13.4,3v1H2.6V3H13.4z M2.6,12v1h10.8v-1H2.6z"/>
</svg>
);
};

View File

@@ -4,6 +4,7 @@ import { CommandToCode } from '../CommandToCode';
import { MessageHelper } from '../helper/MessageHelper';
import { Collapsible } from './Collapsible';
import { BugIcon } from './Icons/BugIcon';
import { CenterIcon } from './Icons/CenterIcon';
import { FileIcon } from './Icons/FileIcon';
import { FolderOpenedIcon } from './Icons/FolderOpenedIcon';
import { SettingsIcon } from './Icons/SettingsIcon';
@@ -44,6 +45,10 @@ export const OtherActions: React.FunctionComponent<IOtherActionsProps> = ({isFil
<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={() => MessageHelper.sendMessage(CommandToCode.toggleCenterMode)}>
<CenterIcon /> <span>Toggle center mode</span>
</OtherActionButton>
<OtherActionButton onClick={createAsTemplate} disabled={!isFile}><TemplateIcon /> <span>Create as template</span></OtherActionButton>
<OtherActionButton onClick={openSettings}><SettingsIcon /> <span>Open settings</span></OtherActionButton>

View File

@@ -0,0 +1,23 @@
import * as React from 'react';
import { CommandToCode } from '../CommandToCode';
import { MessageHelper } from '../helper/MessageHelper';
import { ActionButton } from './ActionButton';
export interface IPreviewProps {
slug: string;
}
export const Preview: React.FunctionComponent<IPreviewProps> = ({slug}: React.PropsWithChildren<IPreviewProps>) => {
const open = () => {
MessageHelper.sendMessage(CommandToCode.openPreview);
};
if (!slug) {
return null;
}
return (
<ActionButton onClick={open} title={`Open preview`} />
);
};

View File

@@ -7,4 +7,5 @@ export const VsTableBody = wrapWc(`vscode-table-body`);
export const VsTableRow = wrapWc(`vscode-table-row`);
export const VsTableCell = wrapWc(`vscode-table-cell`);
export const VsCollapsible = wrapWc(`vscode-collapsible`);
export const VsCheckbox = wrapWc(`vscode-checkbox`);
export const VsCheckbox = wrapWc(`vscode-checkbox`);
export const VsLabel = wrapWc(`vscode-label`);

View File

@@ -0,0 +1,25 @@
import { useEffect, useState } from "react";
export function useDebounce(value: string, delay: number) {
// State and setters for debounced value
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(
() => {
// Update debounced value after delay
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// Cancel the timeout if value changes (also on delay change or unmount)
// This is how we prevent debounced value from updating if value is changed ...
// .. within the delay period. Timeout gets cleared and restarted.
return () => {
clearTimeout(handler);
};
},
[value, delay] // Only re-call effect if value or delay changes
);
return debouncedValue;
}

View File

@@ -11,6 +11,7 @@ import '@bendera/vscode-webview-elements/dist/vscode-table-row';
import '@bendera/vscode-webview-elements/dist/vscode-table-cell';
import '@bendera/vscode-webview-elements/dist/vscode-collapsible';
import '@bendera/vscode-webview-elements/dist/vscode-checkbox';
import '@bendera/vscode-webview-elements/dist/vscode-label';
declare const acquireVsCodeApi: <T = unknown>() => {
getState: () => T;

View File

@@ -1,9 +1,9 @@
import { Template } from './../commands/Template';
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 { 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, SETTING_PREVIEW_HOST } 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";
import { CONFIG_KEY, SETTING_PANEL_FREEFORM, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_TAXONOMY_CATEGORIES, SETTING_TAXONOMY_TAGS } from "../constants";
import { SETTING_PANEL_FREEFORM, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_TAXONOMY_CATEGORIES, SETTING_TAXONOMY_TAGS } from "../constants";
import { ArticleHelper, SettingsHelper } from "../helpers";
import { Command } from "../viewpanel/Command";
import { CommandToCode } from '../viewpanel/CommandToCode';
@@ -17,6 +17,7 @@ import { Content } from 'mdast';
import { Notifications } from '../helpers/Notifications';
import { COMMAND_NAME } from '../constants/Extension';
import { Folders } from '../commands/Folders';
import { Preview } from '../commands/Preview';
export class ExplorerView implements WebviewViewProvider, Disposable {
@@ -161,6 +162,12 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
case CommandToCode.toggleCenterMode:
await commands.executeCommand(`workbench.action.toggleCenteredLayout`);
break;
case CommandToCode.openPreview:
await commands.executeCommand(COMMAND_NAME.preview);
break;
case CommandToCode.updatePreviewUrl:
this.updatePreviewUrl(msg.data || "");
break;
}
});
@@ -222,7 +229,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
* @param msg
*/
private runCustomScript(msg: { command: string, data: any}) {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
const scripts: CustomScript[] | undefined = config.get(SETTING_CUSTOM_SCRIPTS);
if (msg?.data?.title && msg?.data?.script && scripts) {
@@ -263,7 +270,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
* Retrieve the extension settings
*/
private async getSettings() {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
this.postWebviewMessage({
command: Command.settings,
@@ -288,6 +295,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
modifiedDateUpdate: config.get(SETTING_AUTO_UPDATE_DATE) || false,
writingSettingsEnabled: this.isWritingSettingsEnabled() || false,
fmHighlighting: config.get(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT),
preview: Preview.getSettings(),
} as PanelSettings
});
}
@@ -331,7 +339,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
*/
private async addTags(tagType: TagType, value: string) {
if (value) {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
let options = tagType === TagType.tags ? config.get<string[]>(SETTING_TAXONOMY_TAGS) : config.get<string[]>(SETTING_TAXONOMY_CATEGORIES);
if (!options) {
@@ -435,11 +443,20 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
return fontSize && lineHeight && wordWrap && wordWrapColumn && lineNumbers && quickSuggestions !== undefined;
}
/**
* Update the preview URL
*/
private async updatePreviewUrl(previewUrl: string) {
const config = SettingsHelper.getConfig();
await config.update(SETTING_PREVIEW_HOST, previewUrl);
this.getSettings();
}
/**
* Toggle the Front Matter highlighting
*/
private async updateFmHighlight(autoUpdate: boolean) {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
await config.update(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, autoUpdate);
this.getSettings();
}
@@ -448,7 +465,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
* Toggle the modified auto-update setting
*/
private async updateModifiedUpdating(autoUpdate: boolean) {
const config = workspace.getConfiguration(CONFIG_KEY);
const config = SettingsHelper.getConfig();
await config.update(SETTING_AUTO_UPDATE_DATE, autoUpdate);
this.getSettings();
}