/// APL
@@ -607,7 +608,7 @@ public enum CodeMirrorLanguage
///
/// Lezer
///
- Lezer,
+ [JsonStringValue("Lezer")] Lezer,
///
/// Markdown
@@ -617,7 +618,7 @@ public enum CodeMirrorLanguage
///
/// Mermaid
///
- Mermaid,
+ [JsonStringValue("Mermaid")] Mermaid,
///
/// Python
@@ -734,3 +735,17 @@ public enum CodeMirrorLanguage
///
[JsonStringValue("YAML")] Yaml,
}
+
+///
+/// Extension methods for the enum
+///
+public static class CodeMirrorLanguageExtensions
+{
+ ///
+ /// Returns the display name of the language
+ ///
+ ///
+ ///
+ public static string DisplayName(this CodeMirrorLanguage language) =>
+ language.GetType().GetField(language.ToString())?.GetCustomAttribute()?.Value ?? language.ToString();
+}
diff --git a/CodeMirror6/Models/CodeMirrorSetup.cs b/CodeMirror6/Models/CodeMirrorSetup.cs
index aa84bc3c..94a8fadd 100644
--- a/CodeMirror6/Models/CodeMirrorSetup.cs
+++ b/CodeMirror6/Models/CodeMirrorSetup.cs
@@ -129,4 +129,9 @@ public CodeMirrorSetup()
/// Bind value mode of the text area
///
[JsonPropertyName("bindValueMode")] public DocumentBindMode BindMode { get; init; } = DocumentBindMode.OnLostFocus;
+
+ ///
+ /// Can the user scroll past the end of the document
+ ///
+ [JsonPropertyName("scrollPastEnd")] public bool ScrollPastEnd { get; init; } = false;
}
diff --git a/CodeMirror6/NodeLib/src/CmConfiguration.ts b/CodeMirror6/NodeLib/src/CmConfiguration.ts
index de0c4149..1e0360c7 100644
--- a/CodeMirror6/NodeLib/src/CmConfiguration.ts
+++ b/CodeMirror6/NodeLib/src/CmConfiguration.ts
@@ -19,6 +19,8 @@ export class CmConfiguration {
public lineWrapping: boolean
public lintingEnabled: boolean
public mergeViewConfiguration: UnifiedMergeConfig | null
+ public highlightTrailingWhitespace: boolean
+ public highlightWhitespace: boolean
}
export interface UnifiedMergeConfig {
diff --git a/CodeMirror6/NodeLib/src/CmFileUpload.ts b/CodeMirror6/NodeLib/src/CmFileUpload.ts
index 7e4fcdcf..92ab5b07 100644
--- a/CodeMirror6/NodeLib/src/CmFileUpload.ts
+++ b/CodeMirror6/NodeLib/src/CmFileUpload.ts
@@ -37,11 +37,13 @@ export function getFileUploadExtensions(id: string, setup: CmSetup)
const dragAndDropHandler = EditorView.domEventHandlers({
dragenter(event, view) {
+ if (!event.dataTransfer?.files.length) return
event.preventDefault()
overlay.style.display = 'flex'
depth++
},
dragleave(event, view) {
+ if (!event.dataTransfer?.files.length) return
event.preventDefault();
depth--
if (depth === 0) {
@@ -49,10 +51,12 @@ export function getFileUploadExtensions(id: string, setup: CmSetup)
}
},
dragover(event, view) {
+ if (!event.dataTransfer?.files.length) return
event.preventDefault()
overlay.style.display = 'flex'
},
drop(event, view) {
+ if (!event.dataTransfer?.files.length) return
const transfer = event.dataTransfer
if (transfer?.files) {
overlay.style.display = 'none'
diff --git a/CodeMirror6/NodeLib/src/CmInstance.ts b/CodeMirror6/NodeLib/src/CmInstance.ts
index 2ed05e21..3d8036fb 100644
--- a/CodeMirror6/NodeLib/src/CmInstance.ts
+++ b/CodeMirror6/NodeLib/src/CmInstance.ts
@@ -24,6 +24,8 @@ export class CmInstance
public emojiReplacerCompartment: Compartment = new Compartment
public lineWrappingCompartment: Compartment = new Compartment
public unifiedMergeViewCompartment: Compartment = new Compartment
+ public highlightTrailingWhitespaceCompartment: Compartment = new Compartment
+ public highlightWhitespaceCompartment: Compartment = new Compartment
}
export const CMInstances: { [id: string]: CmInstance} = {}
diff --git a/CodeMirror6/NodeLib/src/CmLanguage.ts b/CodeMirror6/NodeLib/src/CmLanguage.ts
index 27e0575d..300f3841 100644
--- a/CodeMirror6/NodeLib/src/CmLanguage.ts
+++ b/CodeMirror6/NodeLib/src/CmLanguage.ts
@@ -29,7 +29,7 @@ export async function getLanguage(languageName: string, fileNameOrExtension: str
}
console.log("getLanguage: " + languageName)
switch (languageName) {
- case "PlainText":
+ case "Plain Text":
return null
case "Lezer":
return lezer()
diff --git a/CodeMirror6/NodeLib/src/CmSetup.ts b/CodeMirror6/NodeLib/src/CmSetup.ts
index 18b2f389..2ecf869c 100644
--- a/CodeMirror6/NodeLib/src/CmSetup.ts
+++ b/CodeMirror6/NodeLib/src/CmSetup.ts
@@ -27,4 +27,5 @@ export class CmSetup
public fileIcon: string
public bindValueMode: string
public krokiUrl: string
+ public scrollPastEnd: boolean
}
diff --git a/CodeMirror6/NodeLib/src/index.ts b/CodeMirror6/NodeLib/src/index.ts
index a8535347..e1c2d728 100644
--- a/CodeMirror6/NodeLib/src/index.ts
+++ b/CodeMirror6/NodeLib/src/index.ts
@@ -1,7 +1,7 @@
import {
EditorView, keymap, highlightSpecialChars, drawSelection, highlightActiveLine, dropCursor,
- rectangularSelection, crosshairCursor, ViewUpdate,
- lineNumbers, highlightActiveLineGutter, placeholder
+ rectangularSelection, crosshairCursor, ViewUpdate, lineNumbers, highlightActiveLineGutter,
+ placeholder, scrollPastEnd, highlightTrailingWhitespace, highlightWhitespace
} from "@codemirror/view"
import { EditorState, SelectionRange, Text } from "@codemirror/state"
import {
@@ -16,10 +16,11 @@ import {
indentUnit, defaultHighlightStyle, syntaxHighlighting, indentOnInput, bracketMatching,
foldGutter, foldKeymap,
} from "@codemirror/language"
+import { languages } from "@codemirror/language-data"
import { unifiedMergeView } from "@codemirror/merge"
import { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap, Completion } from "@codemirror/autocomplete"
import { searchKeymap, highlightSelectionMatches } from "@codemirror/search"
-import { linter, lintKeymap } from "@codemirror/lint"
+import { linter, lintGutter, lintKeymap } from "@codemirror/lint"
import { CmInstance, CMInstances } from "./CmInstance"
import { CmConfiguration, UnifiedMergeConfig } from "./CmConfiguration"
import { getDynamicHeaderStyling } from "./CmDynamicMarkdownHeaderStyling"
@@ -55,7 +56,6 @@ import { DotNet } from "@microsoft/dotnet-js-interop"
import { markdownTableExtension } from "./CmMarkdownTable"
import { dynamicDiagramsExtension } from "./CmDiagrams"
import { hideMarksExtension } from "./CmHideMarkdownMarks"
-import { languages } from "@codemirror/language-data"
/**
* Initialize a new CodeMirror instance
@@ -91,6 +91,8 @@ export async function initCodeMirror(
indentationMarkers(),
CMInstances[id].lineWrappingCompartment.of(initialConfig.lineWrapping ? 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() : []),
EditorView.updateListener.of(async (update) => { await updateListenerExtension(id, update) }),
keymap.of([
@@ -145,15 +147,18 @@ export async function initCodeMirror(
if (setup.syntaxHighlighting === true) extensions.push(syntaxHighlighting(defaultHighlightStyle, { fallback: true }))
if (setup.bracketMatching === true) extensions.push(bracketMatching())
if (setup.closeBrackets === true) extensions.push(closeBrackets())
- if (setup.autocompletion === true) extensions.push(autocompletion({}))
+ if (setup.autocompletion === true) extensions.push(autocompletion())
if (setup.rectangularSelection === true) extensions.push(rectangularSelection())
if (setup.crossHairSelection === true) extensions.push(crosshairCursor())
if (setup.highlightActiveLine === true) extensions.push(highlightActiveLine())
if (setup.highlightSelectionMatches === true) extensions.push(highlightSelectionMatches())
+ if (setup.scrollPastEnd === true) extensions.push(scrollPastEnd())
+ if (setup.allowMultipleSelections === true) extensions.push(EditorState.allowMultipleSelections.of(true))
if (initialConfig.lintingEnabled === true || setup.bindValueMode == "OnDelayedInput")
extensions.push(linter(async view => await externalLintSource(view, dotnetHelper), getExternalLinterConfig()))
- if (setup.allowMultipleSelections === true) extensions.push(EditorState.allowMultipleSelections.of(true))
+ if (initialConfig.lintingEnabled === true)
+ extensions.push(lintGutter())
extensions.push(...getFileUploadExtensions(id, setup))
@@ -299,6 +304,18 @@ export function setMentionCompletions(id: string, mentionCompletions: Completion
forceRedraw(id)
}
+export function setHighlightTrailingWhitespace(id: string, value: boolean) {
+ CMInstances[id].view.dispatch({
+ effects: CMInstances[id].highlightTrailingWhitespaceCompartment.reconfigure(value ? highlightTrailingWhitespace() : [])
+ })
+}
+
+export function setHighlightWhitespace(id: string, value: boolean) {
+ CMInstances[id].view.dispatch({
+ effects: CMInstances[id].highlightWhitespaceCompartment.reconfigure(value ? highlightWhitespace() : [])
+ })
+}
+
export function forceRedraw(id: string) {
const view = CMInstances[id].view
if (!view) return
diff --git a/Examples.BlazorServer/Examples.BlazorServer.csproj b/Examples.BlazorServer/Examples.BlazorServer.csproj
index 09202c29..1f3d7c73 100644
--- a/Examples.BlazorServer/Examples.BlazorServer.csproj
+++ b/Examples.BlazorServer/Examples.BlazorServer.csproj
@@ -4,7 +4,7 @@
enable
false
enable
- 0.2.0
+ 0.2.1
@@ -16,4 +16,4 @@
-
+
\ No newline at end of file
diff --git a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
index 858f6981..4f133da7 100644
--- a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
+++ b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.2.0
+ 0.2.1
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/Examples.BlazorWasm/Examples.BlazorWasm.csproj b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
index 0faf5454..1f2ee711 100644
--- a/Examples.BlazorWasm/Examples.BlazorWasm.csproj
+++ b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.2.0
+ 0.2.1
@@ -17,4 +17,4 @@
-
+
\ No newline at end of file
diff --git a/Examples.Common/Example.razor b/Examples.Common/Example.razor
index 17ac159d..7b1184fe 100644
--- a/Examples.Common/Example.razor
+++ b/Examples.Common/Example.razor
@@ -10,11 +10,8 @@
@@ -75,6 +72,20 @@
}
+
+
+ {
+ HighlightTrailingWhitespace = (v.Value as bool?) == true;
+ await InvokeAsync(StateHasChanged);
+ }) />
+
+
+ {
+ HighlightWhitespace = (v.Value as bool?) == true;
+ await InvokeAsync(StateHasChanged);
+ }) />
+
+
@@ -260,6 +273,8 @@
private bool ReplaceEmojiCodes = false;
private bool LineWrapping = true;
private bool MergeViewEnabled = false;
+ private bool HighlightTrailingWhitespace = true;
+ private bool HighlightWhitespace = false;
private List Languages =>
Enum.GetValues()
.OrderBy(l => l == CodeMirrorLanguage.PlainText ? 0 : 1)
@@ -271,6 +286,7 @@
HighlightActiveLineGutter = false,
HighlightSelectionMatches = false,
ScrollToEnd = true,
+ ScrollPastEnd = true,
BindMode = DocumentBindMode.OnDelayedInput,
};
private UnifiedMergeConfig? PreviousMergeViewConfiguration;
diff --git a/Examples.Common/Examples.Common.csproj b/Examples.Common/Examples.Common.csproj
index 6f20717a..48e1ff97 100644
--- a/Examples.Common/Examples.Common.csproj
+++ b/Examples.Common/Examples.Common.csproj
@@ -5,7 +5,7 @@
enable
enable
false
- 0.2.0
+ 0.2.1
@@ -18,4 +18,4 @@
-
+
\ No newline at end of file
diff --git a/Examples.Common/_Imports.razor b/Examples.Common/_Imports.razor
index 74af7536..e1bc1b8a 100644
--- a/Examples.Common/_Imports.razor
+++ b/Examples.Common/_Imports.razor
@@ -9,4 +9,3 @@
@using GaelJ.BlazorCodeMirror6.Commands
@using GaelJ.BlazorCodeMirror6.Models
@using System.Linq
-@using System.Reflection
diff --git a/NEW_CHANGELOG.md b/NEW_CHANGELOG.md
index 6023aa62..2a16d593 100644
--- a/NEW_CHANGELOG.md
+++ b/NEW_CHANGELOG.md
@@ -1,21 +1,14 @@
### ✨ Introduce new features
-- Implement configurable Unified Merge View
-- Support and dynamically load 145 languages
-- Allow specifying FileNameOrExtension to detect language automatically (instead of specifying Language parameter)
+- Add DisplayName() extension to CodeMirrorLanguage enum
+- Allow scrolling past the end of the document
+- Implement white space & trailing white space highlighting
-### ⚡️ Improve performance
+### 🐛 Fix a bug
-- Use record instead of class for interop DTOs: CodeMirrorCompletion/Section, CodeMirrorDiagnostic
+- Fix dragging text was highjacked by the file drag overlay
+- Fix empty language definitions in example
-### ⬆️ Upgrade dependencies
+### ✏️ Fix typos
-- Update dependencies: Sentry in examples projects ; languages, merge, babel in js
-
-### 📝 Add or update documentation
-
-- Add csv mode in README.md todo
-
-### 🚚 Move or rename resources (e.g., files, paths)
-
-- Move GetMentionCompletions in example, to dedicated file
+- Display Plain Text language name with space