Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 61 additions & 7 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@
if (!editSucceeded) {
const result = Papa.parse(oldText, { dynamicTyping: false, delimiter: separator });
const data = result.data as string[][];
while (data.length <= row) data.push([]);

Check warning on line 229 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'while' condition
while (data[row].length <= col) data[row].push('');

Check warning on line 230 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'while' condition
data[row][col] = value;
const newCsvText = Papa.unparse(data, { delimiter: separator });
const fullRange = new vscode.Range(0, 0, this.document.lineCount, this.document.lineCount ? this.document.lineAt(this.document.lineCount - 1).text.length : 0);
Expand Down Expand Up @@ -266,7 +266,7 @@
const data = result.data as string[][];
for (const row of data) {
if (index > row.length) {
while (row.length < index) row.push('');

Check warning on line 269 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'while' condition
}
row.splice(index, 0, '');
}
Expand Down Expand Up @@ -327,7 +327,7 @@

const cmp = (a: string, b: string) => {
const na = parseFloat(a), nb = parseFloat(b);
if (!isNaN(na) && !isNaN(nb)) return na - nb; // numeric compare

Check warning on line 330 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'if' condition
return a.localeCompare(b, undefined, { sensitivity: 'base' });
};

Expand Down Expand Up @@ -368,7 +368,7 @@
const numColumns = Math.max(...data.map(r => r.length), 0);
const newRow = Array(numColumns).fill('');
if (index > data.length) {
while (data.length < index) data.push(Array(numColumns).fill(''));

Check warning on line 371 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'while' condition
}
data.splice(index, 0, newRow);
const newText = Papa.unparse(data, { delimiter: separator });
Expand Down Expand Up @@ -473,8 +473,8 @@
}

// keep **only** the first chunk in the initial render
if (treatHeader) bodyData.length = CHUNK_SIZE;

Check warning on line 476 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'if' condition
else data.length = CHUNK_SIZE;

Check warning on line 477 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'else'
}
/* ────────── END VIRTUAL-SCROLL SUPPORT ────────── */

Expand Down Expand Up @@ -602,7 +602,7 @@
document.body.setAttribute('tabindex', '0'); document.body.focus();
const vscode = acquireVsCodeApi();
let lastContextIsHeader = false; // remembers whether we right-clicked a <th>
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');
Expand Down Expand Up @@ -704,8 +704,32 @@

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
Expand All @@ -722,7 +746,7 @@
/* ──────── 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 => {
Expand All @@ -731,6 +755,7 @@
if(selectionMode === "cell"){
if(target.tagName === 'TD' || target.tagName === 'TH'){
endCell = target;
rangeEndCell = target;
selectRange(getCellCoords(startCell), getCellCoords(endCell));
}
} else if(selectionMode === "column"){
Expand All @@ -739,6 +764,7 @@
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);
Expand All @@ -748,6 +774,7 @@
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);
Expand All @@ -758,16 +785,20 @@
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) => {
Expand Down Expand Up @@ -887,6 +918,28 @@
}

/* ──────── 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;
Expand All @@ -905,6 +958,7 @@
nextCell.classList.add('selected');
currentSelection.push(nextCell);
anchorCell = nextCell;
rangeEndCell = nextCell;
nextCell.focus({preventScroll:true});
nextCell.scrollIntoView({ block:'nearest', inline:'nearest', behavior:'smooth' });
}
Expand Down Expand Up @@ -1078,11 +1132,11 @@
for (const cell of column) {
const items = cell.split(',').map(item => item.trim());
for (const item of items){
if (item === '') continue;

Check warning on line 1135 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'if' condition
allEmpty = false;
const lower = item.toLowerCase();
if (!(lower === 'true' || lower === 'false')) allBoolean = false;

Check warning on line 1138 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'if' condition
if (!this.isDate(item)) allDate = false;

Check warning on line 1139 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Expected { after 'if' condition
const num = Number(item);
if (!Number.isInteger(num)) allInteger = false;
if (isNaN(num)) allFloat = false;
Expand Down
Loading