From 94cac875450f577e5813eee4f65fb0719abba7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20James?= Date: Tue, 6 Feb 2024 01:22:50 +0100 Subject: [PATCH 1/7] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Add=20"Visible"=20prop?= =?UTF-8?q?erty=20to=20allow=20hiding=20the=20editor=20without=20destroyin?= =?UTF-8?q?g=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeMirror6/CodeMirror6Wrapper.razor | 1 + CodeMirror6/CodeMirror6Wrapper.razor.cs | 5 +++++ CodeMirror6/CodeMirror6WrapperInternal.razor | 4 ++-- CodeMirror6/CodeMirror6WrapperInternal.razor.cs | 6 ++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CodeMirror6/CodeMirror6Wrapper.razor b/CodeMirror6/CodeMirror6Wrapper.razor index 3b658636..4dc2a4bb 100644 --- a/CodeMirror6/CodeMirror6Wrapper.razor +++ b/CodeMirror6/CodeMirror6Wrapper.razor @@ -34,6 +34,7 @@ FileNameOrExtension="@FileNameOrExtension" HighlightWhitespace="@HighlightWhitespace" HighlightTrailingWhitespace="@HighlightTrailingWhitespace" + Visible="@Visible" /> diff --git a/CodeMirror6/CodeMirror6Wrapper.razor.cs b/CodeMirror6/CodeMirror6Wrapper.razor.cs index 094e190f..df14c68c 100644 --- a/CodeMirror6/CodeMirror6Wrapper.razor.cs +++ b/CodeMirror6/CodeMirror6Wrapper.razor.cs @@ -165,6 +165,11 @@ public partial class CodeMirror6Wrapper : ComponentBase /// [Parameter] public bool HighlightWhitespace { get; set; } /// + /// Whether the editor is visible + /// + /// + [Parameter] public bool Visible { get; set; } + /// /// Additional attributes to be applied to the container element /// /// diff --git a/CodeMirror6/CodeMirror6WrapperInternal.razor b/CodeMirror6/CodeMirror6WrapperInternal.razor index 53b4e71a..4ae0f0b7 100644 --- a/CodeMirror6/CodeMirror6WrapperInternal.razor +++ b/CodeMirror6/CodeMirror6WrapperInternal.razor @@ -5,7 +5,7 @@
@for (var i = 0; i < (Doc?.Split("\n").Length ?? 10); i++) { var randomWidth = new Random().Next(20, 80); @@ -14,7 +14,7 @@
} -
+
[Parameter] public bool HighlightWhitespace { get; set; } /// + /// Whether the editor is visible + /// + /// + [Parameter] public bool Visible { get; set; } + /// /// Additional attributes to be applied to the container element /// /// @@ -183,6 +188,7 @@ public partial class CodeMirror6WrapperInternal : ComponentBase, IAsyncDisposabl : AllowVerticalResize ? "vertical" : AllowHorizontalResize ? "horizontal" : "none"; + private string VisibleClass => Visible ? string.Empty : " d-none "; /// /// JavaScript interop instance From 39cca3e31e785507bcf0b0ccac422f6df18a6852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20James?= Date: Tue, 6 Feb 2024 09:07:06 +0100 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=90=9B=20Fix=20tabulating=20csv=20col?= =?UTF-8?q?umns=20skipped=20the=20last=20/=20first=20ones?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeMirror6/NodeLib/src/CmColumns.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CodeMirror6/NodeLib/src/CmColumns.ts b/CodeMirror6/NodeLib/src/CmColumns.ts index 2b571a05..d791ff0d 100644 --- a/CodeMirror6/NodeLib/src/CmColumns.ts +++ b/CodeMirror6/NodeLib/src/CmColumns.ts @@ -49,6 +49,11 @@ function getRelativeColumnOffset(text: string, separator: string, position: numb } else if (char === '\\') { escapeNext = true offset++ + } else if (char === '\n' && previous) { + previousColumnOffset = offset + offset++ + } else if (char === '\n' && i >= position) { + return offset } else if (char === separator && !inQuotes && previous) { previousColumnOffset = offset offset++ From 667ed2d8f551ad2da14a65f9c93b00a59c86b883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20James?= Date: Tue, 6 Feb 2024 16:27:05 +0100 Subject: [PATCH 3/7] =?UTF-8?q?=E2=9C=A8=20Disable=20initial=20setting=20o?= =?UTF-8?q?f=20line=20wrapping=20in=20csv=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeMirror6/NodeLib/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeMirror6/NodeLib/src/index.ts b/CodeMirror6/NodeLib/src/index.ts index a8a82c89..4b1bc5e6 100644 --- a/CodeMirror6/NodeLib/src/index.ts +++ b/CodeMirror6/NodeLib/src/index.ts @@ -99,7 +99,7 @@ export async function initCodeMirror( CMInstances[id].emojiReplacerCompartment.of(replaceEmojiExtension(initialConfig.replaceEmojiCodes)), lastOperationWasUndo, indentationMarkers(), - CMInstances[id].lineWrappingCompartment.of(initialConfig.lineWrapping ? EditorView.lineWrapping : []), + CMInstances[id].lineWrappingCompartment.of(initialConfig.lineWrapping && initialConfig.languageName !== "CSV" && initialConfig.languageName !== "TSV" ? EditorView.lineWrapping : []), CMInstances[id].unifiedMergeViewCompartment.of(initialConfig.mergeViewConfiguration ? unifiedMergeView(initialConfig.mergeViewConfiguration) : []), CMInstances[id].highlightTrailingWhitespaceCompartment.of(initialConfig.highlightTrailingWhitespace ? highlightTrailingWhitespace() : []), CMInstances[id].highlightWhitespaceCompartment.of(initialConfig.highlightWhitespace ? highlightWhitespace() : []), From 3e79dafb3e5f9dc61d512fd37ccd50a437516a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20James?= Date: Tue, 6 Feb 2024 16:39:25 +0100 Subject: [PATCH 4/7] =?UTF-8?q?=E2=9C=A8=20Add=20linting=20that=20checks?= =?UTF-8?q?=20csv=20column=20count=20relative=20to=20first=20line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeMirror6/NodeLib/src/CmColumns.ts | 30 ++++++++++++++++++++++++++++ CodeMirror6/NodeLib/src/CmLint.ts | 3 ++- CodeMirror6/NodeLib/src/index.ts | 15 +++++++++++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/CodeMirror6/NodeLib/src/CmColumns.ts b/CodeMirror6/NodeLib/src/CmColumns.ts index d791ff0d..1a6ad8e5 100644 --- a/CodeMirror6/NodeLib/src/CmColumns.ts +++ b/CodeMirror6/NodeLib/src/CmColumns.ts @@ -1,6 +1,7 @@ import { Decoration, ViewPlugin, EditorView, KeyBinding } from "@codemirror/view"; import { Extension, RangeSetBuilder, Transaction } from "@codemirror/state"; import { buildWidget } from "./lib/codemirror-kit"; +import { Diagnostic } from "@codemirror/lint"; function createColumnReplaceDecoration(content: string, from: number) { @@ -138,6 +139,35 @@ export const getColumnStylingKeymap = (separator: string): KeyBinding[] => [ }}, ] +export function getSeparator(languageName: string) { + if (languageName === "CSV") return ',' + if (languageName === "TSV") return '\t' + return null +} + +export async function columnLintSource(view: EditorView, separator: string): Promise { + try { + const code = view.state.doc.toString() + const data = parseCSV(code, separator) + const nbCols = data[0].length + const errors: Diagnostic[] = [] + for (let i = 1; i < data.length; i++) { + if (data[i].length !== nbCols && data[i].length !== 1) { + const message = `Expected ${nbCols} columns, found ${data[i].length}` + const from = view.state.doc.line(i + 1).from + const to = view.state.doc.line(i + 1).to + errors.push({ from, to, message, severity: 'error' }) + } + } + if (errors.length > 0) + console.log('Linter found:', errors) + return errors + } catch (error) { + console.error('Linter error:', error) + return + } +} + function moveCursor(view: EditorView, inc: number) { console.log("moveCursors") const { state } = view diff --git a/CodeMirror6/NodeLib/src/CmLint.ts b/CodeMirror6/NodeLib/src/CmLint.ts index 9c5d9454..6fa94631 100644 --- a/CodeMirror6/NodeLib/src/CmLint.ts +++ b/CodeMirror6/NodeLib/src/CmLint.ts @@ -9,7 +9,8 @@ export async function externalLintSource(view: EditorView, dotnetHelper: DotNet. try { const code = view.state.doc.toString() const errors: Diagnostic[] = await dotnetHelper.invokeMethodAsync("LintingRequestedFromJS", code) - console.log('Linter found:', errors) + if (errors.length > 0) + console.log('Linter found:', errors) return errors } catch (error) { console.error('Linter error:', error) diff --git a/CodeMirror6/NodeLib/src/index.ts b/CodeMirror6/NodeLib/src/index.ts index 4b1bc5e6..c57e67b2 100644 --- a/CodeMirror6/NodeLib/src/index.ts +++ b/CodeMirror6/NodeLib/src/index.ts @@ -58,7 +58,7 @@ import { DotNet } from "@microsoft/dotnet-js-interop" import { markdownTableExtension } from "./CmMarkdownTable" import { dynamicDiagramsExtension } from "./CmDiagrams" import { hideMarksExtension } from "./CmHideMarkdownMarks" -import { getColumnStylingKeymap, columnStylingPlugin } from "./CmColumns" +import { getColumnStylingKeymap, columnStylingPlugin, columnLintSource, getSeparator } from "./CmColumns" /** * Initialize a new CodeMirror instance @@ -105,7 +105,11 @@ export async function initCodeMirror( CMInstances[id].highlightWhitespaceCompartment.of(initialConfig.highlightWhitespace ? highlightWhitespace() : []), CMInstances[id].columnsStylingCompartment.of( initialConfig.languageName === "CSV" || initialConfig.languageName === "TSV" - ? [columnStylingPlugin(initialConfig.languageName === "CSV" ? ',' : '\t'), keymap.of(getColumnStylingKeymap(initialConfig.languageName === "CSV" ? ',' : '\t'))] + ? [ + columnStylingPlugin(getSeparator(initialConfig.languageName)), + keymap.of(getColumnStylingKeymap(getSeparator(initialConfig.languageName))), + linter(async view => columnLintSource(view, getSeparator(initialConfig.languageName))), + ] : [] ), @@ -304,6 +308,7 @@ export async function setLanguage(id: string, languageName: string, fileNameOrEx const customKeyMap = getLanguageKeyMaps(languageName, fileNameOrExtension) if (languageName !== "CSV" && languageName !== "TSV") customKeyMap.push(indentWithTab) + const separator = getSeparator(languageName) CMInstances[id].view.dispatch({ effects: [ @@ -313,7 +318,11 @@ export async function setLanguage(id: string, languageName: string, fileNameOrEx CMInstances[id].markdownStylingCompartment.reconfigure(autoFormatMarkdownExtensions(id, languageName === 'Markdown')), CMInstances[id].columnsStylingCompartment.reconfigure( languageName === "CSV" || languageName === "TSV" - ? [columnStylingPlugin(languageName === "CSV" ? ',' : '\t'), keymap.of(getColumnStylingKeymap(languageName === "CSV" ? ',' : '\t'))] + ? [ + columnStylingPlugin(separator), + keymap.of(getColumnStylingKeymap(separator)), + linter(async view => columnLintSource(view, separator)), + ] : [] ), ] From 6e878c135d693468b93bd0c64a4c568b272284c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20James?= Date: Tue, 6 Feb 2024 16:39:33 +0100 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=93=9D=20Update=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d2ace8b2..c801fc9c 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Visit the [live demo](https://gaelj.github.io/BlazorCodeMirror6/) to see the com - [x] support C# language - [x] update doc in dotnet either on text changes or on blur - [x] diff viewer +- [x] CSV mode: add column paddings for alignment, navigate columns with tab / shift-tab - [ ] search & replace toolbar button - [ ] toolbar with toolbar button template - [ ] support read-only paragraphs @@ -47,7 +48,6 @@ Visit the [live demo](https://gaelj.github.io/BlazorCodeMirror6/) to see the com - [ ] automatic translation - [ ] deleting a file link deletes the file from the server - [ ] button (visible when editor is hovered), to copy raw editor content to clipboard -- [ ] CSV mode ### Markdown specific From 55ab11f332820a12621d1f2cb7252becac383bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20James?= Date: Tue, 6 Feb 2024 16:48:18 +0100 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=93=9D=20Update=20changelog=20for=200?= =?UTF-8?q?.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 19 +++++++++++++++++++ NEW_CHANGELOG.md | 15 ++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4ed91fd..c1d672f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 0.3.2 - 2024-02-06 + +### ⚡️ Improve performance + +- Add "Visible" property to allow hiding the editor without destroying it + +### ✨ Introduce new features + +- Add linting that checks csv column count relative to first line +- Disable initial setting of line wrapping in csv mode + +### 🐛 Fix a bug + +- Fix tabulating csv columns skipped the last / first ones + +### 📝 Add or update documentation + +- Update README + ## 0.3.1 - 2024-02-06 ### 🐛 Fix a bug diff --git a/NEW_CHANGELOG.md b/NEW_CHANGELOG.md index 349f9f37..05361261 100644 --- a/NEW_CHANGELOG.md +++ b/NEW_CHANGELOG.md @@ -1,7 +1,16 @@ +### ⚡️ Improve performance + +- Add "Visible" property to allow hiding the editor without destroying it + +### ✨ Introduce new features + +- Add linting that checks csv column count relative to first line +- Disable initial setting of line wrapping in csv mode + ### 🐛 Fix a bug -- Fix shift-tab in csv not working on last cell +- Fix tabulating csv columns skipped the last / first ones -### 🥅 Catch errors +### 📝 Add or update documentation -- Silence errors when DOM elements are no longer available in Diagrams (SVG) and file upload (main div) +- Update README From 682b36319e1f5f2963f0545215f4b074b8d77241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20James?= Date: Tue, 6 Feb 2024 16:48:19 +0100 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=94=96=20Bump=20version=20to=200.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeMirror6/CodeMirror6.csproj | 2 +- Examples.BlazorServer/Examples.BlazorServer.csproj | 2 +- .../Examples.BlazorServerInteractive.csproj | 2 +- Examples.BlazorWasm/Examples.BlazorWasm.csproj | 2 +- Examples.Common/Examples.Common.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CodeMirror6/CodeMirror6.csproj b/CodeMirror6/CodeMirror6.csproj index 5c532505..3965b60b 100644 --- a/CodeMirror6/CodeMirror6.csproj +++ b/CodeMirror6/CodeMirror6.csproj @@ -9,7 +9,7 @@ GaelJ.BlazorCodeMirror6 true GaelJ.BlazorCodeMirror6 - 0.3.1 + 0.3.2 true snupkg true diff --git a/Examples.BlazorServer/Examples.BlazorServer.csproj b/Examples.BlazorServer/Examples.BlazorServer.csproj index d91094cd..2d69aa5a 100644 --- a/Examples.BlazorServer/Examples.BlazorServer.csproj +++ b/Examples.BlazorServer/Examples.BlazorServer.csproj @@ -4,7 +4,7 @@ enable false enable - 0.3.1 + 0.3.2 diff --git a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj index 88b0667f..3a0b5eac 100644 --- a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj +++ b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj @@ -4,7 +4,7 @@ enable enable false - 0.3.1 + 0.3.2 diff --git a/Examples.BlazorWasm/Examples.BlazorWasm.csproj b/Examples.BlazorWasm/Examples.BlazorWasm.csproj index 75357825..c6c863cf 100644 --- a/Examples.BlazorWasm/Examples.BlazorWasm.csproj +++ b/Examples.BlazorWasm/Examples.BlazorWasm.csproj @@ -4,7 +4,7 @@ enable enable false - 0.3.1 + 0.3.2 diff --git a/Examples.Common/Examples.Common.csproj b/Examples.Common/Examples.Common.csproj index 218498f0..10364307 100644 --- a/Examples.Common/Examples.Common.csproj +++ b/Examples.Common/Examples.Common.csproj @@ -5,7 +5,7 @@ enable enable false - 0.3.1 + 0.3.2