diff --git a/src/extension.ts b/src/extension.ts
index fc86d1b..45cc3ca 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -602,7 +602,7 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
document.body.setAttribute('tabindex', '0'); document.body.focus();
const vscode = acquireVsCodeApi();
let lastContextIsHeader = false; // remembers whether we right-clicked a
- let isUpdating = false, isSelecting = false, anchorCell = null, currentSelection = [];
+ let isUpdating = false, isSelecting = false, anchorCell = null, rangeEndCell = null, currentSelection = [];
let startCell = null, endCell = null, selectionMode = "cell";
let editingCell = null, originalCellValue = "";
const table = document.querySelector('table');
@@ -704,8 +704,32 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
table.addEventListener('mousedown', e => {
if(e.target.tagName !== 'TD' && e.target.tagName !== 'TH') return;
- if(editingCell){ if(e.target !== editingCell) editingCell.blur(); else return; } else clearSelection();
const target = e.target;
+
+ // ──────── NEW: Shift+Click range selection ────────
+ if (
+ e.shiftKey &&
+ anchorCell &&
+ !editingCell &&
+ target.getAttribute('data-row') !== null &&
+ target.getAttribute('data-col') !== null &&
+ anchorCell.getAttribute('data-row') !== null &&
+ anchorCell.getAttribute('data-col') !== null &&
+ target.getAttribute('data-col') !== '-1' &&
+ anchorCell.getAttribute('data-col') !== '-1'
+ ) {
+ e.preventDefault();
+ selectRange(
+ getCellCoords(anchorCell),
+ getCellCoords(target)
+ );
+ rangeEndCell = target;
+ anchorCell.focus();
+ return;
+ }
+
+ if(editingCell){ if(e.target !== editingCell) editingCell.blur(); else return; } else clearSelection();
+
/* ──────── NEW: select-all via top-left header cell ──────── */
if (
target.tagName === 'TH' && // header cell
@@ -722,7 +746,7 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
/* ──────── END NEW BLOCK ──────── */
selectionMode = (target.tagName === 'TH') ? "column" : (target.getAttribute('data-col') === '-1' ? "row" : "cell");
- startCell = target; endCell = target; isSelecting = true; e.preventDefault();
+ startCell = target; endCell = target; rangeEndCell = target; isSelecting = true; e.preventDefault();
target.focus();
});
table.addEventListener('mousemove', e => {
@@ -731,6 +755,7 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
if(selectionMode === "cell"){
if(target.tagName === 'TD' || target.tagName === 'TH'){
endCell = target;
+ rangeEndCell = target;
selectRange(getCellCoords(startCell), getCellCoords(endCell));
}
} else if(selectionMode === "column"){
@@ -739,6 +764,7 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
target = table.querySelector('thead th[data-col="'+col+'"]') || target;
}
endCell = target;
+ rangeEndCell = target;
const startCol = parseInt(startCell.getAttribute('data-col'));
const endCol = parseInt(endCell.getAttribute('data-col'));
selectFullColumnRange(startCol, endCol);
@@ -748,6 +774,7 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
target = table.querySelector('td[data-col="-1"][data-row="'+row+'"]') || target;
}
endCell = target;
+ rangeEndCell = target;
const startRow = parseInt(startCell.getAttribute('data-row'));
const endRow = parseInt(endCell.getAttribute('data-row'));
selectFullRowRange(startRow, endRow);
@@ -758,16 +785,20 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
isSelecting = false;
if(selectionMode === "cell"){
if(startCell === endCell){
- clearSelection(); startCell.classList.add('selected'); currentSelection.push(startCell); anchorCell = startCell;
- } else { anchorCell = startCell; }
+ clearSelection();
+ startCell.classList.add('selected');
+ currentSelection.push(startCell);
+ }
+ anchorCell = startCell;
+ rangeEndCell = endCell;
} else if(selectionMode === "column"){
const startCol = parseInt(startCell.getAttribute('data-col'));
const endCol = parseInt(endCell.getAttribute('data-col'));
- selectFullColumnRange(startCol, endCol); anchorCell = startCell;
+ selectFullColumnRange(startCol, endCol); anchorCell = startCell; rangeEndCell = endCell;
} else if(selectionMode === "row"){
const startRow = parseInt(startCell.getAttribute('data-row'));
const endRow = parseInt(endCell.getAttribute('data-row'));
- selectFullRowRange(startRow, endRow); anchorCell = startCell;
+ selectFullRowRange(startRow, endRow); anchorCell = startCell; rangeEndCell = endCell;
}
});
const selectRange = (start, end) => {
@@ -887,6 +918,28 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
}
/* ──────── ARROW KEY NAVIGATION ──────── */
+ if (!editingCell && anchorCell && e.shiftKey && ['ArrowUp','ArrowDown','ArrowLeft','ArrowRight'].includes(e.key)) {
+ const { row, col } = getCellCoords(rangeEndCell || anchorCell);
+ let targetRow = row, targetCol = col;
+ switch(e.key){
+ case 'ArrowUp': targetRow = row - 1; break;
+ case 'ArrowDown': targetRow = row + 1; break;
+ case 'ArrowLeft': targetCol = col - 1; break;
+ case 'ArrowRight':targetCol = col + 1; break;
+ }
+ if(targetRow < 0 || targetCol < 0) return;
+ const tag = (hasHeader && targetRow === 0 ? 'th' : 'td');
+ const nextCell = table.querySelector(\`\${tag}[data-row="\${targetRow}"][data-col="\${targetCol}"]\`);
+ if(nextCell){
+ e.preventDefault();
+ rangeEndCell = nextCell;
+ selectRange(getCellCoords(anchorCell), getCellCoords(rangeEndCell));
+ anchorCell.focus({preventScroll:true});
+ rangeEndCell.scrollIntoView({ block:'nearest', inline:'nearest', behavior:'smooth' });
+ }
+ return;
+ }
+
if (!editingCell && anchorCell && ['ArrowUp','ArrowDown','ArrowLeft','ArrowRight'].includes(e.key)) {
const { row, col } = getCellCoords(anchorCell);
let targetRow = row, targetCol = col;
@@ -905,6 +958,7 @@ class CsvEditorProvider implements vscode.CustomTextEditorProvider {
nextCell.classList.add('selected');
currentSelection.push(nextCell);
anchorCell = nextCell;
+ rangeEndCell = nextCell;
nextCell.focus({preventScroll:true});
nextCell.scrollIntoView({ block:'nearest', inline:'nearest', behavior:'smooth' });
}
|