mirror of
https://github.com/jasonwilliams/vscode-helix.git
synced 2024-10-06 13:17:15 +03:00
g commands are implemented
This commit is contained in:
parent
8ae4f6d73e
commit
e66541133c
@ -1,6 +1,5 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"semi": false,
|
||||
"printWidth": 120,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"arrowParens": "always",
|
||||
|
324
package-lock.json
generated
324
package-lock.json
generated
@ -12,14 +12,14 @@
|
||||
"@types/http-errors": "^1.8.0",
|
||||
"@types/node": "^20.8.9",
|
||||
"@types/vscode": "^1.83.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.42.1",
|
||||
"@typescript-eslint/parser": "^5.42.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
||||
"@typescript-eslint/parser": "^6.10.0",
|
||||
"bumpp": "^8.2.1",
|
||||
"esbuild": "^0.19.5",
|
||||
"eslint": "^8.27.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"esno": "^0.16.3",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier": "^3.0.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"string.prototype.matchall": "^4.0.2",
|
||||
"typescript": "^5.2.2",
|
||||
@ -480,6 +480,30 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/regexpp": {
|
||||
"version": "4.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
|
||||
"integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz",
|
||||
@ -623,9 +647,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
@ -638,9 +662,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/semver": {
|
||||
"version": "7.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
|
||||
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
|
||||
"version": "7.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz",
|
||||
"integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/vscode": {
|
||||
@ -650,31 +674,33 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz",
|
||||
"integrity": "sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz",
|
||||
"integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.42.1",
|
||||
"@typescript-eslint/type-utils": "5.42.1",
|
||||
"@typescript-eslint/utils": "5.42.1",
|
||||
"@eslint-community/regexpp": "^4.5.1",
|
||||
"@typescript-eslint/scope-manager": "6.10.0",
|
||||
"@typescript-eslint/type-utils": "6.10.0",
|
||||
"@typescript-eslint/utils": "6.10.0",
|
||||
"@typescript-eslint/visitor-keys": "6.10.0",
|
||||
"debug": "^4.3.4",
|
||||
"ignore": "^5.2.0",
|
||||
"natural-compare-lite": "^1.4.0",
|
||||
"regexpp": "^3.2.0",
|
||||
"semver": "^7.3.7",
|
||||
"tsutils": "^3.21.0"
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.4",
|
||||
"natural-compare": "^1.4.0",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@typescript-eslint/parser": "^5.0.0",
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
"@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
|
||||
"eslint": "^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
@ -683,9 +709,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
|
||||
"version": "7.3.8",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@ -697,41 +723,27 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/tsutils": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
|
||||
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^1.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.1.tgz",
|
||||
"integrity": "sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz",
|
||||
"integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.42.1",
|
||||
"@typescript-eslint/types": "5.42.1",
|
||||
"@typescript-eslint/typescript-estree": "5.42.1",
|
||||
"@typescript-eslint/scope-manager": "6.10.0",
|
||||
"@typescript-eslint/types": "6.10.0",
|
||||
"@typescript-eslint/typescript-estree": "6.10.0",
|
||||
"@typescript-eslint/visitor-keys": "6.10.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
"eslint": "^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
@ -740,16 +752,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz",
|
||||
"integrity": "sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz",
|
||||
"integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.42.1",
|
||||
"@typescript-eslint/visitor-keys": "5.42.1"
|
||||
"@typescript-eslint/types": "6.10.0",
|
||||
"@typescript-eslint/visitor-keys": "6.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@ -757,25 +769,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz",
|
||||
"integrity": "sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz",
|
||||
"integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "5.42.1",
|
||||
"@typescript-eslint/utils": "5.42.1",
|
||||
"@typescript-eslint/typescript-estree": "6.10.0",
|
||||
"@typescript-eslint/utils": "6.10.0",
|
||||
"debug": "^4.3.4",
|
||||
"tsutils": "^3.21.0"
|
||||
"ts-api-utils": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "*"
|
||||
"eslint": "^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
@ -783,28 +795,13 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils/node_modules/tsutils": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
|
||||
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^1.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.1.tgz",
|
||||
"integrity": "sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz",
|
||||
"integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@ -812,21 +809,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz",
|
||||
"integrity": "sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz",
|
||||
"integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.42.1",
|
||||
"@typescript-eslint/visitor-keys": "5.42.1",
|
||||
"@typescript-eslint/types": "6.10.0",
|
||||
"@typescript-eslint/visitor-keys": "6.10.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.7",
|
||||
"tsutils": "^3.21.0"
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@ -839,9 +836,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
||||
"version": "7.3.8",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@ -853,51 +850,35 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/tsutils": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
|
||||
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^1.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.1.tgz",
|
||||
"integrity": "sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz",
|
||||
"integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@types/semver": "^7.3.12",
|
||||
"@typescript-eslint/scope-manager": "5.42.1",
|
||||
"@typescript-eslint/types": "5.42.1",
|
||||
"@typescript-eslint/typescript-estree": "5.42.1",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0",
|
||||
"semver": "^7.3.7"
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@types/json-schema": "^7.0.12",
|
||||
"@types/semver": "^7.5.0",
|
||||
"@typescript-eslint/scope-manager": "6.10.0",
|
||||
"@typescript-eslint/types": "6.10.0",
|
||||
"@typescript-eslint/typescript-estree": "6.10.0",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
"eslint": "^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils/node_modules/semver": {
|
||||
"version": "7.3.8",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@ -910,16 +891,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.42.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz",
|
||||
"integrity": "sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz",
|
||||
"integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.42.1",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
"@typescript-eslint/types": "6.10.0",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@ -1950,9 +1931,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-prettier": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
|
||||
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
|
||||
"integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"eslint-config-prettier": "bin/cli.js"
|
||||
@ -1961,28 +1942,6 @@
|
||||
"eslint": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope/node_modules/estraverse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-utils": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
||||
@ -2011,12 +1970,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-visitor-keys": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
|
||||
"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/ansi-styles": {
|
||||
@ -2524,6 +2486,12 @@
|
||||
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/graphemer": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
||||
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
@ -2645,9 +2613,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
|
||||
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
@ -3147,12 +3115,6 @@
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/natural-compare-lite": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
|
||||
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.28.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.28.0.tgz",
|
||||
@ -3426,15 +3388,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
||||
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
@ -3962,11 +3924,17 @@
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"dev": true
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
|
||||
"integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16.13.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "3.11.0",
|
||||
|
10
package.json
10
package.json
@ -29,7 +29,7 @@
|
||||
"dist"
|
||||
],
|
||||
"engines": {
|
||||
"vscode": "^1.69.0"
|
||||
"vscode": "^1.80.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onStartupFinished"
|
||||
@ -90,13 +90,13 @@
|
||||
"@types/http-errors": "^1.8.0",
|
||||
"@types/node": "^20.8.9",
|
||||
"@types/vscode": "^1.83.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.42.1",
|
||||
"@typescript-eslint/parser": "^5.42.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
||||
"@typescript-eslint/parser": "^6.10.0",
|
||||
"bumpp": "^8.2.1",
|
||||
"eslint": "^8.27.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"esno": "^0.16.3",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier": "^3.0.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"string.prototype.matchall": "^4.0.2",
|
||||
"typescript": "^5.2.2",
|
||||
|
@ -1,10 +1,6 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { VimState } from './vim_state_types'
|
||||
import { ParseKeysStatus } from './parse_keys_types'
|
||||
import { HelixState } from './helix_state_types';
|
||||
import { ParseKeysStatus } from './parse_keys_types';
|
||||
|
||||
export type Action = (
|
||||
vimState: VimState,
|
||||
keys: string[],
|
||||
editor: vscode.TextEditor,
|
||||
) => ParseKeysStatus
|
||||
export type Action = (vimState: HelixState, keys: string[], editor: vscode.TextEditor) => ParseKeysStatus;
|
||||
|
@ -1,23 +1,23 @@
|
||||
import * as vscode from 'vscode'
|
||||
import { Action } from '../action_types'
|
||||
import * as vscode from 'vscode';
|
||||
import { Action } from '../action_types';
|
||||
import {
|
||||
enterInsertMode,
|
||||
enterOccurrenceMode,
|
||||
enterVisualLineMode,
|
||||
enterVisualMode,
|
||||
setModeCursorStyle,
|
||||
} from '../modes'
|
||||
import { Mode } from '../modes_types'
|
||||
import { parseKeysExact, parseKeysRegex } from '../parse_keys'
|
||||
import * as positionUtils from '../position_utils'
|
||||
import { putAfter } from '../put_utils/put_after'
|
||||
import { putBefore } from '../put_utils/put_before'
|
||||
import { removeTypeSubscription } from '../type_subscription'
|
||||
import { VimState } from '../vim_state_types'
|
||||
import { setVisualLineSelections } from '../visual_line_utils'
|
||||
import { flashYankHighlight } from '../yank_highlight'
|
||||
import KeyMap from './keymaps'
|
||||
import { yank } from './operators'
|
||||
} from '../modes';
|
||||
import { Mode } from '../modes_types';
|
||||
import { parseKeysExact, parseKeysRegex } from '../parse_keys';
|
||||
import * as positionUtils from '../position_utils';
|
||||
import { putAfter } from '../put_utils/put_after';
|
||||
import { putBefore } from '../put_utils/put_before';
|
||||
import { removeTypeSubscription } from '../type_subscription';
|
||||
import { HelixState } from '../helix_state_types';
|
||||
import { setVisualLineSelections } from '../visual_line_utils';
|
||||
import { flashYankHighlight } from '../yank_highlight';
|
||||
import KeyMap from './keymaps';
|
||||
import { yank } from './operators';
|
||||
|
||||
enum Direction {
|
||||
Up,
|
||||
@ -26,126 +26,117 @@ enum Direction {
|
||||
|
||||
/* eslint @typescript-eslint/no-unused-vars: 0 */
|
||||
export const actions: Action[] = [
|
||||
// parseKeysExact([':'], [Mode.Normal], (vimState, editor) => {
|
||||
// vscode.commands.executeCommand('workbench.action.gotoLine')
|
||||
// }),
|
||||
|
||||
// parseKeysExact(['m', 'l'], [Mode.Normal], (vimState, editor) => {
|
||||
// vscode.commands.executeCommand('bookmarks.list')
|
||||
// }),
|
||||
|
||||
// parseKeysExact(['m', 'L'], [Mode.Normal], (vimState, editor) => {
|
||||
// vscode.commands.executeCommand('bookmarks.listFromAllFiles')
|
||||
// }),
|
||||
|
||||
// parseKeysExact(['m', 'i'], [Mode.Normal], (vimState, editor) => {
|
||||
// vscode.commands.executeCommand('bookmarks.jumpToPrevious')
|
||||
// }),
|
||||
|
||||
// parseKeysExact(['m', 'k'], [Mode.Normal], (vimState, editor) => {
|
||||
// vscode.commands.executeCommand('bookmarks.jumpToNext')
|
||||
// }),
|
||||
|
||||
// new space actions
|
||||
parseKeysExact([' ', ' '], [Mode.Normal], (vimState, editor) => {
|
||||
enterOccurrenceMode(vimState)
|
||||
vscode.commands.executeCommand('editor.action.addSelectionToNextFindMatch')
|
||||
enterOccurrenceMode(vimState);
|
||||
vscode.commands.executeCommand('editor.action.addSelectionToNextFindMatch');
|
||||
}),
|
||||
|
||||
parseKeysExact(['p'], [Mode.Occurrence], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('editor.action.addSelectionToPreviousFindMatch')
|
||||
vscode.commands.executeCommand('editor.action.addSelectionToPreviousFindMatch');
|
||||
}),
|
||||
|
||||
parseKeysExact(['n'], [Mode.Occurrence], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('editor.action.addSelectionToNextFindMatch')
|
||||
vscode.commands.executeCommand('editor.action.addSelectionToNextFindMatch');
|
||||
}),
|
||||
|
||||
parseKeysExact(['a'], [Mode.Occurrence], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('editor.action.selectHighlights')
|
||||
vscode.commands.executeCommand('editor.action.selectHighlights');
|
||||
}),
|
||||
|
||||
parseKeysExact([' ', 'z'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('undo')
|
||||
vscode.commands.executeCommand('undo');
|
||||
}),
|
||||
|
||||
parseKeysExact([' ', 'r'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('redo')
|
||||
vscode.commands.executeCommand('redo');
|
||||
}),
|
||||
|
||||
parseKeysExact([' ', 'i'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('extension.helixKeymap.scrollUpHalfPage')
|
||||
vscode.commands.executeCommand('extension.helixKeymap.scrollUpHalfPage');
|
||||
}),
|
||||
|
||||
parseKeysExact([' ', 'k'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('extension.helixKeymap.scrollDownHalfPage')
|
||||
vscode.commands.executeCommand('extension.helixKeymap.scrollDownHalfPage');
|
||||
}),
|
||||
|
||||
// G actions
|
||||
// TODO: Goto last accessed file, Goto last modified file don't have any VSCode equivalent.
|
||||
parseKeysExact(['g', '.'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('workbench.action.navigateToLastEditLocation')
|
||||
vscode.commands.executeCommand('workbench.action.navigateToLastEditLocation');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'e'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorBottom')
|
||||
vscode.commands.executeCommand('cursorBottom');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'g'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorTop')
|
||||
vscode.commands.executeCommand('cursorTop');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'h'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorLineStart')
|
||||
vscode.commands.executeCommand('cursorLineStart');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'l'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorLineEnd')
|
||||
vscode.commands.executeCommand('cursorLineEnd');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 's'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorHome')
|
||||
vscode.commands.executeCommand('cursorHome');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'd'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('editor.action.revealDefinition')
|
||||
vscode.commands.executeCommand('editor.action.revealDefinition');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'y'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('editor.action.goToTypeDefinition')
|
||||
vscode.commands.executeCommand('editor.action.goToTypeDefinition');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'r'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('editor.action.goToReferences')
|
||||
vscode.commands.executeCommand('editor.action.goToReferences');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 't'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorPageUp')
|
||||
vscode.commands.executeCommand('cursorPageUp');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'b'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorPageDown')
|
||||
vscode.commands.executeCommand('cursorPageDown');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'c'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('cursorMove', {
|
||||
to: 'viewPortCenter',
|
||||
})
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'k'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('scrollLineUp')
|
||||
vscode.commands.executeCommand('scrollLineUp');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'j'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('scrollLineDown')
|
||||
vscode.commands.executeCommand('scrollLineDown');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', '.'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('workbench.action.navigateToLastEditLocation')
|
||||
vscode.commands.executeCommand('workbench.action.navigateToLastEditLocation');
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'a'], [Mode.Normal], () => {
|
||||
vscode.commands.executeCommand('workbench.action.quickOpenNavigatePreviousInEditorPicker')
|
||||
parseKeysExact(['g', 'a'], [Mode.Normal], (helixState) => {
|
||||
// VS Code has no concept of "last accessed file" so instead we'll need to keep track of previous text editors
|
||||
const editor = helixState.editorState.previousEditor;
|
||||
if (!editor) return;
|
||||
|
||||
vscode.window.showTextDocument(editor.document);
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'm'], [Mode.Normal], (helixState) => {
|
||||
// VS Code has no concept of "last accessed file" so instead we'll need to keep track of previous text editors
|
||||
const document = helixState.editorState.lastModifiedDocument;
|
||||
if (!document) return;
|
||||
|
||||
vscode.window.showTextDocument(document);
|
||||
}),
|
||||
|
||||
// existing
|
||||
@ -153,100 +144,99 @@ export const actions: Action[] = [
|
||||
[KeyMap.Actions.InsertMode],
|
||||
[Mode.Normal, Mode.Visual, Mode.VisualLine, Mode.Occurrence],
|
||||
(vimState, editor) => {
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
},
|
||||
),
|
||||
|
||||
parseKeysExact([KeyMap.Actions.InsertAtLineStart], [Mode.Normal], (vimState, editor) => {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const character = editor.document.lineAt(
|
||||
selection.active.line,
|
||||
).firstNonWhitespaceCharacterIndex
|
||||
const newPosition = selection.active.with({ character: character })
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
const character = editor.document.lineAt(selection.active.line).firstNonWhitespaceCharacterIndex;
|
||||
const newPosition = selection.active.with({ character: character });
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
}),
|
||||
|
||||
parseKeysExact(['a'], [Mode.Normal], (vimState, editor) => {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const newPosition = positionUtils.right(editor.document, selection.active)
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
const newPosition = positionUtils.right(editor.document, selection.active);
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
}),
|
||||
|
||||
parseKeysExact([KeyMap.Actions.InsertAtLineEnd], [Mode.Normal], (vimState, editor) => {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length
|
||||
const newPosition = selection.active.with({ character: lineLength })
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length;
|
||||
const newPosition = selection.active.with({ character: lineLength });
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
}),
|
||||
|
||||
parseKeysExact(['v'], [Mode.Normal, Mode.VisualLine], (vimState, editor) => {
|
||||
if (vimState.mode === Mode.Normal) {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length;
|
||||
|
||||
if (lineLength === 0) return selection
|
||||
if (lineLength === 0) return selection;
|
||||
|
||||
return new vscode.Selection(
|
||||
selection.active,
|
||||
positionUtils.right(editor.document, selection.active),
|
||||
)
|
||||
})
|
||||
return new vscode.Selection(selection.active, positionUtils.right(editor.document, selection.active));
|
||||
});
|
||||
}
|
||||
|
||||
enterVisualMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
enterVisualMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
}),
|
||||
|
||||
parseKeysExact(['x'], [Mode.Normal, Mode.Visual], (vimState, editor) => {
|
||||
enterVisualLineMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
setVisualLineSelections(editor)
|
||||
enterVisualLineMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
setVisualLineSelections(editor);
|
||||
}),
|
||||
|
||||
parseKeysExact([KeyMap.Actions.NewLineBelow], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('editor.action.insertLineAfter')
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
vscode.commands.executeCommand('editor.action.insertLineAfter');
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
}),
|
||||
|
||||
parseKeysExact([KeyMap.Actions.NewLineAbove], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('editor.action.insertLineBefore')
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
vscode.commands.executeCommand('editor.action.insertLineBefore');
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
}),
|
||||
|
||||
parseKeysExact(['P'], [Mode.Normal, Mode.Visual, Mode.VisualLine], putAfter),
|
||||
parseKeysExact(['p'], [Mode.Normal], putBefore),
|
||||
|
||||
parseKeysExact(['u'], [Mode.Normal, Mode.Visual, Mode.VisualLine], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('undo')
|
||||
vscode.commands.executeCommand('undo');
|
||||
}),
|
||||
|
||||
parseKeysExact(['d', 'd'], [Mode.Normal], (vimState, editor) => {
|
||||
deleteLine(vimState, editor)
|
||||
deleteLine(vimState, editor);
|
||||
}),
|
||||
|
||||
parseKeysExact(['D'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('deleteAllRight')
|
||||
vscode.commands.executeCommand('deleteAllRight');
|
||||
}),
|
||||
|
||||
parseKeysRegex(/(\\d+)g/, /^g$/, [Mode.Normal, Mode.Visual], (helixState, editor, match) => {
|
||||
new vscode.Position(parseInt(match[1]), 0);
|
||||
}),
|
||||
|
||||
// add 1 character swap
|
||||
@ -257,10 +247,10 @@ export const actions: Action[] = [
|
||||
end: s.active.with({
|
||||
character: s.active.character + 1,
|
||||
}),
|
||||
})
|
||||
builder.replace(oneChar, match[1])
|
||||
})
|
||||
})
|
||||
});
|
||||
builder.replace(oneChar, match[1]);
|
||||
});
|
||||
});
|
||||
}),
|
||||
|
||||
// these allow you to the delete n lines above/below
|
||||
@ -270,10 +260,10 @@ export const actions: Action[] = [
|
||||
/^(d|d\d+)$/,
|
||||
[Mode.Normal, Mode.Visual],
|
||||
(vimState, editor, match) => {
|
||||
const lineCount = parseInt(match[1])
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down
|
||||
const lineCount = parseInt(match[1]);
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down;
|
||||
// console.log(`delete ${lineCount} lines down`);
|
||||
deleteLines(vimState, editor, lineCount, direction)
|
||||
deleteLines(vimState, editor, lineCount, direction);
|
||||
},
|
||||
),
|
||||
|
||||
@ -283,14 +273,14 @@ export const actions: Action[] = [
|
||||
/^(c|c\d+)$/,
|
||||
[Mode.Normal, Mode.Visual],
|
||||
(vimState, editor, match) => {
|
||||
const lineCount = parseInt(match[1])
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down
|
||||
const lineCount = parseInt(match[1]);
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down;
|
||||
// console.log(`delete ${lineCount} lines down`);
|
||||
deleteLines(vimState, editor, lineCount, direction)
|
||||
deleteLines(vimState, editor, lineCount, direction);
|
||||
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
},
|
||||
),
|
||||
|
||||
@ -300,10 +290,10 @@ export const actions: Action[] = [
|
||||
/^(s|s\d+)$/,
|
||||
[Mode.Normal, Mode.Visual],
|
||||
(vimState, editor, match) => {
|
||||
const lineCount = parseInt(match[1])
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down
|
||||
const lineCount = parseInt(match[1]);
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down;
|
||||
// console.log(`delete ${lineCount} lines up`);
|
||||
editor.selections = makeMultiLineSelection(vimState, editor, lineCount, direction)
|
||||
editor.selections = makeMultiLineSelection(vimState, editor, lineCount, direction);
|
||||
},
|
||||
),
|
||||
|
||||
@ -313,14 +303,14 @@ export const actions: Action[] = [
|
||||
/^(y|y\d+)$/,
|
||||
[Mode.Normal, Mode.Visual],
|
||||
(vimState, editor, match) => {
|
||||
const lineCount = parseInt(match[1])
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down
|
||||
const lineCount = parseInt(match[1]);
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down;
|
||||
// console.log(`delete ${lineCount} lines up`);
|
||||
const selections = makeMultiLineSelection(vimState, editor, lineCount, direction)
|
||||
const selections = makeMultiLineSelection(vimState, editor, lineCount, direction);
|
||||
|
||||
yank(vimState, editor, selections, true)
|
||||
yank(vimState, editor, selections, true);
|
||||
|
||||
flashYankHighlight(editor, selections)
|
||||
flashYankHighlight(editor, selections);
|
||||
},
|
||||
),
|
||||
|
||||
@ -330,14 +320,14 @@ export const actions: Action[] = [
|
||||
/^(r|r\d+)$/,
|
||||
[Mode.Normal, Mode.Visual],
|
||||
(vimState, editor, match) => {
|
||||
const lineCount = parseInt(match[1])
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down
|
||||
const lineCount = parseInt(match[1]);
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down;
|
||||
// console.log(`delete ${lineCount} lines up`);
|
||||
const selections = makeMultiLineSelection(vimState, editor, lineCount, direction)
|
||||
const selections = makeMultiLineSelection(vimState, editor, lineCount, direction);
|
||||
|
||||
yank(vimState, editor, selections, true)
|
||||
yank(vimState, editor, selections, true);
|
||||
|
||||
deleteLines(vimState, editor, lineCount, direction)
|
||||
deleteLines(vimState, editor, lineCount, direction);
|
||||
},
|
||||
),
|
||||
|
||||
@ -347,18 +337,18 @@ export const actions: Action[] = [
|
||||
/^(q|q\d+)$/,
|
||||
[Mode.Normal, Mode.Visual],
|
||||
(vimState, editor, match) => {
|
||||
const lineCount = parseInt(match[1])
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down
|
||||
const lineCount = parseInt(match[1]);
|
||||
const direction = match[2] == KeyMap.Motions.MoveUp ? Direction.Up : Direction.Down;
|
||||
// console.log(`delete ${lineCount} lines up`);
|
||||
editor.selections = makeMultiLineSelection(vimState, editor, lineCount, direction)
|
||||
vscode.commands.executeCommand('editor.action.copyLinesDownAction')
|
||||
editor.selections = makeMultiLineSelection(vimState, editor, lineCount, direction);
|
||||
vscode.commands.executeCommand('editor.action.copyLinesDownAction');
|
||||
},
|
||||
),
|
||||
|
||||
parseKeysExact(['c', 'c'], [Mode.Normal], (vimState, editor) => {
|
||||
editor.edit((editBuilder) => {
|
||||
editor.selections.forEach((selection) => {
|
||||
const line = editor.document.lineAt(selection.active.line)
|
||||
const line = editor.document.lineAt(selection.active.line);
|
||||
editBuilder.delete(
|
||||
new vscode.Range(
|
||||
selection.active.with({
|
||||
@ -366,63 +356,63 @@ export const actions: Action[] = [
|
||||
}),
|
||||
selection.active.with({ character: line.text.length }),
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
}),
|
||||
|
||||
parseKeysExact(['C'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('deleteAllRight')
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
vscode.commands.executeCommand('deleteAllRight');
|
||||
enterInsertMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
removeTypeSubscription(vimState);
|
||||
}),
|
||||
|
||||
parseKeysExact(['y', 'y'], [Mode.Normal], (vimState, editor) => {
|
||||
yankLine(vimState, editor)
|
||||
yankLine(vimState, editor);
|
||||
|
||||
// Yank highlight
|
||||
const highlightRanges = editor.selections.map((selection) => {
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length;
|
||||
return new vscode.Range(
|
||||
selection.active.with({ character: 0 }),
|
||||
selection.active.with({ character: lineLength }),
|
||||
)
|
||||
})
|
||||
flashYankHighlight(editor, highlightRanges)
|
||||
);
|
||||
});
|
||||
flashYankHighlight(editor, highlightRanges);
|
||||
}),
|
||||
|
||||
parseKeysExact(['Y'], [Mode.Normal], (vimState, editor) => {
|
||||
yankToEndOfLine(vimState, editor)
|
||||
yankToEndOfLine(vimState, editor);
|
||||
|
||||
// Yank highlight
|
||||
const highlightRanges = editor.selections.map((selection) => {
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length
|
||||
return new vscode.Range(selection.active, selection.active.with({ character: lineLength }))
|
||||
})
|
||||
flashYankHighlight(editor, highlightRanges)
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length;
|
||||
return new vscode.Range(selection.active, selection.active.with({ character: lineLength }));
|
||||
});
|
||||
flashYankHighlight(editor, highlightRanges);
|
||||
}),
|
||||
|
||||
parseKeysExact(['q', 'q'], [Mode.Normal, Mode.Visual], () => {
|
||||
vscode.commands.executeCommand('editor.action.copyLinesDownAction')
|
||||
vscode.commands.executeCommand('editor.action.copyLinesDownAction');
|
||||
}),
|
||||
|
||||
parseKeysExact(['Q', 'Q'], [Mode.Normal, Mode.Visual], () => {
|
||||
vscode.commands.executeCommand('editor.action.copyLinesUpAction')
|
||||
vscode.commands.executeCommand('editor.action.copyLinesUpAction');
|
||||
}),
|
||||
|
||||
parseKeysExact(['r', 'r'], [Mode.Normal], (vimState, editor) => {
|
||||
yankLine(vimState, editor)
|
||||
deleteLine(vimState, editor)
|
||||
yankLine(vimState, editor);
|
||||
deleteLine(vimState, editor);
|
||||
}),
|
||||
|
||||
parseKeysExact(['R'], [Mode.Normal], (vimState, editor) => {
|
||||
yankToEndOfLine(vimState, editor)
|
||||
vscode.commands.executeCommand('deleteAllRight')
|
||||
yankToEndOfLine(vimState, editor);
|
||||
vscode.commands.executeCommand('deleteAllRight');
|
||||
}),
|
||||
|
||||
parseKeysExact(['s', 's'], [Mode.Normal], (vimState, editor) => {
|
||||
@ -430,23 +420,20 @@ export const actions: Action[] = [
|
||||
return new vscode.Selection(
|
||||
selection.active.with({ character: 0 }),
|
||||
positionUtils.lineEnd(editor.document, selection.active),
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
enterVisualLineMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
enterVisualLineMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
}),
|
||||
|
||||
parseKeysExact(['S'], [Mode.Normal], (vimState, editor) => {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
return new vscode.Selection(
|
||||
selection.active,
|
||||
positionUtils.lineEnd(editor.document, selection.active),
|
||||
)
|
||||
})
|
||||
return new vscode.Selection(selection.active, positionUtils.lineEnd(editor.document, selection.active));
|
||||
});
|
||||
|
||||
enterVisualMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
enterVisualMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
}),
|
||||
|
||||
// parseKeysExact(['h'], [Mode.Normal], (vimState, editor) => {
|
||||
@ -454,92 +441,92 @@ export const actions: Action[] = [
|
||||
// }),
|
||||
|
||||
parseKeysExact(['n'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('deleteRight')
|
||||
vscode.commands.executeCommand('deleteRight');
|
||||
}),
|
||||
|
||||
parseKeysExact(['z', KeyMap.Motions.MoveUp], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('revealLine', {
|
||||
lineNumber: editor.selection.active.line,
|
||||
at: 'top',
|
||||
})
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['z', 'z'], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('revealLine', {
|
||||
lineNumber: editor.selection.active.line,
|
||||
at: 'center',
|
||||
})
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['z', KeyMap.Motions.MoveDown], [Mode.Normal], (vimState, editor) => {
|
||||
vscode.commands.executeCommand('revealLine', {
|
||||
lineNumber: editor.selection.active.line,
|
||||
at: 'bottom',
|
||||
})
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact([';'], [Mode.Normal], (vimState, editor) => {
|
||||
vimState.semicolonAction(vimState, editor)
|
||||
vimState.semicolonAction(vimState, editor);
|
||||
}),
|
||||
|
||||
parseKeysExact([','], [Mode.Normal], (vimState, editor) => {
|
||||
vimState.commaAction(vimState, editor)
|
||||
vimState.commaAction(vimState, editor);
|
||||
}),
|
||||
]
|
||||
];
|
||||
|
||||
function makeMultiLineSelection(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
lineCount: number,
|
||||
direction: Direction,
|
||||
): vscode.Selection[] {
|
||||
return editor.selections.map((selection) => {
|
||||
if (direction == Direction.Up) {
|
||||
const endLine = selection.active.line - lineCount + 1
|
||||
const startPos = positionUtils.lineEnd(editor.document, selection.active)
|
||||
const endPos = endLine >= 0 ? new vscode.Position(endLine, 0) : new vscode.Position(0, 0)
|
||||
return new vscode.Selection(startPos, endPos)
|
||||
const endLine = selection.active.line - lineCount + 1;
|
||||
const startPos = positionUtils.lineEnd(editor.document, selection.active);
|
||||
const endPos = endLine >= 0 ? new vscode.Position(endLine, 0) : new vscode.Position(0, 0);
|
||||
return new vscode.Selection(startPos, endPos);
|
||||
} else {
|
||||
const endLine = selection.active.line + lineCount - 1
|
||||
const startPos = new vscode.Position(selection.active.line, 0)
|
||||
const endLine = selection.active.line + lineCount - 1;
|
||||
const startPos = new vscode.Position(selection.active.line, 0);
|
||||
const endPos =
|
||||
endLine < editor.document.lineCount
|
||||
? new vscode.Position(endLine, editor.document.lineAt(endLine).text.length)
|
||||
: positionUtils.lastChar(editor.document)
|
||||
: positionUtils.lastChar(editor.document);
|
||||
|
||||
return new vscode.Selection(startPos, endPos)
|
||||
return new vscode.Selection(startPos, endPos);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function deleteLines(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
lineCount: number,
|
||||
direction: Direction = Direction.Down,
|
||||
): void {
|
||||
const selections = editor.selections.map((selection) => {
|
||||
if (direction == Direction.Up) {
|
||||
const endLine = selection.active.line - lineCount
|
||||
const endLine = selection.active.line - lineCount;
|
||||
if (endLine >= 0) {
|
||||
const startPos = positionUtils.lineEnd(editor.document, selection.active)
|
||||
const endPos = new vscode.Position(endLine, editor.document.lineAt(endLine).text.length)
|
||||
return new vscode.Selection(startPos, endPos)
|
||||
const startPos = positionUtils.lineEnd(editor.document, selection.active);
|
||||
const endPos = new vscode.Position(endLine, editor.document.lineAt(endLine).text.length);
|
||||
return new vscode.Selection(startPos, endPos);
|
||||
} else {
|
||||
const startPos =
|
||||
selection.active.line + 1 <= editor.document.lineCount
|
||||
? new vscode.Position(selection.active.line + 1, 0)
|
||||
: positionUtils.lineEnd(editor.document, selection.active)
|
||||
: positionUtils.lineEnd(editor.document, selection.active);
|
||||
|
||||
const endPos = new vscode.Position(0, 0)
|
||||
return new vscode.Selection(startPos, endPos)
|
||||
const endPos = new vscode.Position(0, 0);
|
||||
return new vscode.Selection(startPos, endPos);
|
||||
}
|
||||
} else {
|
||||
const endLine = selection.active.line + lineCount
|
||||
const endLine = selection.active.line + lineCount;
|
||||
if (endLine <= editor.document.lineCount - 1) {
|
||||
const startPos = new vscode.Position(selection.active.line, 0)
|
||||
const endPos = new vscode.Position(endLine, 0)
|
||||
return new vscode.Selection(startPos, endPos)
|
||||
const startPos = new vscode.Position(selection.active.line, 0);
|
||||
const endPos = new vscode.Position(endLine, 0);
|
||||
return new vscode.Selection(startPos, endPos);
|
||||
} else {
|
||||
const startPos =
|
||||
selection.active.line - 1 >= 0
|
||||
@ -547,53 +534,45 @@ function deleteLines(
|
||||
selection.active.line - 1,
|
||||
editor.document.lineAt(selection.active.line - 1).text.length,
|
||||
)
|
||||
: new vscode.Position(selection.active.line, 0)
|
||||
: new vscode.Position(selection.active.line, 0);
|
||||
|
||||
const endPos = positionUtils.lastChar(editor.document)
|
||||
return new vscode.Selection(startPos, endPos)
|
||||
const endPos = positionUtils.lastChar(editor.document);
|
||||
return new vscode.Selection(startPos, endPos);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
editor
|
||||
.edit((builder) => {
|
||||
selections.forEach((sel) => builder.replace(sel, ''))
|
||||
selections.forEach((sel) => builder.replace(sel, ''));
|
||||
})
|
||||
.then(() => {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const character = editor.document.lineAt(
|
||||
selection.active.line,
|
||||
).firstNonWhitespaceCharacterIndex
|
||||
const newPosition = selection.active.with({ character: character })
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
})
|
||||
const character = editor.document.lineAt(selection.active.line).firstNonWhitespaceCharacterIndex;
|
||||
const newPosition = selection.active.with({ character: character });
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteLine(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
direction: Direction = Direction.Down,
|
||||
): void {
|
||||
deleteLines(vimState, editor, 1, direction)
|
||||
function deleteLine(vimState: HelixState, editor: vscode.TextEditor, direction: Direction = Direction.Down): void {
|
||||
deleteLines(vimState, editor, 1, direction);
|
||||
}
|
||||
|
||||
function yankLine(vimState: VimState, editor: vscode.TextEditor): void {
|
||||
function yankLine(vimState: HelixState, editor: vscode.TextEditor): void {
|
||||
vimState.registers = {
|
||||
contentsList: editor.selections.map((selection) => {
|
||||
return editor.document.lineAt(selection.active.line).text
|
||||
return editor.document.lineAt(selection.active.line).text;
|
||||
}),
|
||||
linewise: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function yankToEndOfLine(vimState: VimState, editor: vscode.TextEditor): void {
|
||||
function yankToEndOfLine(vimState: HelixState, editor: vscode.TextEditor): void {
|
||||
vimState.registers = {
|
||||
contentsList: editor.selections.map((selection) => {
|
||||
return editor.document
|
||||
.lineAt(selection.active.line)
|
||||
.text.substring(selection.active.character)
|
||||
return editor.document.lineAt(selection.active.line).text.substring(selection.active.character);
|
||||
}),
|
||||
linewise: false,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,44 +1,44 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { Mode } from '../modes_types'
|
||||
import { Action } from '../action_types'
|
||||
import { parseKeysExact, parseKeysRegex } from '../parse_keys'
|
||||
import { Mode } from '../modes_types';
|
||||
import { Action } from '../action_types';
|
||||
import { parseKeysExact, parseKeysRegex } from '../parse_keys';
|
||||
import {
|
||||
vscodeToVimVisualSelection,
|
||||
vimToVscodeVisualLineSelection,
|
||||
vimToVscodeVisualSelection,
|
||||
vscodeToVimVisualLineSelection,
|
||||
} from '../selection_utils'
|
||||
import * as positionUtils from '../position_utils'
|
||||
import { VimState } from '../vim_state_types'
|
||||
import { wordRanges, whitespaceWordRanges } from '../word_utils'
|
||||
import { searchForward, searchBackward } from '../search_utils'
|
||||
import { paragraphForward, paragraphBackward } from '../paragraph_utils'
|
||||
import { setVisualLineSelections } from '../visual_line_utils'
|
||||
import { setVisualSelections } from '../visual_utils'
|
||||
import KeyMap from './keymaps'
|
||||
} from '../selection_utils';
|
||||
import * as positionUtils from '../position_utils';
|
||||
import { HelixState } from '../helix_state_types';
|
||||
import { wordRanges, whitespaceWordRanges } from '../word_utils';
|
||||
import { searchForward, searchBackward } from '../search_utils';
|
||||
import { paragraphForward, paragraphBackward } from '../paragraph_utils';
|
||||
import { setVisualLineSelections } from '../visual_line_utils';
|
||||
import { setVisualSelections } from '../visual_utils';
|
||||
import KeyMap from './keymaps';
|
||||
|
||||
export const motions: Action[] = [
|
||||
parseKeysExact([KeyMap.Motions.MoveRight], [Mode.Normal, Mode.Visual], (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
return positionUtils.rightNormal(document, position)
|
||||
})
|
||||
return positionUtils.rightNormal(document, position);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact([KeyMap.Motions.MoveLeft], [Mode.Normal, Mode.Visual], (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ position }) => {
|
||||
return positionUtils.left(position)
|
||||
})
|
||||
return positionUtils.left(position);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact([KeyMap.Motions.MoveUp], [Mode.Normal], (_vimState, _editor) => {
|
||||
vscode.commands.executeCommand('cursorMove', {
|
||||
to: 'up',
|
||||
by: 'wrappedLine',
|
||||
})
|
||||
});
|
||||
}),
|
||||
parseKeysExact([KeyMap.Motions.MoveUp], [Mode.Visual], (vimState, editor) => {
|
||||
const originalSelections = editor.selections
|
||||
const originalSelections = editor.selections;
|
||||
|
||||
vscode.commands
|
||||
.executeCommand('cursorMove', {
|
||||
@ -47,25 +47,23 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualSelections(editor, originalSelections)
|
||||
})
|
||||
setVisualSelections(editor, originalSelections);
|
||||
});
|
||||
}),
|
||||
parseKeysExact([KeyMap.Motions.MoveUp], [Mode.VisualLine], (vimState, editor) => {
|
||||
vscode.commands
|
||||
.executeCommand('cursorMove', { to: 'up', by: 'line', select: true })
|
||||
.then(() => {
|
||||
setVisualLineSelections(editor)
|
||||
})
|
||||
vscode.commands.executeCommand('cursorMove', { to: 'up', by: 'line', select: true }).then(() => {
|
||||
setVisualLineSelections(editor);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact([KeyMap.Motions.MoveDown], [Mode.Normal], (_vimState, _editor) => {
|
||||
vscode.commands.executeCommand('cursorMove', {
|
||||
to: 'down',
|
||||
by: 'wrappedLine',
|
||||
})
|
||||
});
|
||||
}),
|
||||
parseKeysExact([KeyMap.Motions.MoveDown], [Mode.Visual], (vimState, editor) => {
|
||||
const originalSelections = editor.selections
|
||||
const originalSelections = editor.selections;
|
||||
|
||||
vscode.commands
|
||||
.executeCommand('cursorMove', {
|
||||
@ -74,134 +72,108 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualSelections(editor, originalSelections)
|
||||
})
|
||||
setVisualSelections(editor, originalSelections);
|
||||
});
|
||||
}),
|
||||
parseKeysExact([KeyMap.Motions.MoveDown], [Mode.VisualLine], (vimState, editor) => {
|
||||
vscode.commands
|
||||
.executeCommand('cursorMove', { to: 'down', by: 'line', select: true })
|
||||
.then(() => {
|
||||
setVisualLineSelections(editor)
|
||||
})
|
||||
vscode.commands.executeCommand('cursorMove', { to: 'down', by: 'line', select: true }).then(() => {
|
||||
setVisualLineSelections(editor);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['w'], [Mode.Normal, Mode.Visual], createWordForwardHandler(wordRanges)),
|
||||
parseKeysExact(['W'], [Mode.Normal, Mode.Visual], createWordForwardHandler(whitespaceWordRanges)),
|
||||
|
||||
parseKeysExact(['b'], [Mode.Normal, Mode.Visual], createWordBackwardHandler(wordRanges)),
|
||||
parseKeysExact(
|
||||
['B'],
|
||||
[Mode.Normal, Mode.Visual],
|
||||
createWordBackwardHandler(whitespaceWordRanges),
|
||||
),
|
||||
parseKeysExact(['B'], [Mode.Normal, Mode.Visual], createWordBackwardHandler(whitespaceWordRanges)),
|
||||
|
||||
parseKeysExact(['e'], [Mode.Normal, Mode.Visual], createWordEndHandler(wordRanges)),
|
||||
parseKeysExact(['E'], [Mode.Normal, Mode.Visual], createWordEndHandler(whitespaceWordRanges)),
|
||||
|
||||
parseKeysRegex(/^f(..)$/, /^(f|f.)$/, [Mode.Normal, Mode.Visual], (vimState, editor, match) => {
|
||||
findForward(vimState, editor, match)
|
||||
findForward(vimState, editor, match);
|
||||
|
||||
vimState.semicolonAction = (innerVimState, innerEditor) => {
|
||||
findForward(innerVimState, innerEditor, match)
|
||||
}
|
||||
findForward(innerVimState, innerEditor, match);
|
||||
};
|
||||
|
||||
vimState.commaAction = (innerVimState, innerEditor) => {
|
||||
findBackward(innerVimState, innerEditor, match)
|
||||
}
|
||||
findBackward(innerVimState, innerEditor, match);
|
||||
};
|
||||
}),
|
||||
|
||||
parseKeysRegex(/^F(..)$/, /^(F|F.)$/, [Mode.Normal, Mode.Visual], (vimState, editor, match) => {
|
||||
findBackward(vimState, editor, match)
|
||||
findBackward(vimState, editor, match);
|
||||
|
||||
vimState.semicolonAction = (innerVimState, innerEditor) => {
|
||||
findBackward(innerVimState, innerEditor, match)
|
||||
}
|
||||
findBackward(innerVimState, innerEditor, match);
|
||||
};
|
||||
|
||||
vimState.commaAction = (innerVimState, innerEditor) => {
|
||||
findForward(innerVimState, innerEditor, match)
|
||||
}
|
||||
findForward(innerVimState, innerEditor, match);
|
||||
};
|
||||
}),
|
||||
|
||||
parseKeysRegex(/^t(.)$/, /^t$/, [Mode.Normal, Mode.Visual], (vimState, editor, match) => {
|
||||
tillForward(vimState, editor, match)
|
||||
tillForward(vimState, editor, match);
|
||||
|
||||
vimState.semicolonAction = (innerVimState, innerEditor) => {
|
||||
tillForward(innerVimState, innerEditor, match)
|
||||
}
|
||||
tillForward(innerVimState, innerEditor, match);
|
||||
};
|
||||
|
||||
vimState.commaAction = (innerVimState, innerEditor) => {
|
||||
tillBackward(innerVimState, innerEditor, match)
|
||||
}
|
||||
tillBackward(innerVimState, innerEditor, match);
|
||||
};
|
||||
}),
|
||||
|
||||
parseKeysRegex(/^T(.)$/, /^T$/, [Mode.Normal, Mode.Visual], (vimState, editor, match) => {
|
||||
tillBackward(vimState, editor, match)
|
||||
tillBackward(vimState, editor, match);
|
||||
|
||||
vimState.semicolonAction = (innerVimState, innerEditor) => {
|
||||
tillBackward(innerVimState, innerEditor, match)
|
||||
}
|
||||
tillBackward(innerVimState, innerEditor, match);
|
||||
};
|
||||
|
||||
vimState.commaAction = (innerVimState, innerEditor) => {
|
||||
tillForward(innerVimState, innerEditor, match)
|
||||
}
|
||||
}),
|
||||
|
||||
parseKeysExact(['g', 'g'], [Mode.Normal, Mode.Visual, Mode.VisualLine], (vimState, editor) => {
|
||||
execMotion(vimState, editor, () => {
|
||||
return new vscode.Position(0, 0)
|
||||
})
|
||||
}),
|
||||
|
||||
parseKeysExact(['G'], [Mode.Normal, Mode.Visual, Mode.VisualLine], (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document }) => {
|
||||
return new vscode.Position(document.lineCount - 1, 0)
|
||||
})
|
||||
tillForward(innerVimState, innerEditor, match);
|
||||
};
|
||||
}),
|
||||
|
||||
parseKeysExact(['}'], [Mode.Normal, Mode.Visual, Mode.VisualLine], (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
return new vscode.Position(paragraphForward(document, position.line), 0)
|
||||
})
|
||||
return new vscode.Position(paragraphForward(document, position.line), 0);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['{'], [Mode.Normal, Mode.Visual, Mode.VisualLine], (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
return new vscode.Position(paragraphBackward(document, position.line), 0)
|
||||
})
|
||||
return new vscode.Position(paragraphBackward(document, position.line), 0);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(
|
||||
[KeyMap.Motions.MoveLineEnd],
|
||||
[Mode.Normal, Mode.Visual, Mode.VisualLine],
|
||||
(vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
const lineLength = document.lineAt(position.line).text.length
|
||||
return position.with({ character: Math.max(lineLength - 1, 0) })
|
||||
})
|
||||
},
|
||||
),
|
||||
parseKeysExact([KeyMap.Motions.MoveLineEnd], [Mode.Normal, Mode.Visual, Mode.VisualLine], (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
const lineLength = document.lineAt(position.line).text.length;
|
||||
return position.with({ character: Math.max(lineLength - 1, 0) });
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(
|
||||
[KeyMap.Motions.MoveLineStart],
|
||||
[Mode.Normal, Mode.Visual, Mode.VisualLine],
|
||||
(vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
const line = document.lineAt(position.line)
|
||||
return position.with({
|
||||
character: line.firstNonWhitespaceCharacterIndex,
|
||||
})
|
||||
})
|
||||
},
|
||||
),
|
||||
parseKeysExact([KeyMap.Motions.MoveLineStart], [Mode.Normal, Mode.Visual, Mode.VisualLine], (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
const line = document.lineAt(position.line);
|
||||
return position.with({
|
||||
character: line.firstNonWhitespaceCharacterIndex,
|
||||
});
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['H'], [Mode.Normal], (_vimState, _editor) => {
|
||||
vscode.commands.executeCommand('cursorMove', {
|
||||
to: 'viewPortTop',
|
||||
by: 'line',
|
||||
})
|
||||
});
|
||||
}),
|
||||
parseKeysExact(['H'], [Mode.Visual], (vimState, editor) => {
|
||||
const originalSelections = editor.selections
|
||||
const originalSelections = editor.selections;
|
||||
|
||||
vscode.commands
|
||||
.executeCommand('cursorMove', {
|
||||
@ -210,8 +182,8 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualSelections(editor, originalSelections)
|
||||
})
|
||||
setVisualSelections(editor, originalSelections);
|
||||
});
|
||||
}),
|
||||
parseKeysExact(['H'], [Mode.VisualLine], (vimState, editor) => {
|
||||
vscode.commands
|
||||
@ -221,18 +193,18 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualLineSelections(editor)
|
||||
})
|
||||
setVisualLineSelections(editor);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['M'], [Mode.Normal], (_vimState, _editor) => {
|
||||
vscode.commands.executeCommand('cursorMove', {
|
||||
to: 'viewPortCenter',
|
||||
by: 'line',
|
||||
})
|
||||
});
|
||||
}),
|
||||
parseKeysExact(['M'], [Mode.Visual], (vimState, editor) => {
|
||||
const originalSelections = editor.selections
|
||||
const originalSelections = editor.selections;
|
||||
|
||||
vscode.commands
|
||||
.executeCommand('cursorMove', {
|
||||
@ -241,8 +213,8 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualSelections(editor, originalSelections)
|
||||
})
|
||||
setVisualSelections(editor, originalSelections);
|
||||
});
|
||||
}),
|
||||
parseKeysExact(['M'], [Mode.VisualLine], (vimState, editor) => {
|
||||
vscode.commands
|
||||
@ -252,18 +224,18 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualLineSelections(editor)
|
||||
})
|
||||
setVisualLineSelections(editor);
|
||||
});
|
||||
}),
|
||||
|
||||
parseKeysExact(['L'], [Mode.Normal], (_vimState, _editor) => {
|
||||
vscode.commands.executeCommand('cursorMove', {
|
||||
to: 'viewPortBottom',
|
||||
by: 'line',
|
||||
})
|
||||
});
|
||||
}),
|
||||
parseKeysExact(['L'], [Mode.Visual], (vimState, editor) => {
|
||||
const originalSelections = editor.selections
|
||||
const originalSelections = editor.selections;
|
||||
|
||||
vscode.commands
|
||||
.executeCommand('cursorMove', {
|
||||
@ -272,8 +244,8 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualSelections(editor, originalSelections)
|
||||
})
|
||||
setVisualSelections(editor, originalSelections);
|
||||
});
|
||||
}),
|
||||
parseKeysExact(['L'], [Mode.VisualLine], (vimState, editor) => {
|
||||
vscode.commands
|
||||
@ -283,28 +255,28 @@ export const motions: Action[] = [
|
||||
select: true,
|
||||
})
|
||||
.then(() => {
|
||||
setVisualLineSelections(editor)
|
||||
})
|
||||
setVisualLineSelections(editor);
|
||||
});
|
||||
}),
|
||||
]
|
||||
];
|
||||
|
||||
type MotionArgs = {
|
||||
document: vscode.TextDocument
|
||||
position: vscode.Position
|
||||
selectionIndex: number
|
||||
vimState: VimState
|
||||
}
|
||||
document: vscode.TextDocument;
|
||||
position: vscode.Position;
|
||||
selectionIndex: number;
|
||||
vimState: HelixState;
|
||||
};
|
||||
|
||||
type RegexMotionArgs = {
|
||||
document: vscode.TextDocument
|
||||
position: vscode.Position
|
||||
selectionIndex: number
|
||||
vimState: VimState
|
||||
match: RegExpMatchArray
|
||||
}
|
||||
document: vscode.TextDocument;
|
||||
position: vscode.Position;
|
||||
selectionIndex: number;
|
||||
vimState: HelixState;
|
||||
match: RegExpMatchArray;
|
||||
};
|
||||
|
||||
function execRegexMotion(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
match: RegExpMatchArray,
|
||||
regexMotion: (args: RegexMotionArgs) => vscode.Position,
|
||||
@ -313,16 +285,12 @@ function execRegexMotion(
|
||||
return regexMotion({
|
||||
...motionArgs,
|
||||
match: match,
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function execMotion(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
motion: (args: MotionArgs) => vscode.Position,
|
||||
) {
|
||||
const document = editor.document
|
||||
function execMotion(vimState: HelixState, editor: vscode.TextEditor, motion: (args: MotionArgs) => vscode.Position) {
|
||||
const document = editor.document;
|
||||
|
||||
const newSelections = editor.selections.map((selection, i) => {
|
||||
if (vimState.mode === Mode.Normal) {
|
||||
@ -331,184 +299,159 @@ function execMotion(
|
||||
position: selection.active,
|
||||
selectionIndex: i,
|
||||
vimState: vimState,
|
||||
})
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
});
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
} else if (vimState.mode === Mode.Visual) {
|
||||
const vimSelection = vscodeToVimVisualSelection(document, selection)
|
||||
const vimSelection = vscodeToVimVisualSelection(document, selection);
|
||||
const motionPosition = motion({
|
||||
document: document,
|
||||
position: vimSelection.active,
|
||||
selectionIndex: i,
|
||||
vimState: vimState,
|
||||
})
|
||||
});
|
||||
|
||||
return vimToVscodeVisualSelection(
|
||||
document,
|
||||
new vscode.Selection(vimSelection.anchor, motionPosition),
|
||||
)
|
||||
return vimToVscodeVisualSelection(document, new vscode.Selection(vimSelection.anchor, motionPosition));
|
||||
} else if (vimState.mode === Mode.VisualLine) {
|
||||
const vimSelection = vscodeToVimVisualLineSelection(document, selection)
|
||||
const vimSelection = vscodeToVimVisualLineSelection(document, selection);
|
||||
const motionPosition = motion({
|
||||
document: document,
|
||||
position: vimSelection.active,
|
||||
selectionIndex: i,
|
||||
vimState: vimState,
|
||||
})
|
||||
});
|
||||
|
||||
return vimToVscodeVisualLineSelection(
|
||||
document,
|
||||
new vscode.Selection(vimSelection.anchor, motionPosition),
|
||||
)
|
||||
return vimToVscodeVisualLineSelection(document, new vscode.Selection(vimSelection.anchor, motionPosition));
|
||||
} else {
|
||||
return selection
|
||||
return selection;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
editor.selections = newSelections
|
||||
editor.selections = newSelections;
|
||||
|
||||
editor.revealRange(
|
||||
new vscode.Range(newSelections[0].active, newSelections[0].active),
|
||||
vscode.TextEditorRevealType.InCenterIfOutsideViewport,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function findForward(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
outerMatch: RegExpMatchArray,
|
||||
): void {
|
||||
function findForward(vimState: HelixState, editor: vscode.TextEditor, outerMatch: RegExpMatchArray): void {
|
||||
execRegexMotion(vimState, editor, outerMatch, ({ document, position, match }) => {
|
||||
const fromPosition = position.with({ character: position.character + 1 })
|
||||
const result = searchForward(document, match[1], fromPosition)
|
||||
const fromPosition = position.with({ character: position.character + 1 });
|
||||
const result = searchForward(document, match[1], fromPosition);
|
||||
|
||||
if (result) {
|
||||
return result
|
||||
return result;
|
||||
} else {
|
||||
return position
|
||||
return position;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function findBackward(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
outerMatch: RegExpMatchArray,
|
||||
): void {
|
||||
function findBackward(vimState: HelixState, editor: vscode.TextEditor, outerMatch: RegExpMatchArray): void {
|
||||
execRegexMotion(vimState, editor, outerMatch, ({ document, position, match }) => {
|
||||
const fromPosition = positionLeftWrap(document, position)
|
||||
const result = searchBackward(document, match[1], fromPosition)
|
||||
const fromPosition = positionLeftWrap(document, position);
|
||||
const result = searchBackward(document, match[1], fromPosition);
|
||||
|
||||
if (result) {
|
||||
return result
|
||||
return result;
|
||||
} else {
|
||||
return position
|
||||
return position;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function tillForward(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
outerMatch: RegExpMatchArray,
|
||||
): void {
|
||||
function tillForward(vimState: HelixState, editor: vscode.TextEditor, outerMatch: RegExpMatchArray): void {
|
||||
execRegexMotion(vimState, editor, outerMatch, ({ document, position, match }) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const result = lineText.indexOf(match[1], position.character + 1)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const result = lineText.indexOf(match[1], position.character + 1);
|
||||
|
||||
if (result >= 0) {
|
||||
return position.with({ character: result })
|
||||
return position.with({ character: result });
|
||||
} else {
|
||||
return position
|
||||
return position;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function tillBackward(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
outerMatch: RegExpMatchArray,
|
||||
): void {
|
||||
function tillBackward(vimState: HelixState, editor: vscode.TextEditor, outerMatch: RegExpMatchArray): void {
|
||||
execRegexMotion(vimState, editor, outerMatch, ({ document, position, match }) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const result = lineText.lastIndexOf(match[1], position.character - 1)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const result = lineText.lastIndexOf(match[1], position.character - 1);
|
||||
|
||||
if (result >= 0) {
|
||||
return position.with({ character: result })
|
||||
return position.with({ character: result });
|
||||
} else {
|
||||
return position
|
||||
return position;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function positionLeftWrap(
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
): vscode.Position {
|
||||
function positionLeftWrap(document: vscode.TextDocument, position: vscode.Position): vscode.Position {
|
||||
if (position.character === 0) {
|
||||
if (position.line === 0) {
|
||||
return position
|
||||
return position;
|
||||
} else {
|
||||
const lineLength = document.lineAt(position.line - 1).text.length
|
||||
return new vscode.Position(position.line - 1, lineLength)
|
||||
const lineLength = document.lineAt(position.line - 1).text.length;
|
||||
return new vscode.Position(position.line - 1, lineLength);
|
||||
}
|
||||
} else {
|
||||
return position.with({ character: position.character - 1 })
|
||||
return position.with({ character: position.character - 1 });
|
||||
}
|
||||
}
|
||||
|
||||
function createWordForwardHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (vimState: VimState, editor: vscode.TextEditor) => void {
|
||||
): (vimState: HelixState, editor: vscode.TextEditor) => void {
|
||||
return (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
const result = ranges.find((x) => x.start > position.character)
|
||||
const result = ranges.find((x) => x.start > position.character);
|
||||
|
||||
if (result) {
|
||||
return position.with({ character: result.start })
|
||||
return position.with({ character: result.start });
|
||||
} else {
|
||||
return position
|
||||
return position;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function createWordBackwardHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (vimState: VimState, editor: vscode.TextEditor) => void {
|
||||
): (vimState: HelixState, editor: vscode.TextEditor) => void {
|
||||
return (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
const result = ranges.reverse().find((x) => x.start < position.character)
|
||||
const result = ranges.reverse().find((x) => x.start < position.character);
|
||||
|
||||
if (result) {
|
||||
return position.with({ character: result.start })
|
||||
return position.with({ character: result.start });
|
||||
} else {
|
||||
return position
|
||||
return position;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function createWordEndHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (vimState: VimState, editor: vscode.TextEditor) => void {
|
||||
): (vimState: HelixState, editor: vscode.TextEditor) => void {
|
||||
return (vimState, editor) => {
|
||||
execMotion(vimState, editor, ({ document, position }) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
const result = ranges.find((x) => x.end > position.character)
|
||||
const result = ranges.find((x) => x.end > position.character);
|
||||
|
||||
if (result) {
|
||||
return position.with({ character: result.end })
|
||||
return position.with({ character: result.end });
|
||||
} else {
|
||||
return position
|
||||
return position;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -1,27 +1,17 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { createOperatorRangeExactKeys, createOperatorRangeRegex } from '../parse_keys'
|
||||
import { OperatorRange } from '../parse_keys_types'
|
||||
import {
|
||||
searchForward,
|
||||
searchBackward,
|
||||
searchBackwardBracket,
|
||||
searchForwardBracket,
|
||||
} from '../search_utils'
|
||||
import * as positionUtils from '../position_utils'
|
||||
import { wordRanges, whitespaceWordRanges } from '../word_utils'
|
||||
import {
|
||||
paragraphForward,
|
||||
paragraphBackward,
|
||||
paragraphRangeOuter,
|
||||
paragraphRangeInner,
|
||||
} from '../paragraph_utils'
|
||||
import { VimState } from '../vim_state_types'
|
||||
import { quoteRanges, findQuoteRange } from '../quote_utils'
|
||||
import { indentLevelRange } from '../indent_utils'
|
||||
import { blockRange } from '../block_utils'
|
||||
import { getTags } from '../tag_utils'
|
||||
import { arrayFindLast } from '../array_utils'
|
||||
import { createOperatorRangeExactKeys, createOperatorRangeRegex } from '../parse_keys';
|
||||
import { OperatorRange } from '../parse_keys_types';
|
||||
import { searchForward, searchBackward, searchBackwardBracket, searchForwardBracket } from '../search_utils';
|
||||
import * as positionUtils from '../position_utils';
|
||||
import { wordRanges, whitespaceWordRanges } from '../word_utils';
|
||||
import { paragraphForward, paragraphBackward, paragraphRangeOuter, paragraphRangeInner } from '../paragraph_utils';
|
||||
import { HelixState } from '../helix_state_types';
|
||||
import { quoteRanges, findQuoteRange } from '../quote_utils';
|
||||
import { indentLevelRange } from '../indent_utils';
|
||||
import { blockRange } from '../block_utils';
|
||||
import { getTags } from '../tag_utils';
|
||||
import { arrayFindLast } from '../array_utils';
|
||||
// import KeyMap from "./keymap";
|
||||
|
||||
export const operatorRanges: OperatorRange[] = [
|
||||
@ -106,63 +96,60 @@ export const operatorRanges: OperatorRange[] = [
|
||||
createOperatorRangeExactKeys(['a', 'W'], false, createOuterWordHandler(whitespaceWordRanges)),
|
||||
|
||||
createOperatorRangeRegex(/^f(..)$/, /^(f|f.)$/, false, (vimState, document, position, match) => {
|
||||
const fromPosition = position.with({ character: position.character + 1 })
|
||||
const result = searchForward(document, match[1], fromPosition)
|
||||
const fromPosition = position.with({ character: position.character + 1 });
|
||||
const result = searchForward(document, match[1], fromPosition);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(position, result)
|
||||
return new vscode.Range(position, result);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
createOperatorRangeRegex(/^F(..)$/, /^(F|F.)$/, false, (vimState, document, position, match) => {
|
||||
const fromPosition = position.with({ character: position.character - 1 })
|
||||
const result = searchBackward(document, match[1], fromPosition)
|
||||
const fromPosition = position.with({ character: position.character - 1 });
|
||||
const result = searchBackward(document, match[1], fromPosition);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(position, result)
|
||||
return new vscode.Range(position, result);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
createOperatorRangeRegex(/^t(.)$/, /^t$/, false, (vimState, document, position, match) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const result = lineText.indexOf(match[1], position.character + 1)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const result = lineText.indexOf(match[1], position.character + 1);
|
||||
|
||||
if (result >= 0) {
|
||||
return new vscode.Range(position, position.with({ character: result }))
|
||||
return new vscode.Range(position, position.with({ character: result }));
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
createOperatorRangeRegex(/^T(.)$/, /^T$/, false, (vimState, document, position, match) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const result = lineText.lastIndexOf(match[1], position.character - 1)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const result = lineText.lastIndexOf(match[1], position.character - 1);
|
||||
|
||||
if (result >= 0) {
|
||||
const newPosition = positionUtils.right(document, position.with({ character: result }))
|
||||
return new vscode.Range(newPosition, position)
|
||||
const newPosition = positionUtils.right(document, position.with({ character: result }));
|
||||
return new vscode.Range(newPosition, position);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
createOperatorRangeExactKeys(['g', 'g'], true, (vimState, document, position) => {
|
||||
const lineLength = document.lineAt(position.line).text.length
|
||||
const lineLength = document.lineAt(position.line).text.length;
|
||||
|
||||
return new vscode.Range(new vscode.Position(0, 0), position.with({ character: lineLength }))
|
||||
return new vscode.Range(new vscode.Position(0, 0), position.with({ character: lineLength }));
|
||||
}),
|
||||
|
||||
createOperatorRangeExactKeys(['G'], true, (vimState, document, position) => {
|
||||
const lineLength = document.lineAt(document.lineCount - 1).text.length
|
||||
const lineLength = document.lineAt(document.lineCount - 1).text.length;
|
||||
|
||||
return new vscode.Range(
|
||||
position.with({ character: 0 }),
|
||||
new vscode.Position(document.lineCount - 1, lineLength),
|
||||
)
|
||||
return new vscode.Range(position.with({ character: 0 }), new vscode.Position(document.lineCount - 1, lineLength));
|
||||
}),
|
||||
|
||||
// TODO: return undefined?
|
||||
@ -170,7 +157,7 @@ export const operatorRanges: OperatorRange[] = [
|
||||
return new vscode.Range(
|
||||
position.with({ character: 0 }),
|
||||
new vscode.Position(paragraphForward(document, position.line), 0),
|
||||
)
|
||||
);
|
||||
}),
|
||||
|
||||
// TODO: return undefined?
|
||||
@ -178,32 +165,32 @@ export const operatorRanges: OperatorRange[] = [
|
||||
return new vscode.Range(
|
||||
new vscode.Position(paragraphBackward(document, position.line), 0),
|
||||
position.with({ character: 0 }),
|
||||
)
|
||||
);
|
||||
}),
|
||||
|
||||
createOperatorRangeExactKeys(['i', 'p'], true, (vimState, document, position) => {
|
||||
const result = paragraphRangeInner(document, position.line)
|
||||
const result = paragraphRangeInner(document, position.line);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(
|
||||
new vscode.Position(result.start, 0),
|
||||
new vscode.Position(result.end, document.lineAt(result.end).text.length),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
createOperatorRangeExactKeys(['a', 'p'], true, (vimState, document, position) => {
|
||||
const result = paragraphRangeOuter(document, position.line)
|
||||
const result = paragraphRangeOuter(document, position.line);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(
|
||||
new vscode.Position(result.start, 0),
|
||||
new vscode.Position(result.end, document.lineAt(result.end).text.length),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
@ -229,18 +216,16 @@ export const operatorRanges: OperatorRange[] = [
|
||||
createOperatorRangeExactKeys(['a', '<'], false, createOuterBracketHandler('<', '>')),
|
||||
|
||||
createOperatorRangeExactKeys(['i', 't'], false, (vimState, document, position) => {
|
||||
const tags = getTags(document)
|
||||
const tags = getTags(document);
|
||||
|
||||
const closestTag = arrayFindLast(tags, (tag) => {
|
||||
if (tag.closing) {
|
||||
return (
|
||||
position.isAfterOrEqual(tag.opening.start) && position.isBeforeOrEqual(tag.closing.end)
|
||||
)
|
||||
return position.isAfterOrEqual(tag.opening.start) && position.isBeforeOrEqual(tag.closing.end);
|
||||
} else {
|
||||
// Self-closing tags have no inside
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (closestTag) {
|
||||
if (closestTag.closing) {
|
||||
@ -249,27 +234,27 @@ export const operatorRanges: OperatorRange[] = [
|
||||
character: closestTag.opening.end.character + 1,
|
||||
}),
|
||||
closestTag.closing.start,
|
||||
)
|
||||
);
|
||||
} else {
|
||||
throw new Error('We should have already filtered out self-closing tags above')
|
||||
throw new Error('We should have already filtered out self-closing tags above');
|
||||
}
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
createOperatorRangeExactKeys(['a', 't'], false, (vimState, document, position) => {
|
||||
const tags = getTags(document)
|
||||
const tags = getTags(document);
|
||||
|
||||
const closestTag = arrayFindLast(tags, (tag) => {
|
||||
const afterStart = position.isAfterOrEqual(tag.opening.start)
|
||||
const afterStart = position.isAfterOrEqual(tag.opening.start);
|
||||
|
||||
if (tag.closing) {
|
||||
return afterStart && position.isBeforeOrEqual(tag.closing.end)
|
||||
return afterStart && position.isBeforeOrEqual(tag.closing.end);
|
||||
} else {
|
||||
return afterStart && position.isBeforeOrEqual(tag.opening.end)
|
||||
return afterStart && position.isBeforeOrEqual(tag.opening.end);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (closestTag) {
|
||||
if (closestTag.closing) {
|
||||
@ -278,47 +263,43 @@ export const operatorRanges: OperatorRange[] = [
|
||||
closestTag.closing.end.with({
|
||||
character: closestTag.closing.end.character + 1,
|
||||
}),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return new vscode.Range(
|
||||
closestTag.opening.start,
|
||||
closestTag.opening.end.with({
|
||||
character: closestTag.opening.end.character + 1,
|
||||
}),
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
// TODO: return undefined?
|
||||
createOperatorRangeExactKeys(['i', 'i'], true, (vimState, document, position) => {
|
||||
const simpleRange = indentLevelRange(document, position.line)
|
||||
const simpleRange = indentLevelRange(document, position.line);
|
||||
|
||||
return new vscode.Range(
|
||||
new vscode.Position(simpleRange.start, 0),
|
||||
new vscode.Position(simpleRange.end, document.lineAt(simpleRange.end).text.length),
|
||||
)
|
||||
);
|
||||
}),
|
||||
|
||||
createOperatorRangeExactKeys(['a', 'b'], true, (vimState, document, position) => {
|
||||
const range = blockRange(document, position)
|
||||
const range = blockRange(document, position);
|
||||
|
||||
return range
|
||||
return range;
|
||||
}),
|
||||
]
|
||||
];
|
||||
|
||||
function createInnerBracketHandler(
|
||||
openingChar: string,
|
||||
closingChar: string,
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const bracketRange = getBracketRange(document, position, openingChar, closingChar)
|
||||
const bracketRange = getBracketRange(document, position, openingChar, closingChar);
|
||||
|
||||
if (bracketRange) {
|
||||
return new vscode.Range(
|
||||
@ -326,33 +307,26 @@ function createInnerBracketHandler(
|
||||
character: bracketRange.start.character + 1,
|
||||
}),
|
||||
bracketRange.end,
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createOuterBracketHandler(
|
||||
openingChar: string,
|
||||
closingChar: string,
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const bracketRange = getBracketRange(document, position, openingChar, closingChar)
|
||||
const bracketRange = getBracketRange(document, position, openingChar, closingChar);
|
||||
|
||||
if (bracketRange) {
|
||||
return new vscode.Range(
|
||||
bracketRange.start,
|
||||
bracketRange.end.with({ character: bracketRange.end.character + 1 }),
|
||||
)
|
||||
return new vscode.Range(bracketRange.start, bracketRange.end.with({ character: bracketRange.end.character + 1 }));
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getBracketRange(
|
||||
@ -361,205 +335,162 @@ function getBracketRange(
|
||||
openingChar: string,
|
||||
closingChar: string,
|
||||
): vscode.Range | undefined {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const currentChar = lineText[position.character]
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const currentChar = lineText[position.character];
|
||||
|
||||
let start
|
||||
let end
|
||||
let start;
|
||||
let end;
|
||||
if (currentChar === openingChar) {
|
||||
start = position
|
||||
end = searchForwardBracket(
|
||||
document,
|
||||
openingChar,
|
||||
closingChar,
|
||||
positionUtils.rightWrap(document, position),
|
||||
)
|
||||
start = position;
|
||||
end = searchForwardBracket(document, openingChar, closingChar, positionUtils.rightWrap(document, position));
|
||||
} else if (currentChar === closingChar) {
|
||||
start = searchBackwardBracket(
|
||||
document,
|
||||
openingChar,
|
||||
closingChar,
|
||||
positionUtils.leftWrap(document, position),
|
||||
)
|
||||
end = position
|
||||
start = searchBackwardBracket(document, openingChar, closingChar, positionUtils.leftWrap(document, position));
|
||||
end = position;
|
||||
} else {
|
||||
start = searchBackwardBracket(document, openingChar, closingChar, position)
|
||||
end = searchForwardBracket(document, openingChar, closingChar, position)
|
||||
start = searchBackwardBracket(document, openingChar, closingChar, position);
|
||||
end = searchForwardBracket(document, openingChar, closingChar, position);
|
||||
}
|
||||
|
||||
if (start && end) {
|
||||
return new vscode.Range(start, end)
|
||||
return new vscode.Range(start, end);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function createInnerQuoteHandler(
|
||||
quoteChar: string,
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = quoteRanges(quoteChar, lineText)
|
||||
const result = findQuoteRange(ranges, position)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = quoteRanges(quoteChar, lineText);
|
||||
const result = findQuoteRange(ranges, position);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(
|
||||
position.with({ character: result.start + 1 }),
|
||||
position.with({ character: result.end }),
|
||||
)
|
||||
return new vscode.Range(position.with({ character: result.start + 1 }), position.with({ character: result.end }));
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createOuterQuoteHandler(
|
||||
quoteChar: string,
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = quoteRanges(quoteChar, lineText)
|
||||
const result = findQuoteRange(ranges, position)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = quoteRanges(quoteChar, lineText);
|
||||
const result = findQuoteRange(ranges, position);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(
|
||||
position.with({ character: result.start }),
|
||||
position.with({ character: result.end + 1 }),
|
||||
)
|
||||
return new vscode.Range(position.with({ character: result.start }), position.with({ character: result.end + 1 }));
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createWordForwardHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (vimState: VimState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range {
|
||||
return (vimState, document, position) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
const result = ranges.find((x) => x.start > position.character)
|
||||
const result = ranges.find((x) => x.start > position.character);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(position, position.with({ character: result.start }))
|
||||
return new vscode.Range(position, position.with({ character: result.start }));
|
||||
} else {
|
||||
return new vscode.Range(position, position.with({ character: lineText.length }))
|
||||
return new vscode.Range(position, position.with({ character: lineText.length }));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createWordBackwardHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
const result = ranges.reverse().find((x) => x.start < position.character)
|
||||
const result = ranges.reverse().find((x) => x.start < position.character);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(position.with({ character: result.start }), position)
|
||||
return new vscode.Range(position.with({ character: result.start }), position);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createWordEndHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
const result = ranges.find((x) => x.end > position.character)
|
||||
const result = ranges.find((x) => x.end > position.character);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(
|
||||
position,
|
||||
positionUtils.right(document, position.with({ character: result.end })),
|
||||
)
|
||||
return new vscode.Range(position, positionUtils.right(document, position.with({ character: result.end })));
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createInnerWordHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
const result = ranges.find((x) => x.start <= position.character && position.character <= x.end)
|
||||
const result = ranges.find((x) => x.start <= position.character && position.character <= x.end);
|
||||
|
||||
if (result) {
|
||||
return new vscode.Range(
|
||||
position.with({ character: result.start }),
|
||||
positionUtils.right(document, position.with({ character: result.end })),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createOuterWordHandler(
|
||||
wordRangesFunction: (text: string) => { start: number; end: number }[],
|
||||
): (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined {
|
||||
): (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined {
|
||||
return (vimState, document, position) => {
|
||||
const lineText = document.lineAt(position.line).text
|
||||
const ranges = wordRangesFunction(lineText)
|
||||
const lineText = document.lineAt(position.line).text;
|
||||
const ranges = wordRangesFunction(lineText);
|
||||
|
||||
for (let i = 0; i < ranges.length; ++i) {
|
||||
const range = ranges[i]
|
||||
const range = ranges[i];
|
||||
|
||||
if (range.start <= position.character && position.character <= range.end) {
|
||||
if (i < ranges.length - 1) {
|
||||
return new vscode.Range(
|
||||
position.with({ character: range.start }),
|
||||
position.with({ character: ranges[i + 1].start }),
|
||||
)
|
||||
);
|
||||
} else if (i > 0) {
|
||||
return new vscode.Range(
|
||||
positionUtils.right(document, position.with({ character: ranges[i - 1].end })),
|
||||
positionUtils.right(document, position.with({ character: range.end })),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return new vscode.Range(
|
||||
position.with({ character: range.start }),
|
||||
positionUtils.right(document, position.with({ character: range.end })),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
}
|
||||
|
@ -1,202 +1,187 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { Action } from '../action_types'
|
||||
import { operatorRanges } from './operator_ranges'
|
||||
import { parseKeysOperator } from '../parse_keys'
|
||||
import {
|
||||
enterInsertMode,
|
||||
enterNormalMode,
|
||||
setModeCursorStyle,
|
||||
enterVisualLineMode,
|
||||
enterVisualMode,
|
||||
} from '../modes'
|
||||
import { removeTypeSubscription } from '../type_subscription'
|
||||
import { VimState } from '../vim_state_types'
|
||||
import { Mode } from '../modes_types'
|
||||
import { flashYankHighlight } from '../yank_highlight'
|
||||
import { Action } from '../action_types';
|
||||
import { HelixState } from '../helix_state_types';
|
||||
import { enterVisualLineMode, enterVisualMode, setModeCursorStyle } from '../modes';
|
||||
import { Mode } from '../modes_types';
|
||||
import { parseKeysOperator } from '../parse_keys';
|
||||
import { operatorRanges } from './operator_ranges';
|
||||
|
||||
export const operators: Action[] = [
|
||||
parseKeysOperator(['d'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
if (ranges.every((x) => x === undefined)) return
|
||||
// parseKeysOperator(['d'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
// if (ranges.every((x) => x === undefined)) return;
|
||||
|
||||
cursorsToRangesStart(editor, ranges)
|
||||
// cursorsToRangesStart(editor, ranges);
|
||||
|
||||
delete_(editor, ranges, linewise)
|
||||
// delete_(editor, ranges, linewise);
|
||||
|
||||
if (vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
}
|
||||
}),
|
||||
parseKeysOperator(['c'], operatorRanges, (vimState, editor, ranges, _linewise) => {
|
||||
if (ranges.every((x) => x === undefined)) return
|
||||
// if (vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
// enterNormalMode(vimState);
|
||||
// setModeCursorStyle(vimState.mode, editor);
|
||||
// }
|
||||
// }),
|
||||
// parseKeysOperator(['c'], operatorRanges, (vimState, editor, ranges, _linewise) => {
|
||||
// if (ranges.every((x) => x === undefined)) return;
|
||||
|
||||
cursorsToRangesStart(editor, ranges)
|
||||
// cursorsToRangesStart(editor, ranges);
|
||||
|
||||
editor.edit((editBuilder) => {
|
||||
ranges.forEach((range) => {
|
||||
if (!range) return
|
||||
editBuilder.delete(range)
|
||||
})
|
||||
})
|
||||
// editor.edit((editBuilder) => {
|
||||
// ranges.forEach((range) => {
|
||||
// if (!range) return;
|
||||
// editBuilder.delete(range);
|
||||
// });
|
||||
// });
|
||||
|
||||
enterInsertMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
removeTypeSubscription(vimState)
|
||||
}),
|
||||
parseKeysOperator(['y'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
if (ranges.every((x) => x === undefined)) return
|
||||
// enterInsertMode(vimState);
|
||||
// setModeCursorStyle(vimState.mode, editor);
|
||||
// removeTypeSubscription(vimState);
|
||||
// }),
|
||||
// parseKeysOperator(['y'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
// if (ranges.every((x) => x === undefined)) return;
|
||||
|
||||
yank(vimState, editor, ranges, linewise)
|
||||
// yank(vimState, editor, ranges, linewise);
|
||||
|
||||
if (vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
// Move cursor to start of yanked text
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
return new vscode.Selection(selection.start, selection.start)
|
||||
})
|
||||
// if (vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
// // Move cursor to start of yanked text
|
||||
// editor.selections = editor.selections.map((selection) => {
|
||||
// return new vscode.Selection(selection.start, selection.start);
|
||||
// });
|
||||
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
} else {
|
||||
// Yank highlight
|
||||
const highlightRanges: vscode.Range[] = []
|
||||
ranges.forEach((range) => {
|
||||
if (range) {
|
||||
highlightRanges.push(new vscode.Range(range.start, range.end))
|
||||
}
|
||||
})
|
||||
flashYankHighlight(editor, highlightRanges)
|
||||
}
|
||||
}),
|
||||
parseKeysOperator(['r'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
if (ranges.every((x) => x === undefined)) return
|
||||
// enterNormalMode(vimState);
|
||||
// setModeCursorStyle(vimState.mode, editor);
|
||||
// } else {
|
||||
// // Yank highlight
|
||||
// const highlightRanges: vscode.Range[] = [];
|
||||
// ranges.forEach((range) => {
|
||||
// if (range) {
|
||||
// highlightRanges.push(new vscode.Range(range.start, range.end));
|
||||
// }
|
||||
// });
|
||||
// flashYankHighlight(editor, highlightRanges);
|
||||
// }
|
||||
// }),
|
||||
// parseKeysOperator(['r'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
// if (ranges.every((x) => x === undefined)) return;
|
||||
|
||||
cursorsToRangesStart(editor, ranges)
|
||||
// cursorsToRangesStart(editor, ranges);
|
||||
|
||||
yank(vimState, editor, ranges, linewise)
|
||||
delete_(editor, ranges, linewise)
|
||||
// yank(vimState, editor, ranges, linewise);
|
||||
// delete_(editor, ranges, linewise);
|
||||
|
||||
if (vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
}
|
||||
}),
|
||||
parseKeysOperator(['s'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
if (
|
||||
ranges.every((x) => x === undefined) ||
|
||||
vimState.mode === Mode.Visual ||
|
||||
vimState.mode === Mode.VisualLine
|
||||
) {
|
||||
return
|
||||
// if (vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
// enterNormalMode(vimState);
|
||||
// setModeCursorStyle(vimState.mode, editor);
|
||||
// }
|
||||
// }),
|
||||
// Match Mode
|
||||
parseKeysOperator(['m'], operatorRanges, (vimState, editor, ranges, linewise) => {
|
||||
if (ranges.every((x) => x === undefined) || vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.selections = ranges.map((range, i) => {
|
||||
if (range) {
|
||||
const start = range.start
|
||||
const end = range.end
|
||||
return new vscode.Selection(start, end)
|
||||
const start = range.start;
|
||||
const end = range.end;
|
||||
return new vscode.Selection(start, end);
|
||||
} else {
|
||||
return editor.selections[i]
|
||||
return editor.selections[i];
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (linewise) {
|
||||
enterVisualLineMode(vimState)
|
||||
enterVisualLineMode(vimState);
|
||||
} else {
|
||||
enterVisualMode(vimState)
|
||||
enterVisualMode(vimState);
|
||||
}
|
||||
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
}),
|
||||
parseKeysOperator(['q'], operatorRanges, (vimState, editor, ranges, _linewise) => {
|
||||
if (
|
||||
ranges.every((x) => x === undefined) ||
|
||||
vimState.mode === Mode.Visual ||
|
||||
vimState.mode === Mode.VisualLine
|
||||
) {
|
||||
return
|
||||
if (ranges.every((x) => x === undefined) || vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.selections = ranges.map((range, i) => {
|
||||
if (range) {
|
||||
const start = range.start
|
||||
const end = range.end
|
||||
return new vscode.Selection(start, end)
|
||||
const start = range.start;
|
||||
const end = range.end;
|
||||
return new vscode.Selection(start, end);
|
||||
} else {
|
||||
return editor.selections[i]
|
||||
return editor.selections[i];
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
vscode.commands.executeCommand('editor.action.copyLinesDownAction')
|
||||
vscode.commands.executeCommand('editor.action.copyLinesDownAction');
|
||||
}),
|
||||
]
|
||||
];
|
||||
|
||||
function cursorsToRangesStart(editor: vscode.TextEditor, ranges: (vscode.Range | undefined)[]) {
|
||||
function cursorsToRangesStart(
|
||||
editor: vscode.TextEditor,
|
||||
ranges: readonly (vscode.Range | vscode.Selection[] | undefined)[],
|
||||
) {
|
||||
editor.selections = editor.selections.map((selection, i) => {
|
||||
const range = ranges[i]
|
||||
const range = ranges[i];
|
||||
|
||||
if (range) {
|
||||
const newPosition = range.start
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
const newPosition = range.start;
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
} else {
|
||||
return selection
|
||||
return selection;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function delete_(
|
||||
editor: vscode.TextEditor,
|
||||
ranges: (vscode.Range | undefined)[],
|
||||
ranges: (vscode.Range | vscode.Selection[] | undefined)[],
|
||||
linewise: boolean,
|
||||
) {
|
||||
editor
|
||||
.edit((editBuilder) => {
|
||||
ranges.forEach((range) => {
|
||||
if (!range) return
|
||||
if (!range) return;
|
||||
|
||||
let deleteRange = range
|
||||
let deleteRange = range;
|
||||
|
||||
if (linewise) {
|
||||
const start = range.start
|
||||
const end = range.end
|
||||
const start = range.start;
|
||||
const end = range.end;
|
||||
|
||||
if (end.line === editor.document.lineCount - 1) {
|
||||
if (start.line === 0) {
|
||||
deleteRange = new vscode.Range(start.with({ character: 0 }), end)
|
||||
deleteRange = new vscode.Range(start.with({ character: 0 }), end);
|
||||
} else {
|
||||
deleteRange = new vscode.Range(
|
||||
new vscode.Position(
|
||||
start.line - 1,
|
||||
editor.document.lineAt(start.line - 1).text.length,
|
||||
),
|
||||
new vscode.Position(start.line - 1, editor.document.lineAt(start.line - 1).text.length),
|
||||
end,
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
deleteRange = new vscode.Range(range.start, new vscode.Position(end.line + 1, 0))
|
||||
deleteRange = new vscode.Range(range.start, new vscode.Position(end.line + 1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
editBuilder.delete(deleteRange)
|
||||
})
|
||||
editBuilder.delete(deleteRange);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
// For linewise deletions, make sure cursor is at beginning of line
|
||||
editor.selections = editor.selections.map((selection, i) => {
|
||||
const range = ranges[i]
|
||||
const range = ranges[i];
|
||||
|
||||
if (range && linewise) {
|
||||
const newPosition = selection.start.with({ character: 0 })
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
const newPosition = selection.start.with({ character: 0 });
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
} else {
|
||||
return selection
|
||||
return selection;
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function yank(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
ranges: (vscode.Range | undefined)[],
|
||||
linewise: boolean,
|
||||
@ -204,11 +189,11 @@ export function yank(
|
||||
vimState.registers = {
|
||||
contentsList: ranges.map((range, i) => {
|
||||
if (range) {
|
||||
return editor.document.getText(range)
|
||||
return editor.document.getText(range);
|
||||
} else {
|
||||
return vimState.registers.contentsList[i]
|
||||
return vimState.registers.contentsList[i];
|
||||
}
|
||||
}),
|
||||
linewise: linewise,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,53 +1,50 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { VimState } from './vim_state_types'
|
||||
import { enterNormalMode, setModeCursorStyle } from './modes'
|
||||
import { addTypeSubscription } from './type_subscription'
|
||||
import { typeHandler } from './type_handler'
|
||||
import * as positionUtils from './position_utils'
|
||||
import { Mode } from './modes_types'
|
||||
import { HelixState } from './helix_state_types';
|
||||
import { enterNormalMode, setModeCursorStyle } from './modes';
|
||||
import { addTypeSubscription } from './type_subscription';
|
||||
import { typeHandler } from './type_handler';
|
||||
import * as positionUtils from './position_utils';
|
||||
import { Mode } from './modes_types';
|
||||
|
||||
export function escapeHandler(vimState: VimState): void {
|
||||
const editor = vscode.window.activeTextEditor
|
||||
export function escapeHandler(vimState: HelixState): void {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
|
||||
if (!editor) return
|
||||
if (!editor) return;
|
||||
|
||||
if (vimState.mode === Mode.Insert || vimState.mode === Mode.Occurrence) {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const newPosition = positionUtils.left(selection.active)
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
const newPosition = positionUtils.left(selection.active);
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
addTypeSubscription(vimState, typeHandler)
|
||||
enterNormalMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
addTypeSubscription(vimState, typeHandler);
|
||||
} else if (vimState.mode === Mode.Normal) {
|
||||
// Clear multiple cursors
|
||||
if (editor.selections.length > 1) {
|
||||
editor.selections = [editor.selections[0]]
|
||||
editor.selections = [editor.selections[0]];
|
||||
}
|
||||
} else if (vimState.mode === Mode.Visual) {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const newPosition = new vscode.Position(
|
||||
selection.active.line,
|
||||
Math.max(selection.active.character - 1, 0),
|
||||
)
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
const newPosition = new vscode.Position(selection.active.line, Math.max(selection.active.character - 1, 0));
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
enterNormalMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
} else if (vimState.mode === Mode.VisualLine) {
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const newPosition = selection.active.with({
|
||||
character: Math.max(selection.active.character - 1, 0),
|
||||
})
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
});
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
enterNormalMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
}
|
||||
|
||||
vimState.keysPressed = []
|
||||
vimState.keysPressed = [];
|
||||
}
|
||||
|
41
src/eventHandlers.ts
Normal file
41
src/eventHandlers.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import type { TextEditor, TextEditorSelectionChangeEvent, TextDocumentChangeEvent } from 'vscode';
|
||||
import { TextEditorSelectionChangeKind } from 'vscode';
|
||||
import { enterNormalMode, enterVisualMode, setModeCursorStyle } from './modes';
|
||||
import { Mode } from './modes_types';
|
||||
import { HelixState } from './helix_state_types';
|
||||
|
||||
/** Currently this handler is used for implementing "g", "m" (go to last modified file) */
|
||||
export function onDidChangeTextDocument(HelixState: HelixState, e: TextDocumentChangeEvent) {
|
||||
HelixState.editorState.lastModifiedDocument = e.document;
|
||||
}
|
||||
|
||||
/** Currently this handler is used for implementing "g", "a" (go to last accessed file) */
|
||||
export function onDidChangeActiveTextEditor(helixState: HelixState, editor: TextEditor | undefined) {
|
||||
if (!editor) return;
|
||||
|
||||
// The user has switched editors, re-set the editor state so we can go back
|
||||
helixState.editorState.previousEditor = helixState.editorState.activeEditor;
|
||||
helixState.editorState.activeEditor = editor;
|
||||
}
|
||||
|
||||
export function onSelectionChange(helixState: HelixState, e: TextEditorSelectionChangeEvent): void {
|
||||
if (helixState.mode === Mode.Insert) return;
|
||||
|
||||
if (e.selections.every((selection) => selection.isEmpty)) {
|
||||
// It would be nice if we could always go from visual to normal mode when all selections are empty
|
||||
// but visual mode on an empty line will yield an empty selection and there's no good way of
|
||||
// distinguishing that case from the rest. So we only do it for mouse events.
|
||||
if (
|
||||
(helixState.mode === Mode.Visual || helixState.mode === Mode.VisualLine) &&
|
||||
e.kind === TextEditorSelectionChangeKind.Mouse
|
||||
) {
|
||||
enterNormalMode(helixState);
|
||||
setModeCursorStyle(helixState.mode, e.textEditor);
|
||||
}
|
||||
} else {
|
||||
if (helixState.mode === Mode.Normal) {
|
||||
enterVisualMode(helixState);
|
||||
setModeCursorStyle(helixState.mode, e.textEditor);
|
||||
}
|
||||
}
|
||||
}
|
19
src/file_utils.ts
Normal file
19
src/file_utils.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { TextEditor, window } from 'vscode'
|
||||
|
||||
let currentEditor: TextEditor | undefined
|
||||
let previousEditor: TextEditor | undefined
|
||||
|
||||
export const registerActiveTextEditorChangeListener = () => {
|
||||
window.onDidChangeActiveTextEditor((textEditor) => {
|
||||
previousEditor = currentEditor
|
||||
currentEditor = textEditor
|
||||
})
|
||||
}
|
||||
|
||||
export const getPreviousEditor = () => {
|
||||
return previousEditor
|
||||
}
|
||||
|
||||
export const getCurrentEditor = () => {
|
||||
return currentEditor
|
||||
}
|
25
src/helix_state_types.ts
Normal file
25
src/helix_state_types.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { TextEditor, Range } from 'vscode';
|
||||
import type { Disposable, TextDocument } from 'vscode';
|
||||
import type { Mode } from './modes_types';
|
||||
|
||||
/** This represents the global Helix state used across the board */
|
||||
export type HelixState = {
|
||||
typeSubscription: Disposable | undefined;
|
||||
mode: Mode;
|
||||
keysPressed: string[];
|
||||
registers: {
|
||||
contentsList: (string | undefined)[];
|
||||
linewise: boolean;
|
||||
};
|
||||
editorState: {
|
||||
activeEditor: TextEditor | undefined;
|
||||
previousEditor: TextEditor | undefined;
|
||||
lastModifiedDocument: TextDocument | undefined;
|
||||
};
|
||||
semicolonAction: (vimState: HelixState, editor: TextEditor) => void;
|
||||
commaAction: (vimState: HelixState, editor: TextEditor) => void;
|
||||
lastPutRanges: {
|
||||
ranges: (Range | undefined)[];
|
||||
linewise: boolean;
|
||||
};
|
||||
};
|
107
src/index.ts
107
src/index.ts
@ -1,14 +1,15 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { Mode } from './modes_types'
|
||||
import * as scrollCommands from './scroll_commands'
|
||||
import { enterNormalMode, enterVisualMode, setModeCursorStyle } from './modes'
|
||||
import { typeHandler } from './type_handler'
|
||||
import { addTypeSubscription, removeTypeSubscription } from './type_subscription'
|
||||
import { VimState } from './vim_state_types'
|
||||
import { escapeHandler } from './escape_handler'
|
||||
import { Mode } from './modes_types';
|
||||
import * as scrollCommands from './scroll_commands';
|
||||
import { enterNormalMode } from './modes';
|
||||
import { typeHandler } from './type_handler';
|
||||
import { addTypeSubscription, removeTypeSubscription } from './type_subscription';
|
||||
import { HelixState } from './helix_state_types';
|
||||
import { escapeHandler } from './escape_handler';
|
||||
import { onSelectionChange, onDidChangeActiveTextEditor, onDidChangeTextDocument } from './eventHandlers';
|
||||
|
||||
const globalVimState: VimState = {
|
||||
const globalhelixState: HelixState = {
|
||||
typeSubscription: undefined,
|
||||
mode: Mode.Insert,
|
||||
keysPressed: [],
|
||||
@ -16,89 +17,39 @@ const globalVimState: VimState = {
|
||||
contentsList: [],
|
||||
linewise: true,
|
||||
},
|
||||
editorState: {
|
||||
activeEditor: undefined,
|
||||
previousEditor: undefined,
|
||||
lastModifiedDocument: undefined,
|
||||
},
|
||||
semicolonAction: () => undefined,
|
||||
commaAction: () => undefined,
|
||||
lastPutRanges: {
|
||||
ranges: [],
|
||||
linewise: true,
|
||||
},
|
||||
}
|
||||
|
||||
function onSelectionChange(vimState: VimState, e: vscode.TextEditorSelectionChangeEvent): void {
|
||||
if (vimState.mode === Mode.Insert) return
|
||||
|
||||
if (e.selections.every((selection) => selection.isEmpty)) {
|
||||
// It would be nice if we could always go from visual to normal mode when all selections are empty
|
||||
// but visual mode on an empty line will yield an empty selection and there's no good way of
|
||||
// distinguishing that case from the rest. So we only do it for mouse events.
|
||||
if (
|
||||
(vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) &&
|
||||
e.kind === vscode.TextEditorSelectionChangeKind.Mouse
|
||||
) {
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, e.textEditor)
|
||||
}
|
||||
} else {
|
||||
if (vimState.mode === Mode.Normal) {
|
||||
enterVisualMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, e.textEditor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onDidChangeActiveTextEditor(vimState: VimState, editor: vscode.TextEditor | undefined) {
|
||||
if (!editor) return
|
||||
|
||||
if (editor.selections.every((selection) => selection.isEmpty)) {
|
||||
if (vimState.mode === Mode.Visual || vimState.mode === Mode.VisualLine) {
|
||||
enterNormalMode(vimState)
|
||||
}
|
||||
} else {
|
||||
if (vimState.mode === Mode.Normal) {
|
||||
enterVisualMode(vimState)
|
||||
}
|
||||
}
|
||||
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
|
||||
vimState.keysPressed = []
|
||||
}
|
||||
};
|
||||
|
||||
export function activate(context: vscode.ExtensionContext): void {
|
||||
context.subscriptions.push(
|
||||
vscode.window.onDidChangeActiveTextEditor((editor) =>
|
||||
onDidChangeActiveTextEditor(globalVimState, editor),
|
||||
),
|
||||
vscode.window.onDidChangeTextEditorSelection((e) => onSelectionChange(globalVimState, e)),
|
||||
vscode.commands.registerCommand('extension.helixKeymap.escapeKey', () =>
|
||||
escapeHandler(globalVimState),
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
'extension.helixKeymap.scrollDownHalfPage',
|
||||
scrollCommands.scrollDownHalfPage,
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
'extension.helixKeymap.scrollUpHalfPage',
|
||||
scrollCommands.scrollUpHalfPage,
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
'extension.helixKeymap.scrollDownPage',
|
||||
scrollCommands.scrollDownPage,
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
'extension.helixKeymap.scrollUpPage',
|
||||
scrollCommands.scrollUpPage,
|
||||
),
|
||||
)
|
||||
vscode.window.onDidChangeActiveTextEditor((editor) => onDidChangeActiveTextEditor(globalhelixState, editor)),
|
||||
vscode.window.onDidChangeTextEditorSelection((e) => onSelectionChange(globalhelixState, e)),
|
||||
vscode.workspace.onDidChangeTextDocument((e) => onDidChangeTextDocument(globalhelixState, e)),
|
||||
vscode.commands.registerCommand('extension.helixKeymap.escapeKey', () => escapeHandler(globalhelixState)),
|
||||
vscode.commands.registerCommand('extension.helixKeymap.scrollDownHalfPage', scrollCommands.scrollDownHalfPage),
|
||||
vscode.commands.registerCommand('extension.helixKeymap.scrollUpHalfPage', scrollCommands.scrollUpHalfPage),
|
||||
vscode.commands.registerCommand('extension.helixKeymap.scrollDownPage', scrollCommands.scrollDownPage),
|
||||
vscode.commands.registerCommand('extension.helixKeymap.scrollUpPage', scrollCommands.scrollUpPage),
|
||||
);
|
||||
|
||||
enterNormalMode(globalVimState)
|
||||
addTypeSubscription(globalVimState, typeHandler)
|
||||
enterNormalMode(globalhelixState);
|
||||
addTypeSubscription(globalhelixState, typeHandler);
|
||||
|
||||
if (vscode.window.activeTextEditor) {
|
||||
onDidChangeActiveTextEditor(globalVimState, vscode.window.activeTextEditor)
|
||||
onDidChangeActiveTextEditor(globalhelixState, vscode.window.activeTextEditor);
|
||||
}
|
||||
}
|
||||
|
||||
export function deactivate(): void {
|
||||
removeTypeSubscription(globalVimState)
|
||||
removeTypeSubscription(globalhelixState);
|
||||
}
|
||||
|
48
src/modes.ts
48
src/modes.ts
@ -1,31 +1,31 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { Mode } from './modes_types'
|
||||
import { VimState } from './vim_state_types'
|
||||
import { Mode } from './modes_types';
|
||||
import { HelixState } from './helix_state_types';
|
||||
|
||||
export function enterInsertMode(vimState: VimState): void {
|
||||
vimState.mode = Mode.Insert
|
||||
setModeContext('extension.helixKeymap.insertMode')
|
||||
export function enterInsertMode(vimState: HelixState): void {
|
||||
vimState.mode = Mode.Insert;
|
||||
setModeContext('extension.helixKeymap.insertMode');
|
||||
}
|
||||
|
||||
export function enterNormalMode(vimState: VimState): void {
|
||||
vimState.mode = Mode.Normal
|
||||
setModeContext('extension.helixKeymap.normalMode')
|
||||
export function enterNormalMode(vimState: HelixState): void {
|
||||
vimState.mode = Mode.Normal;
|
||||
setModeContext('extension.helixKeymap.normalMode');
|
||||
}
|
||||
|
||||
export function enterVisualMode(vimState: VimState): void {
|
||||
vimState.mode = Mode.Visual
|
||||
setModeContext('extension.helixKeymap.visualMode')
|
||||
export function enterVisualMode(vimState: HelixState): void {
|
||||
vimState.mode = Mode.Visual;
|
||||
setModeContext('extension.helixKeymap.visualMode');
|
||||
}
|
||||
|
||||
export function enterVisualLineMode(vimState: VimState): void {
|
||||
vimState.mode = Mode.VisualLine
|
||||
setModeContext('extension.helixKeymap.visualLineMode')
|
||||
export function enterVisualLineMode(vimState: HelixState): void {
|
||||
vimState.mode = Mode.VisualLine;
|
||||
setModeContext('extension.helixKeymap.visualLineMode');
|
||||
}
|
||||
|
||||
export function enterOccurrenceMode(vimState: VimState): void {
|
||||
vimState.mode = Mode.Occurrence
|
||||
setModeContext('extension.helixKeymap.occurrenceMode')
|
||||
export function enterOccurrenceMode(vimState: HelixState): void {
|
||||
vimState.mode = Mode.Occurrence;
|
||||
setModeContext('extension.helixKeymap.occurrenceMode');
|
||||
}
|
||||
|
||||
function setModeContext(key: string) {
|
||||
@ -35,19 +35,19 @@ function setModeContext(key: string) {
|
||||
'extension.helixKeymap.visualMode',
|
||||
'extension.helixKeymap.visualLineMode',
|
||||
'extension.helixKeymap.occurrenceMode',
|
||||
]
|
||||
];
|
||||
|
||||
modeKeys.forEach((modeKey) => {
|
||||
vscode.commands.executeCommand('setContext', modeKey, key === modeKey)
|
||||
})
|
||||
vscode.commands.executeCommand('setContext', modeKey, key === modeKey);
|
||||
});
|
||||
}
|
||||
|
||||
export function setModeCursorStyle(mode: Mode, editor: vscode.TextEditor): void {
|
||||
if (mode === Mode.Insert || mode === Mode.Occurrence) {
|
||||
editor.options.cursorStyle = vscode.TextEditorCursorStyle.Line
|
||||
editor.options.cursorStyle = vscode.TextEditorCursorStyle.Line;
|
||||
} else if (mode === Mode.Normal) {
|
||||
editor.options.cursorStyle = vscode.TextEditorCursorStyle.Block
|
||||
editor.options.cursorStyle = vscode.TextEditorCursorStyle.Block;
|
||||
} else if (mode === Mode.Visual || mode === Mode.VisualLine) {
|
||||
editor.options.cursorStyle = vscode.TextEditorCursorStyle.Block
|
||||
editor.options.cursorStyle = vscode.TextEditorCursorStyle.Block;
|
||||
}
|
||||
}
|
||||
|
@ -1,126 +1,123 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { VimState } from './vim_state_types'
|
||||
import { Mode } from './modes_types'
|
||||
import { HelixState } from './helix_state_types';
|
||||
import { Mode } from './modes_types';
|
||||
import {
|
||||
ParseKeysStatus,
|
||||
OperatorRange,
|
||||
ParseFailure,
|
||||
ParseOperatorPartSuccess,
|
||||
ParseOperatorRangeSuccess,
|
||||
} from './parse_keys_types'
|
||||
import { Action } from './action_types'
|
||||
} from './parse_keys_types';
|
||||
import { Action } from './action_types';
|
||||
|
||||
export function arrayStartsWith<T>(prefix: T[], xs: T[]) {
|
||||
if (xs.length < prefix.length) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < prefix.length; ++i) {
|
||||
if (prefix[i] !== xs[i]) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
export function arrayEquals<T>(xs: T[], ys: T[]) {
|
||||
if (xs.length !== ys.length) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < xs.length; ++i) {
|
||||
if (xs[i] !== ys[i]) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
export function parseKeysExact(
|
||||
matchKeys: string[],
|
||||
modes: Mode[],
|
||||
action: (vimState: VimState, editor: vscode.TextEditor) => void,
|
||||
action: (vimState: HelixState, editor: vscode.TextEditor) => void,
|
||||
): Action {
|
||||
return (vimState, keys, editor) => {
|
||||
if (modes && modes.indexOf(vimState.mode) < 0) {
|
||||
return ParseKeysStatus.NO
|
||||
return ParseKeysStatus.NO;
|
||||
}
|
||||
|
||||
if (arrayEquals(keys, matchKeys)) {
|
||||
action(vimState, editor)
|
||||
return ParseKeysStatus.YES
|
||||
action(vimState, editor);
|
||||
return ParseKeysStatus.YES;
|
||||
} else if (arrayStartsWith(keys, matchKeys)) {
|
||||
return ParseKeysStatus.MORE_INPUT
|
||||
return ParseKeysStatus.MORE_INPUT;
|
||||
} else {
|
||||
return ParseKeysStatus.NO
|
||||
return ParseKeysStatus.NO;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function parseKeysRegex(
|
||||
doesPattern: RegExp,
|
||||
couldPattern: RegExp,
|
||||
modes: Mode[],
|
||||
action: (vimState: VimState, editor: vscode.TextEditor, match: RegExpMatchArray) => void,
|
||||
action: (vimState: HelixState, editor: vscode.TextEditor, match: RegExpMatchArray) => void,
|
||||
): Action {
|
||||
return (vimState, keys, editor) => {
|
||||
if (modes && modes.indexOf(vimState.mode) < 0) {
|
||||
return ParseKeysStatus.NO
|
||||
return ParseKeysStatus.NO;
|
||||
}
|
||||
|
||||
const keysStr = keys.join('')
|
||||
const doesMatch = keysStr.match(doesPattern)
|
||||
const keysStr = keys.join('');
|
||||
const doesMatch = keysStr.match(doesPattern);
|
||||
|
||||
if (doesMatch) {
|
||||
action(vimState, editor, doesMatch)
|
||||
return ParseKeysStatus.YES
|
||||
action(vimState, editor, doesMatch);
|
||||
return ParseKeysStatus.YES;
|
||||
} else if (keysStr.match(couldPattern)) {
|
||||
return ParseKeysStatus.MORE_INPUT
|
||||
return ParseKeysStatus.MORE_INPUT;
|
||||
} else {
|
||||
return ParseKeysStatus.NO
|
||||
return ParseKeysStatus.NO;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function parseOperatorPart(
|
||||
keys: string[],
|
||||
operatorKeys: string[],
|
||||
): ParseFailure | ParseOperatorPartSuccess {
|
||||
function parseOperatorPart(keys: string[], operatorKeys: string[]): ParseFailure | ParseOperatorPartSuccess {
|
||||
if (arrayStartsWith(operatorKeys, keys)) {
|
||||
return {
|
||||
kind: 'success',
|
||||
rest: keys.slice(operatorKeys.length),
|
||||
}
|
||||
};
|
||||
} else if (arrayStartsWith(keys, operatorKeys)) {
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.MORE_INPUT,
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.NO,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function parseOperatorRangePart(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
keys: string[],
|
||||
editor: vscode.TextEditor,
|
||||
motions: OperatorRange[],
|
||||
): ParseFailure | ParseOperatorRangeSuccess {
|
||||
let could = false
|
||||
let could = false;
|
||||
for (const motion of motions) {
|
||||
const result = motion(vimState, keys, editor)
|
||||
const result = motion(vimState, keys, editor);
|
||||
|
||||
if (result.kind === 'success') {
|
||||
return result
|
||||
return result;
|
||||
} else if (result.status === ParseKeysStatus.MORE_INPUT) {
|
||||
could = true
|
||||
could = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,12 +125,12 @@ function parseOperatorRangePart(
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.MORE_INPUT,
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.NO,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,76 +138,72 @@ export function parseKeysOperator(
|
||||
operatorKeys: string[],
|
||||
motions: OperatorRange[],
|
||||
operator: (
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
ranges: (vscode.Range | undefined)[],
|
||||
ranges: readonly (vscode.Range | vscode.Selection[] | undefined)[],
|
||||
linewise: boolean,
|
||||
) => void,
|
||||
): Action {
|
||||
return (vimState, keys, editor) => {
|
||||
const operatorResult = parseOperatorPart(keys, operatorKeys)
|
||||
const operatorResult = parseOperatorPart(keys, operatorKeys);
|
||||
if (operatorResult.kind === 'failure') {
|
||||
return operatorResult.status
|
||||
return operatorResult.status;
|
||||
}
|
||||
|
||||
let ranges: (vscode.Range | undefined)[]
|
||||
let linewise = true
|
||||
let ranges: readonly (vscode.Range | vscode.Selection[] | undefined)[];
|
||||
let linewise = true;
|
||||
if (vimState.mode === Mode.Normal) {
|
||||
if (operatorResult.rest.length === 0) {
|
||||
return ParseKeysStatus.MORE_INPUT
|
||||
return ParseKeysStatus.MORE_INPUT;
|
||||
}
|
||||
|
||||
const motionResult = parseOperatorRangePart(vimState, operatorResult.rest, editor, motions)
|
||||
const motionResult = parseOperatorRangePart(vimState, operatorResult.rest, editor, motions);
|
||||
if (motionResult.kind === 'failure') {
|
||||
return motionResult.status
|
||||
return motionResult.status;
|
||||
}
|
||||
|
||||
ranges = motionResult.ranges
|
||||
linewise = motionResult.linewise
|
||||
ranges = motionResult.ranges;
|
||||
linewise = motionResult.linewise;
|
||||
} else if (vimState.mode === Mode.VisualLine) {
|
||||
ranges = editor.selections
|
||||
linewise = true
|
||||
ranges = editor.selections;
|
||||
linewise = true;
|
||||
} else {
|
||||
ranges = editor.selections
|
||||
linewise = false
|
||||
ranges = editor.selections;
|
||||
linewise = false;
|
||||
}
|
||||
|
||||
operator(vimState, editor, ranges, linewise)
|
||||
return ParseKeysStatus.YES
|
||||
}
|
||||
operator(vimState, editor, ranges, linewise);
|
||||
return ParseKeysStatus.YES;
|
||||
};
|
||||
}
|
||||
|
||||
export function createOperatorRangeExactKeys(
|
||||
matchKeys: string[],
|
||||
linewise: boolean,
|
||||
f: (
|
||||
vimState: VimState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
) => vscode.Range | undefined,
|
||||
f: (vimState: HelixState, document: vscode.TextDocument, position: vscode.Position) => vscode.Range | undefined,
|
||||
): OperatorRange {
|
||||
return (vimState, keys, editor) => {
|
||||
if (arrayEquals(keys, matchKeys)) {
|
||||
const ranges = editor.selections.map((selection) => {
|
||||
return f(vimState, editor.document, selection.active)
|
||||
})
|
||||
return f(vimState, editor.document, selection.active);
|
||||
});
|
||||
return {
|
||||
kind: 'success',
|
||||
ranges: ranges,
|
||||
linewise: linewise,
|
||||
}
|
||||
};
|
||||
} else if (arrayStartsWith(keys, matchKeys)) {
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.MORE_INPUT,
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.NO,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function createOperatorRangeRegex(
|
||||
@ -218,35 +211,35 @@ export function createOperatorRangeRegex(
|
||||
couldPattern: RegExp,
|
||||
linewise: boolean,
|
||||
f: (
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
match: RegExpMatchArray,
|
||||
) => vscode.Range | undefined,
|
||||
): OperatorRange {
|
||||
return (vimState, keys, editor) => {
|
||||
const keysStr = keys.join('')
|
||||
const doesMatch = keysStr.match(doesPattern)
|
||||
const keysStr = keys.join('');
|
||||
const doesMatch = keysStr.match(doesPattern);
|
||||
|
||||
if (doesMatch) {
|
||||
const ranges = editor.selections.map((selection) => {
|
||||
return f(vimState, editor.document, selection.active, doesMatch)
|
||||
})
|
||||
return f(vimState, editor.document, selection.active, doesMatch);
|
||||
});
|
||||
return {
|
||||
kind: 'success',
|
||||
ranges: ranges,
|
||||
linewise: linewise,
|
||||
}
|
||||
};
|
||||
} else if (keysStr.match(couldPattern)) {
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.MORE_INPUT,
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
kind: 'failure',
|
||||
status: ParseKeysStatus.NO,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { VimState } from './vim_state_types'
|
||||
import { HelixState } from './helix_state_types';
|
||||
|
||||
export enum ParseKeysStatus {
|
||||
YES,
|
||||
@ -9,28 +9,28 @@ export enum ParseKeysStatus {
|
||||
}
|
||||
|
||||
export type ParseFailure = {
|
||||
kind: 'failure'
|
||||
status: ParseKeysStatus
|
||||
}
|
||||
kind: 'failure';
|
||||
status: ParseKeysStatus;
|
||||
};
|
||||
|
||||
export type ParseOperatorPartSuccess = {
|
||||
kind: 'success'
|
||||
rest: string[]
|
||||
}
|
||||
kind: 'success';
|
||||
rest: string[];
|
||||
};
|
||||
|
||||
export type ParseOperatorRangeSuccess = {
|
||||
kind: 'success'
|
||||
ranges: (vscode.Range | undefined)[]
|
||||
linewise: boolean
|
||||
}
|
||||
kind: 'success';
|
||||
ranges: (vscode.Range | undefined)[];
|
||||
linewise: boolean;
|
||||
};
|
||||
|
||||
export type ParseOperatorSuccess = {
|
||||
kind: 'success'
|
||||
motion: OperatorRange | undefined
|
||||
}
|
||||
kind: 'success';
|
||||
motion: OperatorRange | undefined;
|
||||
};
|
||||
|
||||
export type OperatorRange = (
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
keys: string[],
|
||||
editor: vscode.TextEditor,
|
||||
) => ParseFailure | ParseOperatorRangeSuccess
|
||||
) => ParseFailure | ParseOperatorRangeSuccess;
|
||||
|
@ -1,19 +1,19 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { VimState } from '../vim_state_types'
|
||||
import { HelixState } from '../helix_state_types';
|
||||
|
||||
export function getRegisterContentsList(vimState: VimState, editor: vscode.TextEditor) {
|
||||
if (vimState.registers.contentsList.length === 0) return undefined
|
||||
export function getRegisterContentsList(vimState: HelixState, editor: vscode.TextEditor) {
|
||||
if (vimState.registers.contentsList.length === 0) return undefined;
|
||||
|
||||
let registerContentsList = vimState.registers.contentsList
|
||||
let registerContentsList = vimState.registers.contentsList;
|
||||
|
||||
// Handle putting with a different number of cursors than when you yanked
|
||||
if (vimState.registers.contentsList.length !== editor.selections.length) {
|
||||
const combinedContents = vimState.registers.contentsList.join('\n')
|
||||
registerContentsList = editor.selections.map(() => combinedContents)
|
||||
const combinedContents = vimState.registers.contentsList.join('\n');
|
||||
registerContentsList = editor.selections.map(() => combinedContents);
|
||||
}
|
||||
|
||||
return registerContentsList
|
||||
return registerContentsList;
|
||||
}
|
||||
|
||||
// Given contents and positions at the end of the contents, return the position at the beginning of the contents
|
||||
@ -23,106 +23,98 @@ export function getInsertRangesFromEnd(
|
||||
contentsList: (string | undefined)[],
|
||||
) {
|
||||
return positions.map((position, i) => {
|
||||
const contents = contentsList[i]
|
||||
if (!contents) return undefined
|
||||
const contents = contentsList[i];
|
||||
if (!contents) return undefined;
|
||||
|
||||
const lines = contents.split(/\r?\n/)
|
||||
const lines = contents.split(/\r?\n/);
|
||||
|
||||
let beginningPosition
|
||||
let beginningPosition;
|
||||
if (lines.length > 1) {
|
||||
const beginningLine = position.line - (lines.length - 1)
|
||||
const beginningCharacter = document.lineAt(beginningLine).text.length - lines[0].length
|
||||
beginningPosition = new vscode.Position(beginningLine, beginningCharacter)
|
||||
const beginningLine = position.line - (lines.length - 1);
|
||||
const beginningCharacter = document.lineAt(beginningLine).text.length - lines[0].length;
|
||||
beginningPosition = new vscode.Position(beginningLine, beginningCharacter);
|
||||
} else {
|
||||
beginningPosition = position.with({
|
||||
character: position.character - lines[0].length,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
return new vscode.Range(beginningPosition, position)
|
||||
})
|
||||
return new vscode.Range(beginningPosition, position);
|
||||
});
|
||||
}
|
||||
|
||||
// Given positions and contents inserted at those positions, return the range that will
|
||||
// select that contents
|
||||
export function getInsertRangesFromBeginning(
|
||||
positions: vscode.Position[],
|
||||
contentsList: (string | undefined)[],
|
||||
) {
|
||||
export function getInsertRangesFromBeginning(positions: vscode.Position[], contentsList: (string | undefined)[]) {
|
||||
return positions.map((position, i) => {
|
||||
const contents = contentsList[i]
|
||||
if (!contents) return undefined
|
||||
const contents = contentsList[i];
|
||||
if (!contents) return undefined;
|
||||
|
||||
const lines = contents.split(/\r?\n/)
|
||||
const endLine = position.line + lines.length - 1
|
||||
const endCharacter =
|
||||
lines.length === 1 ? position.character + lines[0].length : lines[lines.length - 1].length
|
||||
const lines = contents.split(/\r?\n/);
|
||||
const endLine = position.line + lines.length - 1;
|
||||
const endCharacter = lines.length === 1 ? position.character + lines[0].length : lines[lines.length - 1].length;
|
||||
|
||||
return new vscode.Range(position, new vscode.Position(endLine, endCharacter))
|
||||
})
|
||||
return new vscode.Range(position, new vscode.Position(endLine, endCharacter));
|
||||
});
|
||||
}
|
||||
|
||||
// Given positions and contents inserted at those positions, figure out how the positions will move
|
||||
// when the contents is inserted. For example inserting a line above a position will increase its
|
||||
// line number by one.
|
||||
export function adjustInsertPositions(
|
||||
positions: vscode.Position[],
|
||||
contentsList: (string | undefined)[],
|
||||
) {
|
||||
export function adjustInsertPositions(positions: vscode.Position[], contentsList: (string | undefined)[]) {
|
||||
const indexPositions = positions.map((position, i) => ({
|
||||
originalIndex: i,
|
||||
position: position,
|
||||
}))
|
||||
}));
|
||||
|
||||
indexPositions.sort((a, b) => {
|
||||
if (a.position.isBefore(b.position)) return -1
|
||||
else if (a.position.isEqual(b.position)) return 0
|
||||
else return 1
|
||||
})
|
||||
if (a.position.isBefore(b.position)) return -1;
|
||||
else if (a.position.isEqual(b.position)) return 0;
|
||||
else return 1;
|
||||
});
|
||||
|
||||
const adjustedIndexPositions = []
|
||||
let lineOffset = 0
|
||||
let characterOffset = 0
|
||||
let lineNumber = 0
|
||||
const adjustedIndexPositions = [];
|
||||
let lineOffset = 0;
|
||||
let characterOffset = 0;
|
||||
let lineNumber = 0;
|
||||
|
||||
for (const indexPosition of indexPositions) {
|
||||
// Adjust position
|
||||
|
||||
const adjustedLine = indexPosition.position.line + lineOffset
|
||||
const adjustedLine = indexPosition.position.line + lineOffset;
|
||||
|
||||
let adjustedCharacter = indexPosition.position.character
|
||||
let adjustedCharacter = indexPosition.position.character;
|
||||
if (indexPosition.position.line === lineNumber) {
|
||||
adjustedCharacter += characterOffset
|
||||
adjustedCharacter += characterOffset;
|
||||
}
|
||||
|
||||
adjustedIndexPositions.push({
|
||||
originalIndex: indexPosition.originalIndex,
|
||||
position: new vscode.Position(adjustedLine, adjustedCharacter),
|
||||
})
|
||||
});
|
||||
|
||||
// Increase offsets
|
||||
|
||||
const contents = contentsList[indexPosition.originalIndex]
|
||||
const contents = contentsList[indexPosition.originalIndex];
|
||||
|
||||
if (contents !== undefined) {
|
||||
const contentsLines = contents.split(/\r?\n/)
|
||||
const contentsLines = contents.split(/\r?\n/);
|
||||
|
||||
lineOffset += contentsLines.length - 1
|
||||
lineOffset += contentsLines.length - 1;
|
||||
|
||||
if (indexPosition.position.line === lineNumber) {
|
||||
if (contentsLines.length === 1) {
|
||||
characterOffset += contentsLines[0].length
|
||||
characterOffset += contentsLines[0].length;
|
||||
} else {
|
||||
characterOffset +=
|
||||
contentsLines[contentsLines.length - 1].length - indexPosition.position.character
|
||||
characterOffset += contentsLines[contentsLines.length - 1].length - indexPosition.position.character;
|
||||
}
|
||||
} else {
|
||||
characterOffset = 0
|
||||
lineNumber = indexPosition.position.line
|
||||
characterOffset = 0;
|
||||
lineNumber = indexPosition.position.line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adjustedIndexPositions.sort((a, b) => a.originalIndex - b.originalIndex)
|
||||
return adjustedIndexPositions.map((indexPosition) => indexPosition.position)
|
||||
adjustedIndexPositions.sort((a, b) => a.originalIndex - b.originalIndex);
|
||||
return adjustedIndexPositions.map((indexPosition) => indexPosition.position);
|
||||
}
|
||||
|
@ -1,132 +1,124 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import * as positionUtils from '../position_utils'
|
||||
import { VimState } from '../vim_state_types'
|
||||
import { Mode } from '../modes_types'
|
||||
import { enterNormalMode, setModeCursorStyle } from '../modes'
|
||||
import * as positionUtils from '../position_utils';
|
||||
import { HelixState } from '../helix_state_types';
|
||||
import { Mode } from '../modes_types';
|
||||
import { enterNormalMode, setModeCursorStyle } from '../modes';
|
||||
import {
|
||||
getRegisterContentsList,
|
||||
adjustInsertPositions,
|
||||
getInsertRangesFromBeginning,
|
||||
getInsertRangesFromEnd,
|
||||
} from './common'
|
||||
} from './common';
|
||||
|
||||
export function putAfter(vimState: VimState, editor: vscode.TextEditor) {
|
||||
const registerContentsList = getRegisterContentsList(vimState, editor)
|
||||
if (registerContentsList === undefined) return
|
||||
export function putAfter(vimState: HelixState, editor: vscode.TextEditor) {
|
||||
const registerContentsList = getRegisterContentsList(vimState, editor);
|
||||
if (registerContentsList === undefined) return;
|
||||
|
||||
if (vimState.mode === Mode.Normal) {
|
||||
if (vimState.registers.linewise) {
|
||||
normalModeLinewise(vimState, editor, registerContentsList)
|
||||
normalModeLinewise(vimState, editor, registerContentsList);
|
||||
} else {
|
||||
normalModeCharacterwise(vimState, editor, registerContentsList)
|
||||
normalModeCharacterwise(vimState, editor, registerContentsList);
|
||||
}
|
||||
} else if (vimState.mode === Mode.Visual) {
|
||||
visualMode(vimState, editor, registerContentsList)
|
||||
visualMode(vimState, editor, registerContentsList);
|
||||
} else {
|
||||
visualLineMode(vimState, editor, registerContentsList)
|
||||
visualLineMode(vimState, editor, registerContentsList);
|
||||
}
|
||||
}
|
||||
|
||||
function normalModeLinewise(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
registerContentsList: (string | undefined)[],
|
||||
) {
|
||||
const insertContentsList = registerContentsList.map((contents) => {
|
||||
if (contents === undefined) return undefined
|
||||
else return `\n${contents}`
|
||||
})
|
||||
if (contents === undefined) return undefined;
|
||||
else return `\n${contents}`;
|
||||
});
|
||||
|
||||
const insertPositions = editor.selections.map((selection) => {
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length
|
||||
return new vscode.Position(selection.active.line, lineLength)
|
||||
})
|
||||
const lineLength = editor.document.lineAt(selection.active.line).text.length;
|
||||
return new vscode.Position(selection.active.line, lineLength);
|
||||
});
|
||||
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, insertContentsList)
|
||||
const rangeBeginnings = adjustedInsertPositions.map(
|
||||
(position) => new vscode.Position(position.line + 1, 0),
|
||||
)
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, insertContentsList);
|
||||
const rangeBeginnings = adjustedInsertPositions.map((position) => new vscode.Position(position.line + 1, 0));
|
||||
|
||||
editor
|
||||
.edit((editBuilder) => {
|
||||
insertPositions.forEach((position, i) => {
|
||||
const contents = insertContentsList[i]
|
||||
if (contents === undefined) return
|
||||
const contents = insertContentsList[i];
|
||||
if (contents === undefined) return;
|
||||
|
||||
editBuilder.insert(position, contents)
|
||||
})
|
||||
editBuilder.insert(position, contents);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
editor.selections = rangeBeginnings.map(
|
||||
(position) => new vscode.Selection(position, position),
|
||||
)
|
||||
})
|
||||
editor.selections = rangeBeginnings.map((position) => new vscode.Selection(position, position));
|
||||
});
|
||||
|
||||
vimState.lastPutRanges = {
|
||||
ranges: getInsertRangesFromBeginning(rangeBeginnings, registerContentsList),
|
||||
linewise: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function normalModeCharacterwise(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
registerContentsList: (string | undefined)[],
|
||||
) {
|
||||
const insertPositions = editor.selections.map((selection) => {
|
||||
return positionUtils.right(editor.document, selection.active)
|
||||
})
|
||||
return positionUtils.right(editor.document, selection.active);
|
||||
});
|
||||
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, registerContentsList)
|
||||
const insertRanges = getInsertRangesFromBeginning(adjustedInsertPositions, registerContentsList)
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, registerContentsList);
|
||||
const insertRanges = getInsertRangesFromBeginning(adjustedInsertPositions, registerContentsList);
|
||||
|
||||
editor
|
||||
.edit((editBuilder) => {
|
||||
insertPositions.forEach((insertPosition, i) => {
|
||||
const registerContents = registerContentsList[i]
|
||||
if (registerContents === undefined) return
|
||||
const registerContents = registerContentsList[i];
|
||||
if (registerContents === undefined) return;
|
||||
|
||||
editBuilder.insert(insertPosition, registerContents)
|
||||
})
|
||||
editBuilder.insert(insertPosition, registerContents);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
editor.selections = editor.selections.map((selection, i) => {
|
||||
const range = insertRanges[i]
|
||||
if (range === undefined) return selection
|
||||
const range = insertRanges[i];
|
||||
if (range === undefined) return selection;
|
||||
|
||||
const position = positionUtils.left(range.end)
|
||||
return new vscode.Selection(position, position)
|
||||
})
|
||||
})
|
||||
const position = positionUtils.left(range.end);
|
||||
return new vscode.Selection(position, position);
|
||||
});
|
||||
});
|
||||
|
||||
vimState.lastPutRanges = {
|
||||
ranges: insertRanges,
|
||||
linewise: false,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function visualMode(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
registerContentsList: (string | undefined)[],
|
||||
) {
|
||||
function visualMode(vimState: HelixState, editor: vscode.TextEditor, registerContentsList: (string | undefined)[]) {
|
||||
const insertContentsList = vimState.registers.linewise
|
||||
? registerContentsList.map((contents) => {
|
||||
if (!contents) return undefined
|
||||
else return '\n' + contents + '\n'
|
||||
if (!contents) return undefined;
|
||||
else return '\n' + contents + '\n';
|
||||
})
|
||||
: registerContentsList
|
||||
: registerContentsList;
|
||||
|
||||
editor
|
||||
.edit((editBuilder) => {
|
||||
editor.selections.forEach((selection, i) => {
|
||||
const contents = insertContentsList[i]
|
||||
if (contents === undefined) return
|
||||
const contents = insertContentsList[i];
|
||||
if (contents === undefined) return;
|
||||
|
||||
editBuilder.delete(selection)
|
||||
editBuilder.insert(selection.start, contents)
|
||||
})
|
||||
editBuilder.delete(selection);
|
||||
editBuilder.insert(selection.start, contents);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
vimState.lastPutRanges = {
|
||||
@ -136,45 +128,39 @@ function visualMode(
|
||||
insertContentsList,
|
||||
),
|
||||
linewise: vimState.registers.linewise,
|
||||
}
|
||||
};
|
||||
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
const newPosition = positionUtils.left(selection.active)
|
||||
return new vscode.Selection(newPosition, newPosition)
|
||||
})
|
||||
})
|
||||
const newPosition = positionUtils.left(selection.active);
|
||||
return new vscode.Selection(newPosition, newPosition);
|
||||
});
|
||||
});
|
||||
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
enterNormalMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
}
|
||||
|
||||
function visualLineMode(
|
||||
vimState: VimState,
|
||||
editor: vscode.TextEditor,
|
||||
registerContentsList: (string | undefined)[],
|
||||
) {
|
||||
function visualLineMode(vimState: HelixState, editor: vscode.TextEditor, registerContentsList: (string | undefined)[]) {
|
||||
editor
|
||||
.edit((editBuilder) => {
|
||||
editor.selections.forEach((selection, i) => {
|
||||
const registerContents = registerContentsList[i]
|
||||
if (registerContents === undefined) return
|
||||
const registerContents = registerContentsList[i];
|
||||
if (registerContents === undefined) return;
|
||||
|
||||
editBuilder.replace(selection, registerContents)
|
||||
})
|
||||
editBuilder.replace(selection, registerContents);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
vimState.lastPutRanges = {
|
||||
ranges: editor.selections.map(
|
||||
(selection) => new vscode.Range(selection.start, selection.end),
|
||||
),
|
||||
ranges: editor.selections.map((selection) => new vscode.Range(selection.start, selection.end)),
|
||||
linewise: vimState.registers.linewise,
|
||||
}
|
||||
};
|
||||
|
||||
editor.selections = editor.selections.map((selection) => {
|
||||
return new vscode.Selection(selection.start, selection.start)
|
||||
})
|
||||
return new vscode.Selection(selection.start, selection.start);
|
||||
});
|
||||
|
||||
enterNormalMode(vimState)
|
||||
setModeCursorStyle(vimState.mode, editor)
|
||||
})
|
||||
enterNormalMode(vimState);
|
||||
setModeCursorStyle(vimState.mode, editor);
|
||||
});
|
||||
}
|
||||
|
@ -1,93 +1,89 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as positionUtils from '../position_utils'
|
||||
import type { VimState } from '../vim_state_types'
|
||||
import {
|
||||
adjustInsertPositions,
|
||||
getInsertRangesFromBeginning,
|
||||
getRegisterContentsList,
|
||||
} from './common'
|
||||
import * as vscode from 'vscode';
|
||||
import * as positionUtils from '../position_utils';
|
||||
import type { HelixState } from '../helix_state_types';
|
||||
import { adjustInsertPositions, getInsertRangesFromBeginning, getRegisterContentsList } from './common';
|
||||
|
||||
export function putBefore(vimState: VimState, editor: vscode.TextEditor) {
|
||||
const registerContentsList = getRegisterContentsList(vimState, editor)
|
||||
if (registerContentsList === undefined) return
|
||||
export function putBefore(vimState: HelixState, editor: vscode.TextEditor) {
|
||||
const registerContentsList = getRegisterContentsList(vimState, editor);
|
||||
if (registerContentsList === undefined) return;
|
||||
|
||||
if (vimState.registers.linewise) {
|
||||
normalModeLinewise(vimState, editor, registerContentsList)
|
||||
normalModeLinewise(vimState, editor, registerContentsList);
|
||||
} else {
|
||||
normalModeCharacterwise(vimState, editor, registerContentsList)
|
||||
normalModeCharacterwise(vimState, editor, registerContentsList);
|
||||
}
|
||||
}
|
||||
|
||||
function normalModeLinewise(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
registerContentsList: (string | undefined)[],
|
||||
) {
|
||||
const insertContentsList = registerContentsList.map((contents) => {
|
||||
if (contents === undefined) return undefined
|
||||
else return `${contents}\n`
|
||||
})
|
||||
if (contents === undefined) return undefined;
|
||||
else return `${contents}\n`;
|
||||
});
|
||||
|
||||
const insertPositions = editor.selections.map((selection) => {
|
||||
return new vscode.Position(selection.active.line, 0)
|
||||
})
|
||||
return new vscode.Position(selection.active.line, 0);
|
||||
});
|
||||
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, insertContentsList)
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, insertContentsList);
|
||||
|
||||
editor
|
||||
.edit((editBuilder) => {
|
||||
insertPositions.forEach((position, i) => {
|
||||
const contents = insertContentsList[i]
|
||||
if (contents === undefined) return
|
||||
const contents = insertContentsList[i];
|
||||
if (contents === undefined) return;
|
||||
|
||||
editBuilder.insert(position, contents)
|
||||
})
|
||||
editBuilder.insert(position, contents);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
editor.selections = editor.selections.map((selection, i) => {
|
||||
const position = adjustedInsertPositions[i]
|
||||
if (position === undefined) return selection
|
||||
const position = adjustedInsertPositions[i];
|
||||
if (position === undefined) return selection;
|
||||
|
||||
return new vscode.Selection(position, position)
|
||||
})
|
||||
})
|
||||
return new vscode.Selection(position, position);
|
||||
});
|
||||
});
|
||||
|
||||
vimState.lastPutRanges = {
|
||||
ranges: getInsertRangesFromBeginning(adjustedInsertPositions, registerContentsList),
|
||||
linewise: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function normalModeCharacterwise(
|
||||
vimState: VimState,
|
||||
vimState: HelixState,
|
||||
editor: vscode.TextEditor,
|
||||
registerContentsList: (string | undefined)[],
|
||||
) {
|
||||
const insertPositions = editor.selections.map((selection) => selection.active)
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, registerContentsList)
|
||||
const insertRanges = getInsertRangesFromBeginning(adjustedInsertPositions, registerContentsList)
|
||||
const insertPositions = editor.selections.map((selection) => selection.active);
|
||||
const adjustedInsertPositions = adjustInsertPositions(insertPositions, registerContentsList);
|
||||
const insertRanges = getInsertRangesFromBeginning(adjustedInsertPositions, registerContentsList);
|
||||
|
||||
editor
|
||||
.edit((editBuilder) => {
|
||||
insertPositions.forEach((insertPosition, i) => {
|
||||
const registerContents = registerContentsList[i]
|
||||
if (registerContents === undefined) return
|
||||
const registerContents = registerContentsList[i];
|
||||
if (registerContents === undefined) return;
|
||||
|
||||
editBuilder.insert(insertPosition, registerContents)
|
||||
})
|
||||
editBuilder.insert(insertPosition, registerContents);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
editor.selections = editor.selections.map((selection, i) => {
|
||||
const range = insertRanges[i]
|
||||
if (range === undefined) return selection
|
||||
const range = insertRanges[i];
|
||||
if (range === undefined) return selection;
|
||||
|
||||
const position = positionUtils.left(range.end)
|
||||
return new vscode.Selection(position, position)
|
||||
})
|
||||
})
|
||||
const position = positionUtils.left(range.end);
|
||||
return new vscode.Selection(position, position);
|
||||
});
|
||||
});
|
||||
|
||||
vimState.lastPutRanges = {
|
||||
ranges: insertRanges,
|
||||
linewise: false,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,33 +1,33 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { ParseKeysStatus } from './parse_keys_types'
|
||||
import { actions } from './actions'
|
||||
import { VimState } from './vim_state_types'
|
||||
import { ParseKeysStatus } from './parse_keys_types';
|
||||
import { actions } from './actions';
|
||||
import { HelixState } from './helix_state_types';
|
||||
|
||||
export function typeHandler(vimState: VimState, char: string): void {
|
||||
const editor = vscode.window.activeTextEditor
|
||||
export function typeHandler(vimState: HelixState, char: string): void {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
|
||||
if (!editor) return
|
||||
if (!editor) return;
|
||||
|
||||
vimState.keysPressed.push(char)
|
||||
vimState.keysPressed.push(char);
|
||||
|
||||
try {
|
||||
let could = false
|
||||
let could = false;
|
||||
for (const action of actions) {
|
||||
const result = action(vimState, vimState.keysPressed, editor)
|
||||
const result = action(vimState, vimState.keysPressed, editor);
|
||||
|
||||
if (result === ParseKeysStatus.YES) {
|
||||
vimState.keysPressed = []
|
||||
break
|
||||
vimState.keysPressed = [];
|
||||
break;
|
||||
} else if (result === ParseKeysStatus.MORE_INPUT) {
|
||||
could = true
|
||||
could = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!could) {
|
||||
vimState.keysPressed = []
|
||||
vimState.keysPressed = [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { VimState } from './vim_state_types'
|
||||
import { HelixState } from './helix_state_types';
|
||||
|
||||
export function addTypeSubscription(
|
||||
vimState: VimState,
|
||||
typeHandler: (vimState: VimState, char: string) => void,
|
||||
vimState: HelixState,
|
||||
typeHandler: (vimState: HelixState, char: string) => void,
|
||||
): void {
|
||||
vimState.typeSubscription = vscode.commands.registerCommand('type', (e) => {
|
||||
typeHandler(vimState, e.text)
|
||||
})
|
||||
typeHandler(vimState, e.text);
|
||||
});
|
||||
}
|
||||
|
||||
export function removeTypeSubscription(vimState: VimState): void {
|
||||
export function removeTypeSubscription(vimState: HelixState): void {
|
||||
if (vimState.typeSubscription) {
|
||||
vimState.typeSubscription.dispose()
|
||||
vimState.typeSubscription.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
import * as vscode from 'vscode'
|
||||
|
||||
import type { Mode } from './modes_types'
|
||||
|
||||
export type VimState = {
|
||||
typeSubscription: vscode.Disposable | undefined
|
||||
mode: Mode
|
||||
keysPressed: string[]
|
||||
registers: {
|
||||
contentsList: (string | undefined)[]
|
||||
linewise: boolean
|
||||
}
|
||||
semicolonAction: (vimState: VimState, editor: vscode.TextEditor) => void
|
||||
commaAction: (vimState: VimState, editor: vscode.TextEditor) => void
|
||||
lastPutRanges: {
|
||||
ranges: (vscode.Range | undefined)[]
|
||||
linewise: boolean
|
||||
}
|
||||
}
|
@ -1,37 +1,31 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import * as positionUtils from './position_utils'
|
||||
import * as positionUtils from './position_utils';
|
||||
|
||||
// This fixes the selection anchor when selection is changed so that active and anchor are reversed.
|
||||
// For most motions we use execMotion for perfect visual mode emulation, but for some we need to
|
||||
// use VSCode's cursorMove instead and this function allows us to fix the selection after the fact.
|
||||
export function setVisualSelections(
|
||||
editor: vscode.TextEditor,
|
||||
originalSelections: vscode.Selection[],
|
||||
): void {
|
||||
export function setVisualSelections(editor: vscode.TextEditor, originalSelections: readonly vscode.Selection[]): void {
|
||||
editor.selections = editor.selections.map((selection, i) => {
|
||||
const originalSelection = originalSelections[i]
|
||||
const originalSelection = originalSelections[i];
|
||||
|
||||
let activePosition = selection.active
|
||||
let activePosition = selection.active;
|
||||
if (!selection.isReversed && selection.active.character === 0) {
|
||||
activePosition = positionUtils.right(editor.document, selection.active)
|
||||
activePosition = positionUtils.right(editor.document, selection.active);
|
||||
}
|
||||
|
||||
if (
|
||||
originalSelection.active.isBefore(originalSelection.anchor) &&
|
||||
selection.active.isAfterOrEqual(selection.anchor)
|
||||
) {
|
||||
return new vscode.Selection(positionUtils.left(selection.anchor), activePosition)
|
||||
return new vscode.Selection(positionUtils.left(selection.anchor), activePosition);
|
||||
} else if (
|
||||
originalSelection.active.isAfter(originalSelection.anchor) &&
|
||||
selection.active.isBeforeOrEqual(selection.anchor)
|
||||
) {
|
||||
return new vscode.Selection(
|
||||
positionUtils.right(editor.document, selection.anchor),
|
||||
activePosition,
|
||||
)
|
||||
return new vscode.Selection(positionUtils.right(editor.document, selection.anchor), activePosition);
|
||||
} else {
|
||||
return new vscode.Selection(selection.anchor, activePosition)
|
||||
return new vscode.Selection(selection.anchor, activePosition);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user