diff --git a/CHANGELOG.md b/CHANGELOG.md
index 670c30c..226b1f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# Changelog
+## 0.7.4 - 2024-03-01
+
+### ✨ Introduce new features
+
+- Support multiple cursors for (shift +) home & end keys
+
+### 🐛 Fix a bug
+
+- Fix error when parsing TSV line with empty cell(s) at the end of the last row
+
## 0.7.3 - 2024-02-27
### 🐛 Fix a bug
diff --git a/CodeMirror6/CodeMirror6.csproj b/CodeMirror6/CodeMirror6.csproj
index 80123a9..dcf4fb2 100644
--- a/CodeMirror6/CodeMirror6.csproj
+++ b/CodeMirror6/CodeMirror6.csproj
@@ -9,7 +9,7 @@
GaelJ.BlazorCodeMirror6
true
GaelJ.BlazorCodeMirror6
- 0.7.3
+ 0.7.4
true
snupkg
true
diff --git a/CodeMirror6/NodeLib/src/CmColumns.ts b/CodeMirror6/NodeLib/src/CmColumns.ts
index f6ed22c..73fbc6b 100644
--- a/CodeMirror6/NodeLib/src/CmColumns.ts
+++ b/CodeMirror6/NodeLib/src/CmColumns.ts
@@ -275,7 +275,7 @@ function findMaxColumnWidths(data: string[][]): number[] {
}
function parseCSV(csvData: string, separator: string): string[][] {
- return csvData.trim().split('\n').map((row) => extractAllRowCells(row, separator))
+ return csvData.split('\n').filter(row => row).map((row) => extractAllRowCells(row, separator))
}
export function csvToMarkdownTable(text: string, separator: string, withHeaders: boolean)
diff --git a/CodeMirror6/NodeLib/src/CmKeymap.ts b/CodeMirror6/NodeLib/src/CmKeymap.ts
index d5ec61a..379fddc 100644
--- a/CodeMirror6/NodeLib/src/CmKeymap.ts
+++ b/CodeMirror6/NodeLib/src/CmKeymap.ts
@@ -1,6 +1,6 @@
import { toggleMarkdownBold, toggleMarkdownItalic } from "./CmCommands"
import { KeyBinding, EditorView } from '@codemirror/view'
-import { Extension, RangeSetBuilder, Transaction, EditorSelection, SelectionRange, Text } from "@codemirror/state"
+import { EditorSelection, SelectionRange, Text } from "@codemirror/state"
import {
deleteCharBackward, deleteCharForward, deleteGroupBackward, deleteGroupForward,
cursorGroupLeft, cursorGroupRight, selectGroupLeft, selectGroupRight,
@@ -12,14 +12,14 @@ export const customMarkdownKeymap: KeyBinding[] = [
{ key: 'Mod-i', run: toggleMarkdownItalic }, // Cmd/Ctrl + I for italics
]
-export const customDeleteKeymap = [
+export const multipleCursorDeleteKeymap = [
{ key: "Delete", run: deleteCharForward },
{ key: "Backspace", run: deleteCharBackward },
{ key: "Mod-Delete", run: deleteGroupForward },
{ key: "Mod-Backspace", run: deleteGroupBackward },
]
-export const customArrowKeymap: KeyBinding[] = [
+export const multipleCursorNavigationKeymap: KeyBinding[] = [
{
key: "ArrowLeft",
run: (view) => moveCursorsByCharacter(view, true, false),
@@ -40,6 +40,16 @@ export const customArrowKeymap: KeyBinding[] = [
run: (view) => moveCursorsByWord(view, false, false),
shift: (view) => moveCursorsByWord(view, false, true),
},
+ {
+ key: "Home",
+ run: (view) => moveCursorsToLineBoundaries(view, true, false),
+ shift: (view) => moveCursorsToLineBoundaries(view, true, true),
+ },
+ {
+ key: "End",
+ run: (view) => moveCursorsToLineBoundaries(view, false, false),
+ shift: (view) => moveCursorsToLineBoundaries(view, false, true),
+ },
]
function moveCursorsByCharacter(view: EditorView, previous: boolean, headOnly: boolean) {
@@ -80,6 +90,28 @@ function moveCursorsByWord(view: EditorView, previous: boolean, headOnly: boolea
return true
}
+function moveCursorsToLineBoundaries(view: EditorView, start: boolean, headOnly: boolean): boolean {
+ const { state } = view
+ const newSelectionRanges: SelectionRange[] = []
+ for (const range of state.selection.ranges) {
+ const currentPos = range.head
+ const startOfLine = state.doc.lineAt(currentPos).from
+ const endOfLine = state.doc.lineAt(currentPos).to
+ const lineBoundary = start ? startOfLine : endOfLine
+
+ const newAnchor = headOnly ? range.anchor : lineBoundary
+ const newHead = !headOnly ? newAnchor : lineBoundary
+
+ newSelectionRanges.push(EditorSelection.range(newAnchor, newHead))
+ }
+ view.dispatch(state.update({
+ selection: EditorSelection.create(newSelectionRanges),
+ scrollIntoView: true,
+ userEvent: 'input'
+ }))
+ return true
+}
+
function findWordBoundary(doc: Text, pos: number, previous: boolean, firstRun: boolean): number {
if (previous && pos === 0) return 0
if (!previous && pos === doc.length) return doc.length
diff --git a/CodeMirror6/NodeLib/src/CmMentionsCompletion.ts b/CodeMirror6/NodeLib/src/CmMentionsCompletion.ts
index dea9923..f15397a 100644
--- a/CodeMirror6/NodeLib/src/CmMentionsCompletion.ts
+++ b/CodeMirror6/NodeLib/src/CmMentionsCompletion.ts
@@ -44,9 +44,7 @@ function getMentionCompletions(firstCharacters: string | null): Completion[] {
export function setCachedCompletions(completions: Completion[]) {
if (cachedCompletions.length === 0) {
- completions.forEach(completion => {
- cachedCompletions.push(completion)
- })
+ cachedCompletions.push(...completions)
}
}
diff --git a/CodeMirror6/NodeLib/src/index.ts b/CodeMirror6/NodeLib/src/index.ts
index 31d9d42..71418ee 100644
--- a/CodeMirror6/NodeLib/src/index.ts
+++ b/CodeMirror6/NodeLib/src/index.ts
@@ -61,7 +61,7 @@ import { getColumnStylingKeymap, columnStylingPlugin, columnLintSource, getSepar
import { consoleLog } from "./CmLogging"
import { createEditorWithId } from "./CmId"
import { hyperLink } from './CmHyperlink'
-import { customArrowKeymap, customDeleteKeymap } from "./CmKeymap"
+import { multipleCursorNavigationKeymap, multipleCursorDeleteKeymap } from "./CmKeymap"
export { getCmInstance }
@@ -180,8 +180,8 @@ export async function initCodeMirror(
...foldKeymap,
...completionKeymap,
...lintKeymap,
- ...customDeleteKeymap,
- ...customArrowKeymap,
+ ...multipleCursorDeleteKeymap,
+ ...multipleCursorNavigationKeymap,
])
]
diff --git a/Examples.BlazorServer/Examples.BlazorServer.csproj b/Examples.BlazorServer/Examples.BlazorServer.csproj
index 396202a..fd86374 100644
--- a/Examples.BlazorServer/Examples.BlazorServer.csproj
+++ b/Examples.BlazorServer/Examples.BlazorServer.csproj
@@ -4,7 +4,7 @@
enable
false
enable
- 0.7.3
+ 0.7.4
diff --git a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
index 97aa5ec..996fafa 100644
--- a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
+++ b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.7.3
+ 0.7.4
diff --git a/Examples.BlazorWasm/Examples.BlazorWasm.csproj b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
index 7363635..ac75cf2 100644
--- a/Examples.BlazorWasm/Examples.BlazorWasm.csproj
+++ b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.7.3
+ 0.7.4
diff --git a/Examples.Common/Examples.Common.csproj b/Examples.Common/Examples.Common.csproj
index 57f6806..f12e6cb 100644
--- a/Examples.Common/Examples.Common.csproj
+++ b/Examples.Common/Examples.Common.csproj
@@ -5,7 +5,7 @@
enable
enable
false
- 0.7.3
+ 0.7.4
diff --git a/NEW_CHANGELOG.md b/NEW_CHANGELOG.md
index 8d83b39..d70d335 100644
--- a/NEW_CHANGELOG.md
+++ b/NEW_CHANGELOG.md
@@ -1,8 +1,7 @@
-### 🐛 Fix a bug
+### ✨ Introduce new features
-- Fix possible null ref on startup
-- Replace \r\n with \n when pasting, to prevent crash in windows (#153)
+- Support multiple cursors for (shift +) home & end keys
-### 🗑️ Deprecate code that needs to be cleaned up
+### 🐛 Fix a bug
-- Remove useless exports (#144)
+- Fix error when parsing TSV line with empty cell(s) at the end of the last row