vim-sim 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -30
- package/dist/index.d.ts +111 -75
- package/dist/index.js +524 -216
- package/dist/index.js.map +1 -1
- package/docs/config-system-improvements.md +221 -0
- package/docs/vim-compatibility.md +246 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -642,19 +642,19 @@ var FileSystemManager = class _FileSystemManager {
|
|
|
642
642
|
/**
|
|
643
643
|
* Create or open a file with the given path
|
|
644
644
|
*/
|
|
645
|
-
openFile(
|
|
645
|
+
openFile(path, content = "", readonly = false) {
|
|
646
646
|
const newFiles = new Map(this.files);
|
|
647
|
-
if (newFiles.has(
|
|
648
|
-
return new _FileSystemManager(newFiles,
|
|
647
|
+
if (newFiles.has(path)) {
|
|
648
|
+
return new _FileSystemManager(newFiles, path);
|
|
649
649
|
}
|
|
650
650
|
const file = {
|
|
651
|
-
path
|
|
651
|
+
path,
|
|
652
652
|
buffer: new Buffer(content),
|
|
653
653
|
modified: false,
|
|
654
654
|
readonly
|
|
655
655
|
};
|
|
656
|
-
newFiles.set(
|
|
657
|
-
return new _FileSystemManager(newFiles,
|
|
656
|
+
newFiles.set(path, file);
|
|
657
|
+
return new _FileSystemManager(newFiles, path);
|
|
658
658
|
}
|
|
659
659
|
/**
|
|
660
660
|
* Update the buffer content for the current file
|
|
@@ -739,9 +739,9 @@ var FileSystemManager = class _FileSystemManager {
|
|
|
739
739
|
/**
|
|
740
740
|
* Switch to a specific file by path
|
|
741
741
|
*/
|
|
742
|
-
switchToFile(
|
|
743
|
-
if (this.files.has(
|
|
744
|
-
return new _FileSystemManager(this.files,
|
|
742
|
+
switchToFile(path) {
|
|
743
|
+
if (this.files.has(path)) {
|
|
744
|
+
return new _FileSystemManager(this.files, path);
|
|
745
745
|
}
|
|
746
746
|
return this;
|
|
747
747
|
}
|
|
@@ -1304,8 +1304,6 @@ var SpellChecker = class _SpellChecker {
|
|
|
1304
1304
|
};
|
|
1305
1305
|
|
|
1306
1306
|
// src/types/CompletionManager.ts
|
|
1307
|
-
import path from "path";
|
|
1308
|
-
import * as fs from "fs";
|
|
1309
1307
|
var CompletionManager = class _CompletionManager {
|
|
1310
1308
|
state = null;
|
|
1311
1309
|
constructor() {
|
|
@@ -1406,36 +1404,19 @@ var CompletionManager = class _CompletionManager {
|
|
|
1406
1404
|
}
|
|
1407
1405
|
/**
|
|
1408
1406
|
* Start filename completion
|
|
1407
|
+
* Note: This is a stub in browser environments. File system access requires Node.js.
|
|
1409
1408
|
*/
|
|
1410
|
-
async fileNameCompletion(buffer, cursorLine, cursorCol, currentDir
|
|
1409
|
+
async fileNameCompletion(buffer, cursorLine, cursorCol, currentDir) {
|
|
1411
1410
|
const prefix = this.getFilePathPrefix(buffer, cursorLine, cursorCol);
|
|
1412
1411
|
if (prefix.length === 0) return [];
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
}
|
|
1422
|
-
const matches = files.filter((file) => file.startsWith(basename)).map((file) => ({
|
|
1423
|
-
text: path.join(path.dirname(prefix), file),
|
|
1424
|
-
type: "filename" /* FILENAME */,
|
|
1425
|
-
info: this.getFileTypeInfo(path.join(dirname, file))
|
|
1426
|
-
}));
|
|
1427
|
-
this.state = {
|
|
1428
|
-
matches,
|
|
1429
|
-
currentIndex: 0,
|
|
1430
|
-
prefix,
|
|
1431
|
-
type: "filename" /* FILENAME */,
|
|
1432
|
-
isActive: prefix.length > 0
|
|
1433
|
-
// Active if we have a prefix, even if no matches
|
|
1434
|
-
};
|
|
1435
|
-
return matches;
|
|
1436
|
-
} catch (error) {
|
|
1437
|
-
return [];
|
|
1438
|
-
}
|
|
1412
|
+
this.state = {
|
|
1413
|
+
matches: [],
|
|
1414
|
+
currentIndex: 0,
|
|
1415
|
+
prefix,
|
|
1416
|
+
type: "filename" /* FILENAME */,
|
|
1417
|
+
isActive: prefix.length > 0
|
|
1418
|
+
};
|
|
1419
|
+
return [];
|
|
1439
1420
|
}
|
|
1440
1421
|
/**
|
|
1441
1422
|
* Start omni completion - context-aware completion
|
|
@@ -1499,17 +1480,10 @@ var CompletionManager = class _CompletionManager {
|
|
|
1499
1480
|
}
|
|
1500
1481
|
/**
|
|
1501
1482
|
* Get file type information
|
|
1483
|
+
* Note: Stub implementation for browser compatibility
|
|
1502
1484
|
*/
|
|
1503
1485
|
getFileTypeInfo(filepath) {
|
|
1504
|
-
|
|
1505
|
-
const stat = fs.statSync(filepath);
|
|
1506
|
-
if (stat.isDirectory()) return "directory";
|
|
1507
|
-
if (stat.isFile()) return "file";
|
|
1508
|
-
if (stat.isSymbolicLink()) return "symlink";
|
|
1509
|
-
return "unknown";
|
|
1510
|
-
} catch {
|
|
1511
|
-
return "unknown";
|
|
1512
|
-
}
|
|
1486
|
+
return "unknown";
|
|
1513
1487
|
}
|
|
1514
1488
|
/**
|
|
1515
1489
|
* Get completion text to insert (without prefix)
|
|
@@ -1547,9 +1521,342 @@ var CompletionManager = class _CompletionManager {
|
|
|
1547
1521
|
}
|
|
1548
1522
|
};
|
|
1549
1523
|
|
|
1524
|
+
// src/core/config-manager.ts
|
|
1525
|
+
var ConfigManager = class _ConfigManager {
|
|
1526
|
+
config;
|
|
1527
|
+
listeners = /* @__PURE__ */ new Map();
|
|
1528
|
+
constructor(initialConfig) {
|
|
1529
|
+
this.config = {
|
|
1530
|
+
// Display
|
|
1531
|
+
number: false,
|
|
1532
|
+
relativenumber: false,
|
|
1533
|
+
wrap: true,
|
|
1534
|
+
cursorline: false,
|
|
1535
|
+
// Indentation
|
|
1536
|
+
tabstop: 4,
|
|
1537
|
+
shiftwidth: 2,
|
|
1538
|
+
expandtab: true,
|
|
1539
|
+
autoindent: true,
|
|
1540
|
+
smartindent: false,
|
|
1541
|
+
// Search
|
|
1542
|
+
ignorecase: false,
|
|
1543
|
+
smartcase: false,
|
|
1544
|
+
hlsearch: true,
|
|
1545
|
+
incsearch: true,
|
|
1546
|
+
wrapscan: true,
|
|
1547
|
+
// Motion behavior
|
|
1548
|
+
whichwrap: "h,l",
|
|
1549
|
+
// vim-sim default: h,l wrap (Vim default: "b,s")
|
|
1550
|
+
startofline: true,
|
|
1551
|
+
// Vim default: true
|
|
1552
|
+
virtualedit: "",
|
|
1553
|
+
// Vim default: ""
|
|
1554
|
+
// Editing
|
|
1555
|
+
undolevels: 1e3,
|
|
1556
|
+
clipboard: "",
|
|
1557
|
+
...initialConfig
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Get a config value
|
|
1562
|
+
*/
|
|
1563
|
+
get(key) {
|
|
1564
|
+
return this.config[key];
|
|
1565
|
+
}
|
|
1566
|
+
/**
|
|
1567
|
+
* Set a config value
|
|
1568
|
+
*/
|
|
1569
|
+
set(key, value) {
|
|
1570
|
+
const oldValue = this.config[key];
|
|
1571
|
+
if (oldValue === value) return;
|
|
1572
|
+
this.config[key] = value;
|
|
1573
|
+
this.notifyListeners(key, value);
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Set multiple config values at once
|
|
1577
|
+
*/
|
|
1578
|
+
setMultiple(updates) {
|
|
1579
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
1580
|
+
this.set(key, value);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Get all config values
|
|
1585
|
+
*/
|
|
1586
|
+
getAll() {
|
|
1587
|
+
return { ...this.config };
|
|
1588
|
+
}
|
|
1589
|
+
/**
|
|
1590
|
+
* Reset to default configuration
|
|
1591
|
+
*/
|
|
1592
|
+
reset() {
|
|
1593
|
+
const defaults = new _ConfigManager().getAll();
|
|
1594
|
+
this.setMultiple(defaults);
|
|
1595
|
+
}
|
|
1596
|
+
/**
|
|
1597
|
+
* Toggle a boolean config option
|
|
1598
|
+
*/
|
|
1599
|
+
toggle(key) {
|
|
1600
|
+
const value = this.config[key];
|
|
1601
|
+
if (typeof value === "boolean") {
|
|
1602
|
+
this.set(key, !value);
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* Subscribe to config changes
|
|
1607
|
+
* @param key - Config key to watch, or '*' for all changes
|
|
1608
|
+
* @param callback - Function to call when config changes
|
|
1609
|
+
* @returns Unsubscribe function
|
|
1610
|
+
*/
|
|
1611
|
+
onChange(key, callback) {
|
|
1612
|
+
if (!this.listeners.has(key)) {
|
|
1613
|
+
this.listeners.set(key, /* @__PURE__ */ new Set());
|
|
1614
|
+
}
|
|
1615
|
+
this.listeners.get(key).add(callback);
|
|
1616
|
+
return () => {
|
|
1617
|
+
this.listeners.get(key)?.delete(callback);
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1620
|
+
/**
|
|
1621
|
+
* Notify all listeners of a config change
|
|
1622
|
+
*/
|
|
1623
|
+
notifyListeners(key, value) {
|
|
1624
|
+
this.listeners.get(key)?.forEach((callback) => callback(key, value));
|
|
1625
|
+
this.listeners.get("*")?.forEach((callback) => callback(key, value));
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Parse a Vim set command string (e.g., "number", "nonumber", "tabstop=4")
|
|
1629
|
+
*/
|
|
1630
|
+
parseSetCommand(command) {
|
|
1631
|
+
const noMatch = command.match(/^no(\w+)$/);
|
|
1632
|
+
if (noMatch) {
|
|
1633
|
+
const key2 = noMatch[1];
|
|
1634
|
+
if (key2 in this.config && typeof this.config[key2] === "boolean") {
|
|
1635
|
+
this.set(key2, false);
|
|
1636
|
+
return true;
|
|
1637
|
+
}
|
|
1638
|
+
return false;
|
|
1639
|
+
}
|
|
1640
|
+
const valueMatch = command.match(/^(\w+)=(.+)$/);
|
|
1641
|
+
if (valueMatch) {
|
|
1642
|
+
const key2 = valueMatch[1];
|
|
1643
|
+
const value = valueMatch[2];
|
|
1644
|
+
if (!(key2 in this.config)) return false;
|
|
1645
|
+
const currentValue = this.config[key2];
|
|
1646
|
+
if (typeof currentValue === "number") {
|
|
1647
|
+
const numValue = parseInt(value, 10);
|
|
1648
|
+
if (!isNaN(numValue)) {
|
|
1649
|
+
this.set(key2, numValue);
|
|
1650
|
+
return true;
|
|
1651
|
+
}
|
|
1652
|
+
} else if (typeof currentValue === "string") {
|
|
1653
|
+
this.set(key2, value);
|
|
1654
|
+
return true;
|
|
1655
|
+
}
|
|
1656
|
+
return false;
|
|
1657
|
+
}
|
|
1658
|
+
const key = command;
|
|
1659
|
+
if (key in this.config && typeof this.config[key] === "boolean") {
|
|
1660
|
+
this.set(key, true);
|
|
1661
|
+
return true;
|
|
1662
|
+
}
|
|
1663
|
+
return false;
|
|
1664
|
+
}
|
|
1665
|
+
/**
|
|
1666
|
+
* Get a formatted string representation of a config value
|
|
1667
|
+
*/
|
|
1668
|
+
formatValue(key) {
|
|
1669
|
+
const value = this.config[key];
|
|
1670
|
+
if (typeof value === "boolean") {
|
|
1671
|
+
return value ? key : `no${key}`;
|
|
1672
|
+
}
|
|
1673
|
+
return `${key}=${value}`;
|
|
1674
|
+
}
|
|
1675
|
+
/**
|
|
1676
|
+
* Get metadata about a config option
|
|
1677
|
+
*/
|
|
1678
|
+
getMetadata(key) {
|
|
1679
|
+
return CONFIG_METADATA[key];
|
|
1680
|
+
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Get all options that differ from vanilla Vim
|
|
1683
|
+
*/
|
|
1684
|
+
getDifferencesFromVim() {
|
|
1685
|
+
return Object.entries(CONFIG_METADATA).filter(([_, meta]) => meta.differsFromVim).map(([key, _]) => key);
|
|
1686
|
+
}
|
|
1687
|
+
/**
|
|
1688
|
+
* Get options by category
|
|
1689
|
+
*/
|
|
1690
|
+
getByCategory(category) {
|
|
1691
|
+
return Object.entries(CONFIG_METADATA).filter(([_, meta]) => meta.category === category).map(([key, _]) => key);
|
|
1692
|
+
}
|
|
1693
|
+
};
|
|
1694
|
+
var CONFIG_METADATA = {
|
|
1695
|
+
// Display options
|
|
1696
|
+
number: {
|
|
1697
|
+
description: "Show line numbers in the left margin",
|
|
1698
|
+
vimDefault: false,
|
|
1699
|
+
vimSimDefault: false,
|
|
1700
|
+
category: "display",
|
|
1701
|
+
type: "boolean",
|
|
1702
|
+
differsFromVim: false
|
|
1703
|
+
},
|
|
1704
|
+
relativenumber: {
|
|
1705
|
+
description: "Show line numbers relative to cursor position",
|
|
1706
|
+
vimDefault: false,
|
|
1707
|
+
vimSimDefault: false,
|
|
1708
|
+
category: "display",
|
|
1709
|
+
type: "boolean",
|
|
1710
|
+
differsFromVim: false
|
|
1711
|
+
},
|
|
1712
|
+
wrap: {
|
|
1713
|
+
description: "Wrap long lines to fit in window",
|
|
1714
|
+
vimDefault: true,
|
|
1715
|
+
vimSimDefault: true,
|
|
1716
|
+
category: "display",
|
|
1717
|
+
type: "boolean",
|
|
1718
|
+
differsFromVim: false
|
|
1719
|
+
},
|
|
1720
|
+
cursorline: {
|
|
1721
|
+
description: "Highlight the screen line of the cursor",
|
|
1722
|
+
vimDefault: false,
|
|
1723
|
+
vimSimDefault: false,
|
|
1724
|
+
category: "display",
|
|
1725
|
+
type: "boolean",
|
|
1726
|
+
differsFromVim: false
|
|
1727
|
+
},
|
|
1728
|
+
// Indentation options
|
|
1729
|
+
tabstop: {
|
|
1730
|
+
description: "Number of spaces that a <Tab> in the file counts for",
|
|
1731
|
+
vimDefault: 8,
|
|
1732
|
+
vimSimDefault: 4,
|
|
1733
|
+
category: "indentation",
|
|
1734
|
+
type: "number",
|
|
1735
|
+
differsFromVim: true
|
|
1736
|
+
},
|
|
1737
|
+
shiftwidth: {
|
|
1738
|
+
description: "Number of spaces to use for each step of (auto)indent",
|
|
1739
|
+
vimDefault: 8,
|
|
1740
|
+
vimSimDefault: 2,
|
|
1741
|
+
category: "indentation",
|
|
1742
|
+
type: "number",
|
|
1743
|
+
differsFromVim: true
|
|
1744
|
+
},
|
|
1745
|
+
expandtab: {
|
|
1746
|
+
description: "Use spaces instead of tabs when pressing <Tab>",
|
|
1747
|
+
vimDefault: false,
|
|
1748
|
+
vimSimDefault: true,
|
|
1749
|
+
category: "indentation",
|
|
1750
|
+
type: "boolean",
|
|
1751
|
+
differsFromVim: true
|
|
1752
|
+
},
|
|
1753
|
+
autoindent: {
|
|
1754
|
+
description: "Copy indent from current line when starting a new line",
|
|
1755
|
+
vimDefault: false,
|
|
1756
|
+
vimSimDefault: true,
|
|
1757
|
+
category: "indentation",
|
|
1758
|
+
type: "boolean",
|
|
1759
|
+
differsFromVim: true
|
|
1760
|
+
},
|
|
1761
|
+
smartindent: {
|
|
1762
|
+
description: "Do smart autoindenting when starting a new line",
|
|
1763
|
+
vimDefault: false,
|
|
1764
|
+
vimSimDefault: false,
|
|
1765
|
+
category: "indentation",
|
|
1766
|
+
type: "boolean",
|
|
1767
|
+
differsFromVim: false
|
|
1768
|
+
},
|
|
1769
|
+
// Search options
|
|
1770
|
+
ignorecase: {
|
|
1771
|
+
description: "Ignore case in search patterns",
|
|
1772
|
+
vimDefault: false,
|
|
1773
|
+
vimSimDefault: false,
|
|
1774
|
+
category: "search",
|
|
1775
|
+
type: "boolean",
|
|
1776
|
+
differsFromVim: false
|
|
1777
|
+
},
|
|
1778
|
+
smartcase: {
|
|
1779
|
+
description: "Override ignorecase if search pattern contains uppercase",
|
|
1780
|
+
vimDefault: false,
|
|
1781
|
+
vimSimDefault: false,
|
|
1782
|
+
category: "search",
|
|
1783
|
+
type: "boolean",
|
|
1784
|
+
differsFromVim: false
|
|
1785
|
+
},
|
|
1786
|
+
hlsearch: {
|
|
1787
|
+
description: "Highlight all matches for the search pattern",
|
|
1788
|
+
vimDefault: false,
|
|
1789
|
+
vimSimDefault: true,
|
|
1790
|
+
category: "search",
|
|
1791
|
+
type: "boolean",
|
|
1792
|
+
differsFromVim: true
|
|
1793
|
+
},
|
|
1794
|
+
incsearch: {
|
|
1795
|
+
description: "Show match for partly typed search pattern",
|
|
1796
|
+
vimDefault: false,
|
|
1797
|
+
vimSimDefault: true,
|
|
1798
|
+
category: "search",
|
|
1799
|
+
type: "boolean",
|
|
1800
|
+
differsFromVim: true
|
|
1801
|
+
},
|
|
1802
|
+
wrapscan: {
|
|
1803
|
+
description: "Searches wrap around the end of the file",
|
|
1804
|
+
vimDefault: true,
|
|
1805
|
+
vimSimDefault: true,
|
|
1806
|
+
category: "search",
|
|
1807
|
+
type: "boolean",
|
|
1808
|
+
differsFromVim: false
|
|
1809
|
+
},
|
|
1810
|
+
// Motion behavior options
|
|
1811
|
+
whichwrap: {
|
|
1812
|
+
description: "Keys that wrap to prev/next line (b=<BS>, s=<Space>, h=h, l=l, <=<Left>, >=<Right>, [=<Left> in insert, ]=<Right> in insert)",
|
|
1813
|
+
vimDefault: "b,s",
|
|
1814
|
+
vimSimDefault: "h,l",
|
|
1815
|
+
category: "motion",
|
|
1816
|
+
type: "string",
|
|
1817
|
+
differsFromVim: true,
|
|
1818
|
+
validValues: ["b", "s", "h", "l", "<", ">", "[", "]", "~"]
|
|
1819
|
+
},
|
|
1820
|
+
startofline: {
|
|
1821
|
+
description: "Move cursor to first non-blank when changing lines with G, gg, d, etc.",
|
|
1822
|
+
vimDefault: true,
|
|
1823
|
+
vimSimDefault: true,
|
|
1824
|
+
category: "motion",
|
|
1825
|
+
type: "boolean",
|
|
1826
|
+
differsFromVim: false
|
|
1827
|
+
},
|
|
1828
|
+
virtualedit: {
|
|
1829
|
+
description: "Allow cursor positioning where there is no character (block, insert, all, onemore)",
|
|
1830
|
+
vimDefault: "",
|
|
1831
|
+
vimSimDefault: "",
|
|
1832
|
+
category: "motion",
|
|
1833
|
+
type: "string",
|
|
1834
|
+
differsFromVim: false,
|
|
1835
|
+
validValues: ["block", "insert", "all", "onemore", ""]
|
|
1836
|
+
},
|
|
1837
|
+
// Editing options
|
|
1838
|
+
undolevels: {
|
|
1839
|
+
description: "Maximum number of changes that can be undone",
|
|
1840
|
+
vimDefault: 1e3,
|
|
1841
|
+
vimSimDefault: 1e3,
|
|
1842
|
+
category: "editing",
|
|
1843
|
+
type: "number",
|
|
1844
|
+
differsFromVim: false
|
|
1845
|
+
},
|
|
1846
|
+
clipboard: {
|
|
1847
|
+
description: "Use system clipboard for unnamed register",
|
|
1848
|
+
vimDefault: "",
|
|
1849
|
+
vimSimDefault: "",
|
|
1850
|
+
category: "editing",
|
|
1851
|
+
type: "string",
|
|
1852
|
+
differsFromVim: false,
|
|
1853
|
+
validValues: ["unnamed", "unnamedplus", ""]
|
|
1854
|
+
}
|
|
1855
|
+
};
|
|
1856
|
+
|
|
1550
1857
|
// src/core/state.ts
|
|
1551
1858
|
var State = class {
|
|
1552
|
-
constructor(buffer, cursor, selection, mode, commandLine = "", desiredColumn = null, viewport = new VimViewport(), visualAnchor = null, lastVisualSelection = null, recordingRegister = null, lastMacroRegister = null, foldManager = new FoldManager(), markManager = new MarkManager(), jumpListManager = new JumpListManager(), fileSystem = new FileSystemManager(), windowManager = new WindowManager(), lastSearch = null, spellChecker = new SpellChecker(), completionManager = new CompletionManager(), undoTree = null, lastCommand = null) {
|
|
1859
|
+
constructor(buffer, cursor, selection, mode, commandLine = "", desiredColumn = null, viewport = new VimViewport(), visualAnchor = null, lastVisualSelection = null, recordingRegister = null, lastMacroRegister = null, foldManager = new FoldManager(), markManager = new MarkManager(), jumpListManager = new JumpListManager(), fileSystem = new FileSystemManager(), windowManager = new WindowManager(), lastSearch = null, spellChecker = new SpellChecker(), completionManager = new CompletionManager(), undoTree = null, lastCommand = null, configManager = null) {
|
|
1553
1860
|
this.buffer = buffer;
|
|
1554
1861
|
this.cursor = cursor;
|
|
1555
1862
|
this.selection = selection;
|
|
@@ -1571,6 +1878,7 @@ var State = class {
|
|
|
1571
1878
|
this.completionManager = completionManager;
|
|
1572
1879
|
this.undoTree = undoTree;
|
|
1573
1880
|
this.lastCommand = lastCommand;
|
|
1881
|
+
this.configManager = configManager;
|
|
1574
1882
|
}
|
|
1575
1883
|
};
|
|
1576
1884
|
function createEmptyState() {
|
|
@@ -1596,8 +1904,10 @@ function createEmptyState() {
|
|
|
1596
1904
|
new CompletionManager(),
|
|
1597
1905
|
null,
|
|
1598
1906
|
// undoTree will be initialized separately
|
|
1599
|
-
null
|
|
1907
|
+
null,
|
|
1600
1908
|
// lastCommand
|
|
1909
|
+
new ConfigManager()
|
|
1910
|
+
// configManager with default settings
|
|
1601
1911
|
);
|
|
1602
1912
|
return state;
|
|
1603
1913
|
}
|
|
@@ -1737,6 +2047,29 @@ function handleInsertArrowDown(state) {
|
|
|
1737
2047
|
}
|
|
1738
2048
|
return state;
|
|
1739
2049
|
}
|
|
2050
|
+
function handleInsertDelete(state) {
|
|
2051
|
+
const lines = state.buffer.content.split("\n");
|
|
2052
|
+
const currentLine2 = lines[state.cursor.line] ?? "";
|
|
2053
|
+
if (state.cursor.column < currentLine2.length) {
|
|
2054
|
+
const newLine = currentLine2.slice(0, state.cursor.column) + currentLine2.slice(state.cursor.column + 1);
|
|
2055
|
+
lines[state.cursor.line] = newLine;
|
|
2056
|
+
return {
|
|
2057
|
+
...state,
|
|
2058
|
+
buffer: new Buffer(lines.join("\n")),
|
|
2059
|
+
desiredColumn: null
|
|
2060
|
+
};
|
|
2061
|
+
} else if (state.cursor.line < lines.length - 1) {
|
|
2062
|
+
const nextLine = lines[state.cursor.line + 1] ?? "";
|
|
2063
|
+
lines[state.cursor.line] = currentLine2 + nextLine;
|
|
2064
|
+
lines.splice(state.cursor.line + 1, 1);
|
|
2065
|
+
return {
|
|
2066
|
+
...state,
|
|
2067
|
+
buffer: new Buffer(lines.join("\n")),
|
|
2068
|
+
desiredColumn: null
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
return state;
|
|
2072
|
+
}
|
|
1740
2073
|
function handleInsertCharacter(state, char) {
|
|
1741
2074
|
const lines = state.buffer.content.split("\n");
|
|
1742
2075
|
const currentLine2 = lines[state.cursor.line] ?? "";
|
|
@@ -2139,7 +2472,17 @@ function withBufferContent(state, content) {
|
|
|
2139
2472
|
state.visualAnchor,
|
|
2140
2473
|
state.lastVisualSelection,
|
|
2141
2474
|
state.recordingRegister,
|
|
2142
|
-
state.lastMacroRegister
|
|
2475
|
+
state.lastMacroRegister,
|
|
2476
|
+
state.foldManager,
|
|
2477
|
+
state.markManager,
|
|
2478
|
+
state.jumpListManager,
|
|
2479
|
+
state.fileSystem,
|
|
2480
|
+
state.windowManager,
|
|
2481
|
+
state.lastSearch,
|
|
2482
|
+
state.spellChecker,
|
|
2483
|
+
state.completionManager,
|
|
2484
|
+
state.undoTree,
|
|
2485
|
+
state.lastCommand
|
|
2143
2486
|
);
|
|
2144
2487
|
}
|
|
2145
2488
|
function withCursor(state, cursor, preserveDesiredColumn = true) {
|
|
@@ -2154,7 +2497,17 @@ function withCursor(state, cursor, preserveDesiredColumn = true) {
|
|
|
2154
2497
|
state.visualAnchor,
|
|
2155
2498
|
state.lastVisualSelection,
|
|
2156
2499
|
state.recordingRegister,
|
|
2157
|
-
state.lastMacroRegister
|
|
2500
|
+
state.lastMacroRegister,
|
|
2501
|
+
state.foldManager,
|
|
2502
|
+
state.markManager,
|
|
2503
|
+
state.jumpListManager,
|
|
2504
|
+
state.fileSystem,
|
|
2505
|
+
state.windowManager,
|
|
2506
|
+
state.lastSearch,
|
|
2507
|
+
state.spellChecker,
|
|
2508
|
+
state.completionManager,
|
|
2509
|
+
state.undoTree,
|
|
2510
|
+
state.lastCommand
|
|
2158
2511
|
);
|
|
2159
2512
|
}
|
|
2160
2513
|
function withCursorVertical(state, cursor, targetColumn) {
|
|
@@ -2166,11 +2519,22 @@ function withCursorVertical(state, cursor, targetColumn) {
|
|
|
2166
2519
|
state.mode,
|
|
2167
2520
|
state.commandLine,
|
|
2168
2521
|
desiredCol,
|
|
2522
|
+
// Maintain desiredColumn for vertical movements
|
|
2169
2523
|
state.viewport,
|
|
2170
2524
|
state.visualAnchor,
|
|
2171
2525
|
state.lastVisualSelection,
|
|
2172
2526
|
state.recordingRegister,
|
|
2173
|
-
state.lastMacroRegister
|
|
2527
|
+
state.lastMacroRegister,
|
|
2528
|
+
state.foldManager,
|
|
2529
|
+
state.markManager,
|
|
2530
|
+
state.jumpListManager,
|
|
2531
|
+
state.fileSystem,
|
|
2532
|
+
state.windowManager,
|
|
2533
|
+
state.lastSearch,
|
|
2534
|
+
state.spellChecker,
|
|
2535
|
+
state.completionManager,
|
|
2536
|
+
state.undoTree,
|
|
2537
|
+
state.lastCommand
|
|
2174
2538
|
);
|
|
2175
2539
|
}
|
|
2176
2540
|
function withCursorHorizontal(state, cursor) {
|
|
@@ -2181,11 +2545,22 @@ function withCursorHorizontal(state, cursor) {
|
|
|
2181
2545
|
state.mode,
|
|
2182
2546
|
state.commandLine,
|
|
2183
2547
|
null,
|
|
2548
|
+
// Reset desiredColumn for horizontal movements
|
|
2184
2549
|
state.viewport,
|
|
2185
2550
|
state.visualAnchor,
|
|
2186
2551
|
state.lastVisualSelection,
|
|
2187
2552
|
state.recordingRegister,
|
|
2188
|
-
state.lastMacroRegister
|
|
2553
|
+
state.lastMacroRegister,
|
|
2554
|
+
state.foldManager,
|
|
2555
|
+
state.markManager,
|
|
2556
|
+
state.jumpListManager,
|
|
2557
|
+
state.fileSystem,
|
|
2558
|
+
state.windowManager,
|
|
2559
|
+
state.lastSearch,
|
|
2560
|
+
state.spellChecker,
|
|
2561
|
+
state.completionManager,
|
|
2562
|
+
state.undoTree,
|
|
2563
|
+
state.lastCommand
|
|
2189
2564
|
);
|
|
2190
2565
|
}
|
|
2191
2566
|
function withViewport(state, topLine) {
|
|
@@ -2471,18 +2846,24 @@ var B = class extends Motion {
|
|
|
2471
2846
|
};
|
|
2472
2847
|
|
|
2473
2848
|
// src/motions/basic.ts
|
|
2849
|
+
function canWrap(state, key) {
|
|
2850
|
+
const whichwrap = state.configManager?.get("whichwrap") ?? "h,l";
|
|
2851
|
+
const allowed = whichwrap.split(",").map((s) => s.trim());
|
|
2852
|
+
return allowed.includes(key);
|
|
2853
|
+
}
|
|
2474
2854
|
var h = class extends Motion {
|
|
2475
2855
|
key = "h";
|
|
2476
2856
|
execute(state, context) {
|
|
2477
2857
|
let count = getCount(context);
|
|
2478
2858
|
let line = state.cursor.line;
|
|
2479
2859
|
let col = state.cursor.column;
|
|
2860
|
+
const allowWrap = canWrap(state, "h");
|
|
2480
2861
|
while (count > 0) {
|
|
2481
2862
|
if (col > 0) {
|
|
2482
2863
|
const moveAmount = Math.min(col, count);
|
|
2483
2864
|
col -= moveAmount;
|
|
2484
2865
|
count -= moveAmount;
|
|
2485
|
-
} else if (line > 0) {
|
|
2866
|
+
} else if (line > 0 && allowWrap) {
|
|
2486
2867
|
line--;
|
|
2487
2868
|
const prevLine = getLine(state.buffer, line);
|
|
2488
2869
|
col = Math.max(0, prevLine.length - 1);
|
|
@@ -2494,11 +2875,53 @@ var h = class extends Motion {
|
|
|
2494
2875
|
return withCursorHorizontal(state, new Cursor(line, col));
|
|
2495
2876
|
}
|
|
2496
2877
|
};
|
|
2497
|
-
var Backspace = class extends
|
|
2878
|
+
var Backspace = class extends Motion {
|
|
2498
2879
|
key = "Backspace";
|
|
2880
|
+
execute(state, context) {
|
|
2881
|
+
let count = getCount(context);
|
|
2882
|
+
let line = state.cursor.line;
|
|
2883
|
+
let col = state.cursor.column;
|
|
2884
|
+
const allowWrap = canWrap(state, "b");
|
|
2885
|
+
while (count > 0) {
|
|
2886
|
+
if (col > 0) {
|
|
2887
|
+
const moveAmount = Math.min(col, count);
|
|
2888
|
+
col -= moveAmount;
|
|
2889
|
+
count -= moveAmount;
|
|
2890
|
+
} else if (line > 0 && allowWrap) {
|
|
2891
|
+
line--;
|
|
2892
|
+
const prevLine = getLine(state.buffer, line);
|
|
2893
|
+
col = Math.max(0, prevLine.length - 1);
|
|
2894
|
+
count--;
|
|
2895
|
+
} else {
|
|
2896
|
+
break;
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
return withCursorHorizontal(state, new Cursor(line, col));
|
|
2900
|
+
}
|
|
2499
2901
|
};
|
|
2500
|
-
var ArrowLeft = class extends
|
|
2902
|
+
var ArrowLeft = class extends Motion {
|
|
2501
2903
|
key = "ArrowLeft";
|
|
2904
|
+
execute(state, context) {
|
|
2905
|
+
let count = getCount(context);
|
|
2906
|
+
let line = state.cursor.line;
|
|
2907
|
+
let col = state.cursor.column;
|
|
2908
|
+
const allowWrap = canWrap(state, "<");
|
|
2909
|
+
while (count > 0) {
|
|
2910
|
+
if (col > 0) {
|
|
2911
|
+
const moveAmount = Math.min(col, count);
|
|
2912
|
+
col -= moveAmount;
|
|
2913
|
+
count -= moveAmount;
|
|
2914
|
+
} else if (line > 0 && allowWrap) {
|
|
2915
|
+
line--;
|
|
2916
|
+
const prevLine = getLine(state.buffer, line);
|
|
2917
|
+
col = Math.max(0, prevLine.length - 1);
|
|
2918
|
+
count--;
|
|
2919
|
+
} else {
|
|
2920
|
+
break;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
return withCursorHorizontal(state, new Cursor(line, col));
|
|
2924
|
+
}
|
|
2502
2925
|
};
|
|
2503
2926
|
var l = class extends Motion {
|
|
2504
2927
|
key = "l";
|
|
@@ -2506,7 +2929,7 @@ var l = class extends Motion {
|
|
|
2506
2929
|
let count = getCount(context);
|
|
2507
2930
|
let line = state.cursor.line;
|
|
2508
2931
|
let col = state.cursor.column;
|
|
2509
|
-
const
|
|
2932
|
+
const allowWrap = canWrap(state, "l");
|
|
2510
2933
|
while (count > 0) {
|
|
2511
2934
|
const currentLine2 = getLine(state.buffer, line);
|
|
2512
2935
|
const maxCol = Math.max(0, currentLine2.length - 1);
|
|
@@ -2514,7 +2937,7 @@ var l = class extends Motion {
|
|
|
2514
2937
|
const moveAmount = Math.min(maxCol - col, count);
|
|
2515
2938
|
col += moveAmount;
|
|
2516
2939
|
count -= moveAmount;
|
|
2517
|
-
} else if (line < lastLine(state)) {
|
|
2940
|
+
} else if (line < lastLine(state) && allowWrap) {
|
|
2518
2941
|
line++;
|
|
2519
2942
|
col = 0;
|
|
2520
2943
|
count--;
|
|
@@ -2525,8 +2948,30 @@ var l = class extends Motion {
|
|
|
2525
2948
|
return withCursorHorizontal(state, new Cursor(line, col));
|
|
2526
2949
|
}
|
|
2527
2950
|
};
|
|
2528
|
-
var ArrowRight = class extends
|
|
2951
|
+
var ArrowRight = class extends Motion {
|
|
2529
2952
|
key = "ArrowRight";
|
|
2953
|
+
execute(state, context) {
|
|
2954
|
+
let count = getCount(context);
|
|
2955
|
+
let line = state.cursor.line;
|
|
2956
|
+
let col = state.cursor.column;
|
|
2957
|
+
const allowWrap = canWrap(state, ">");
|
|
2958
|
+
while (count > 0) {
|
|
2959
|
+
const currentLine2 = getLine(state.buffer, line);
|
|
2960
|
+
const maxCol = Math.max(0, currentLine2.length - 1);
|
|
2961
|
+
if (col < maxCol) {
|
|
2962
|
+
const moveAmount = Math.min(maxCol - col, count);
|
|
2963
|
+
col += moveAmount;
|
|
2964
|
+
count -= moveAmount;
|
|
2965
|
+
} else if (line < lastLine(state) && allowWrap) {
|
|
2966
|
+
line++;
|
|
2967
|
+
col = 0;
|
|
2968
|
+
count--;
|
|
2969
|
+
} else {
|
|
2970
|
+
break;
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
return withCursorHorizontal(state, new Cursor(line, col));
|
|
2974
|
+
}
|
|
2530
2975
|
};
|
|
2531
2976
|
var j = class extends Motion {
|
|
2532
2977
|
key = "j";
|
|
@@ -2838,151 +3283,6 @@ var IndentationManager = class {
|
|
|
2838
3283
|
}
|
|
2839
3284
|
};
|
|
2840
3285
|
|
|
2841
|
-
// src/core/config-manager.ts
|
|
2842
|
-
var ConfigManager = class _ConfigManager {
|
|
2843
|
-
config;
|
|
2844
|
-
listeners = /* @__PURE__ */ new Map();
|
|
2845
|
-
constructor(initialConfig) {
|
|
2846
|
-
this.config = {
|
|
2847
|
-
// Display
|
|
2848
|
-
number: false,
|
|
2849
|
-
relativenumber: false,
|
|
2850
|
-
wrap: true,
|
|
2851
|
-
cursorline: false,
|
|
2852
|
-
// Indentation
|
|
2853
|
-
tabstop: 4,
|
|
2854
|
-
shiftwidth: 2,
|
|
2855
|
-
expandtab: true,
|
|
2856
|
-
autoindent: true,
|
|
2857
|
-
smartindent: false,
|
|
2858
|
-
// Search
|
|
2859
|
-
ignorecase: false,
|
|
2860
|
-
smartcase: false,
|
|
2861
|
-
hlsearch: true,
|
|
2862
|
-
incsearch: true,
|
|
2863
|
-
// Editing
|
|
2864
|
-
undolevels: 1e3,
|
|
2865
|
-
clipboard: "",
|
|
2866
|
-
...initialConfig
|
|
2867
|
-
};
|
|
2868
|
-
}
|
|
2869
|
-
/**
|
|
2870
|
-
* Get a config value
|
|
2871
|
-
*/
|
|
2872
|
-
get(key) {
|
|
2873
|
-
return this.config[key];
|
|
2874
|
-
}
|
|
2875
|
-
/**
|
|
2876
|
-
* Set a config value
|
|
2877
|
-
*/
|
|
2878
|
-
set(key, value) {
|
|
2879
|
-
const oldValue = this.config[key];
|
|
2880
|
-
if (oldValue === value) return;
|
|
2881
|
-
this.config[key] = value;
|
|
2882
|
-
this.notifyListeners(key, value);
|
|
2883
|
-
}
|
|
2884
|
-
/**
|
|
2885
|
-
* Set multiple config values at once
|
|
2886
|
-
*/
|
|
2887
|
-
setMultiple(updates) {
|
|
2888
|
-
for (const [key, value] of Object.entries(updates)) {
|
|
2889
|
-
this.set(key, value);
|
|
2890
|
-
}
|
|
2891
|
-
}
|
|
2892
|
-
/**
|
|
2893
|
-
* Get all config values
|
|
2894
|
-
*/
|
|
2895
|
-
getAll() {
|
|
2896
|
-
return { ...this.config };
|
|
2897
|
-
}
|
|
2898
|
-
/**
|
|
2899
|
-
* Reset to default configuration
|
|
2900
|
-
*/
|
|
2901
|
-
reset() {
|
|
2902
|
-
const defaults = new _ConfigManager().getAll();
|
|
2903
|
-
this.setMultiple(defaults);
|
|
2904
|
-
}
|
|
2905
|
-
/**
|
|
2906
|
-
* Toggle a boolean config option
|
|
2907
|
-
*/
|
|
2908
|
-
toggle(key) {
|
|
2909
|
-
const value = this.config[key];
|
|
2910
|
-
if (typeof value === "boolean") {
|
|
2911
|
-
this.set(key, !value);
|
|
2912
|
-
}
|
|
2913
|
-
}
|
|
2914
|
-
/**
|
|
2915
|
-
* Subscribe to config changes
|
|
2916
|
-
* @param key - Config key to watch, or '*' for all changes
|
|
2917
|
-
* @param callback - Function to call when config changes
|
|
2918
|
-
* @returns Unsubscribe function
|
|
2919
|
-
*/
|
|
2920
|
-
onChange(key, callback) {
|
|
2921
|
-
if (!this.listeners.has(key)) {
|
|
2922
|
-
this.listeners.set(key, /* @__PURE__ */ new Set());
|
|
2923
|
-
}
|
|
2924
|
-
this.listeners.get(key).add(callback);
|
|
2925
|
-
return () => {
|
|
2926
|
-
this.listeners.get(key)?.delete(callback);
|
|
2927
|
-
};
|
|
2928
|
-
}
|
|
2929
|
-
/**
|
|
2930
|
-
* Notify all listeners of a config change
|
|
2931
|
-
*/
|
|
2932
|
-
notifyListeners(key, value) {
|
|
2933
|
-
this.listeners.get(key)?.forEach((callback) => callback(key, value));
|
|
2934
|
-
this.listeners.get("*")?.forEach((callback) => callback(key, value));
|
|
2935
|
-
}
|
|
2936
|
-
/**
|
|
2937
|
-
* Parse a Vim set command string (e.g., "number", "nonumber", "tabstop=4")
|
|
2938
|
-
*/
|
|
2939
|
-
parseSetCommand(command) {
|
|
2940
|
-
const noMatch = command.match(/^no(\w+)$/);
|
|
2941
|
-
if (noMatch) {
|
|
2942
|
-
const key2 = noMatch[1];
|
|
2943
|
-
if (key2 in this.config && typeof this.config[key2] === "boolean") {
|
|
2944
|
-
this.set(key2, false);
|
|
2945
|
-
return true;
|
|
2946
|
-
}
|
|
2947
|
-
return false;
|
|
2948
|
-
}
|
|
2949
|
-
const valueMatch = command.match(/^(\w+)=(.+)$/);
|
|
2950
|
-
if (valueMatch) {
|
|
2951
|
-
const key2 = valueMatch[1];
|
|
2952
|
-
const value = valueMatch[2];
|
|
2953
|
-
if (!(key2 in this.config)) return false;
|
|
2954
|
-
const currentValue = this.config[key2];
|
|
2955
|
-
if (typeof currentValue === "number") {
|
|
2956
|
-
const numValue = parseInt(value, 10);
|
|
2957
|
-
if (!isNaN(numValue)) {
|
|
2958
|
-
this.set(key2, numValue);
|
|
2959
|
-
return true;
|
|
2960
|
-
}
|
|
2961
|
-
} else if (typeof currentValue === "string") {
|
|
2962
|
-
this.set(key2, value);
|
|
2963
|
-
return true;
|
|
2964
|
-
}
|
|
2965
|
-
return false;
|
|
2966
|
-
}
|
|
2967
|
-
const key = command;
|
|
2968
|
-
if (key in this.config && typeof this.config[key] === "boolean") {
|
|
2969
|
-
this.set(key, true);
|
|
2970
|
-
return true;
|
|
2971
|
-
}
|
|
2972
|
-
return false;
|
|
2973
|
-
}
|
|
2974
|
-
/**
|
|
2975
|
-
* Get a formatted string representation of a config value
|
|
2976
|
-
*/
|
|
2977
|
-
formatValue(key) {
|
|
2978
|
-
const value = this.config[key];
|
|
2979
|
-
if (typeof value === "boolean") {
|
|
2980
|
-
return value ? key : `no${key}`;
|
|
2981
|
-
}
|
|
2982
|
-
return `${key}=${value}`;
|
|
2983
|
-
}
|
|
2984
|
-
};
|
|
2985
|
-
|
|
2986
3286
|
// src/core/mode-transition.ts
|
|
2987
3287
|
var ModeTransition = class extends Command {
|
|
2988
3288
|
// Optional hook to modify state before mode transition
|
|
@@ -3146,11 +3446,23 @@ var dd = class extends Command {
|
|
|
3146
3446
|
};
|
|
3147
3447
|
var Delete = class extends Operator {
|
|
3148
3448
|
key = "Delete";
|
|
3449
|
+
// Override Operator defaults - Delete doesn't accept motions/text objects
|
|
3450
|
+
acceptsMotion = false;
|
|
3451
|
+
acceptsTextObject = false;
|
|
3149
3452
|
execute(state, context) {
|
|
3150
3453
|
if (state.selection) {
|
|
3151
3454
|
return deleteRangeWithRegister(state, state.selection, context, false);
|
|
3152
3455
|
}
|
|
3153
|
-
|
|
3456
|
+
const count = context.count ?? 1;
|
|
3457
|
+
return deleteRangeWithRegister(
|
|
3458
|
+
state,
|
|
3459
|
+
{
|
|
3460
|
+
start: state.cursor,
|
|
3461
|
+
end: new Cursor(state.cursor.line, state.cursor.column + count)
|
|
3462
|
+
},
|
|
3463
|
+
context,
|
|
3464
|
+
false
|
|
3465
|
+
);
|
|
3154
3466
|
}
|
|
3155
3467
|
};
|
|
3156
3468
|
|
|
@@ -3841,7 +4153,7 @@ var gE = class extends Motion {
|
|
|
3841
4153
|
return repeatCursorMotion(state, context, findPrevWORDEnd);
|
|
3842
4154
|
}
|
|
3843
4155
|
};
|
|
3844
|
-
var
|
|
4156
|
+
var g_ = class extends Motion {
|
|
3845
4157
|
key = "g_";
|
|
3846
4158
|
inclusive = true;
|
|
3847
4159
|
// g_ is inclusive
|
|
@@ -3855,7 +4167,7 @@ var LastNonBlank = class extends Motion {
|
|
|
3855
4167
|
return withCursorHorizontal(state, new Cursor(state.cursor.line, col));
|
|
3856
4168
|
}
|
|
3857
4169
|
};
|
|
3858
|
-
var
|
|
4170
|
+
var gm = class extends Motion {
|
|
3859
4171
|
key = "gm";
|
|
3860
4172
|
execute(state) {
|
|
3861
4173
|
const line = getLine(state.buffer, state.cursor.line);
|
|
@@ -6234,18 +6546,11 @@ var Session = class _Session {
|
|
|
6234
6546
|
}
|
|
6235
6547
|
this.keyBuffer.push(key);
|
|
6236
6548
|
const input = this.keyBuffer.join("");
|
|
6237
|
-
console.log("[DEBUG] handleKey - input:", input, "keyBuffer:", this.keyBuffer);
|
|
6238
6549
|
const result = this.match(input, this.keyBuffer);
|
|
6239
|
-
console.log("[DEBUG] handleKey - match result:", result ? result === "partial" ? "partial" : `complete: ${result.command.key}` : "null");
|
|
6240
6550
|
if (result && result !== "partial" && result.isComplete) {
|
|
6241
6551
|
const stateBefore = this.state;
|
|
6242
6552
|
result.context.registerManager = this.registerManager;
|
|
6243
6553
|
result.context.indentationManager = this.indentationManager;
|
|
6244
|
-
console.log("[DEBUG] Executing command:", result.command.key, "with context:", {
|
|
6245
|
-
count: result.context.count,
|
|
6246
|
-
motion: result.context.motion?.key,
|
|
6247
|
-
char: result.context.char
|
|
6248
|
-
});
|
|
6249
6554
|
this.state = result.command.execute(this.state, result.context);
|
|
6250
6555
|
if ((stateBefore.mode === 2 /* VISUAL */ || stateBefore.mode === 3 /* VISUAL_LINE */ || stateBefore.mode === 4 /* VISUAL_BLOCK */) && this.state.mode === stateBefore.mode && // Still in same visual mode
|
|
6251
6556
|
stateBefore.visualAnchor && (this.state.cursor.line !== stateBefore.cursor.line || this.state.cursor.column !== stateBefore.cursor.column)) {
|
|
@@ -6332,6 +6637,8 @@ var Session = class _Session {
|
|
|
6332
6637
|
this.state = handleInsertEnter(this.state, this.indentationManager);
|
|
6333
6638
|
} else if (key === "Space") {
|
|
6334
6639
|
this.state = handleInsertSpace(this.state);
|
|
6640
|
+
} else if (key === "Delete") {
|
|
6641
|
+
this.state = handleInsertDelete(this.state);
|
|
6335
6642
|
} else if (key === "ArrowLeft") {
|
|
6336
6643
|
this.state = handleInsertArrowLeft(this.state);
|
|
6337
6644
|
} else if (key === "ArrowRight") {
|
|
@@ -6648,8 +6955,8 @@ var Session = class _Session {
|
|
|
6648
6955
|
addMotionAllModes(new MatchPercent());
|
|
6649
6956
|
addMotionAllModes(new ge());
|
|
6650
6957
|
addMotionAllModes(new gE());
|
|
6651
|
-
addMotionAllModes(new
|
|
6652
|
-
addMotionAllModes(new
|
|
6958
|
+
addMotionAllModes(new g_());
|
|
6959
|
+
addMotionAllModes(new gm());
|
|
6653
6960
|
addMotionAllModes(new MiddleOfLine());
|
|
6654
6961
|
addMotionAllModes(new Column());
|
|
6655
6962
|
addMotionAllModes(new Star());
|
|
@@ -6845,6 +7152,7 @@ var PatternRegistry = class {
|
|
|
6845
7152
|
};
|
|
6846
7153
|
export {
|
|
6847
7154
|
Buffer,
|
|
7155
|
+
CONFIG_METADATA,
|
|
6848
7156
|
Change,
|
|
6849
7157
|
Command,
|
|
6850
7158
|
ConfigManager,
|