├── .github
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .travis.yml
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── .vscodeignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── ROADMAP.md
├── STYLE.md
├── designdoc.md
├── extension.ts
├── gulpfile.js
├── images
├── design
│ ├── vscodevim-logo.png
│ └── vscodevim-logo.svg
└── icon.png
├── package-lock.json
├── package.json
├── scripts
├── create_changelog.py
└── keybind_gen.py
├── src
├── common
│ └── motion
│ │ ├── position.ts
│ │ └── range.ts
├── configuration
│ └── configuration.ts
├── globals.ts
├── textEditor.ts
└── util.ts
├── srcNV
├── nvUtil.ts
├── rpcHandlers.ts
├── screen.ts
├── vimSettings.ts
└── vscHandlers.ts
├── tsconfig.json
├── tsd.json
├── tslint.json
├── typings.json
└── typings
└── custom
└── promised-neovim-client.d.ts
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guide
2 |
3 | The following is a set of guidelines for contributing to Vim for VSCode.
4 | These are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request.
5 | If you need help with Vim for VSCode, drop by on [Slack](https://vscodevim-slackin.azurewebsites.net/).
6 | Thanks for helping us make Vim for VSCode better!
7 |
8 | ## Submitting Issues
9 |
10 | The [GitHub issue tracker](https://github.com/VSCodeVim/Vim/issues) is the preferred channel for tracking bugs and enhancement suggestions.
11 | When creating a new bug report do:
12 |
13 | * Search against existing issues to check if somebody else has already reported your problem or requested your idea
14 | * Include as many details as possible -- include screenshots/gifs and repro steps where applicable.
15 |
16 | ## Submitting Pull Requests
17 |
18 | Pull requests are *awesome*.
19 | If you're looking to raise a PR for something which doesn't have an open issue, consider creating an issue first.
20 | When submitting a PR, ensure:
21 |
22 | 1. All tests pass.
23 | 2. If you added a new feature, add tests to exercise the new code path.
24 | 3. If you fixed a bug, add tests to ensure the bug stays away.
25 | 4. Submit the PR. Pour yourself a glass of champagne and feel good about contributing to open source!
26 |
27 | ## First Time Setup
28 |
29 | 1. Install prerequisites:
30 | * latest [Visual Studio Code](https://code.visualstudio.com/)
31 | * [Node.js](https://nodejs.org/) v4.0.0 or higher
32 | 2. Fork and clone the repository
33 | 3. `cd Vim`
34 | 4. Install the dependencies:
35 |
36 | ```bash
37 | $ npm install -g gulp-cli
38 | $ npm install
39 | ```
40 | 5. Open the folder in VS Code
41 |
42 | ## Developing
43 |
44 | 1. Watch for changes and recompile Typescript files. Run this in the `Vim` directory: `gulp watch`
45 | 2. Open Visual Studio Code and add the `Vim` directory as a folder.
46 | 3. Click on the debugger. You have two options - Launch Extension (to play around with the extension) and Launch Tests (to run the tests).
47 |
48 | ## Code Architecture
49 |
50 | The code is split into two parts - ModeHandler (which is essentially the Vim state machine), and Actions (which are things that modify the state).
51 |
52 | ### Actions
53 |
54 | Actions are all currently stuffed into actions.ts (sorry!). There are:
55 | * BaseAction - the base Action type that all Actions derive from.
56 | * BaseMovement - A movement, like `w`, `h`, `{`, etc. ONLY updates the cursor position. At worst, might return an IMovement, which indicates a start and stop. This is used for movements like aw which may actually start before the cursor.
57 | * BaseCommand - Anything which is not just a movement is a Command. That includes motions which also update the state of Vim in some way, like `*`.
58 |
59 | At one point, I wanted to have actions.ts be completely pure (no side effects whatsoever), so commands would just return objects indicating what side effects on the editor they would have. This explains the giant switch in handleCommand in ModeHandler. I now believe this to be a dumb idea and someone should get rid of it.
60 |
61 | Probably me. :wink:
62 |
63 | ### The Vim State Machine
64 |
65 | It's contained entirely within modeHandler.ts. It's actually pretty complicated, and I probably won't be able to articulate all of the edge cases it contains.
66 |
67 | It consists of two data structures:
68 |
69 | * VimState - this is the state of Vim. It's what actions update.
70 | * RecordedState - this is temporary state that will reset at the end of a change. (RecordedState is a poor name for this; I've been going back and forth on different names).
71 |
72 | #### How it works
73 |
74 | 1. `handleKeyEventHelper` is called with the most recent keypress.
75 | 2. `Actions.getRelevantAction` determines if all the keys pressed so far uniquely specify any action in actions.ts. If not, we continue waiting for keypresses.
76 | 3. `runAction` runs the action that was matched. Movements, Commands and Operators all have separate functions that dictate how to run them - `executeMovement`, `handleCommand`, and `executeOperator` respectively.
77 | 4. Now that we've updated VimState, we run `updateView` with the new VimState to "redraw" VSCode to the new state.
78 |
79 | #### vscode.window.onDidChangeTextEditorSelection
80 |
81 | This is my hack to simulate a click event based API in an IDE that doesn't have them (yet?). I check the selection that just came in to see if it's the same as what I thought I previously set the selection to the last time the state machine updated. If it's not, the user *probably* clicked. (But she also could have tab completed!)
82 |
83 | ## Release
84 |
85 | To push a release:
86 |
87 | 1. Bump the version number and create a git tag: `gulp patch|minor|major`
88 | 2. Push the changes: `git push origin --tags`
89 |
90 | In addition to building and testing the extension, when a tag is applied to the commit, the CI server will also create a GitHub release and publish the new version to the Visual Studio marketplace.
91 |
92 | ## Troubleshooting
93 |
94 | ### Visual Studio Code Slowdown
95 |
96 | If your autocomplete, your fuzzy file search, or your _everything_ is suddenly running slower, try to recall if you ever ran `npm test` instead of just running tests through Visual Studio Code. This will add a massive folder called `.vscode-test/` to your project, which Visual Studio Code will happily consume all of your CPU cycles indexing.
97 |
98 | Long story short, you can speed up VS Code by:
99 |
100 | `$ rm -rf .vscode-test/`
101 |
102 | ## Styleguide
103 |
104 | Please try your best to adhere our [style guidelines](https://github.com/VSCodeVim/Vim/blob/master/STYLE.md).
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | * Click *thumbs-up* 👍 on this issue if you want it!
7 | * Click *confused* 😕 on this issue if not having it makes VSCodeVim unusable.
8 |
9 | The VSCodeVim team prioritizes issues based on reaction count.
10 |
11 | --------
12 |
13 | **Is this a BUG REPORT or FEATURE REQUEST?** (choose one):
14 |
15 |
27 |
28 | **Environment**:
29 |
30 |
33 |
34 | - **VSCode Version**:
35 | - **VsCodeVim Version**:
36 | - **OS**:
37 |
38 | **What happened**:
39 |
40 |
43 |
44 | **What did you expect to happen**:
45 |
46 | **How to reproduce it**:
47 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | testing
3 | node_modules
4 | *.sw?
5 | .vscode-test
6 | .DS_Store
7 | *.log
8 |
9 | typings/*
10 | !typings/custom/
11 | testing
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | notifications:
2 | email: false
3 |
4 | sudo: false
5 |
6 | os:
7 | - linux
8 |
9 | language: node_js
10 |
11 | node_js:
12 | - 6.3.1
13 |
14 | env:
15 | global:
16 | secure: "tzpL/lQ2L2mVDS0sPY0LnJ3idspKmiOAuKFFfBZbBk4vA6NtJYveXILiskNDWK4p3JIWux/JBxgU3auXU4t7BZy7bMfUpTm0PpsMQfvDV2/rsf3QUQgYvROZkVpeH6b73hxxyTy0wfDHrb0SIUjB9IChUiSDIBjwteVAb/HuIWNKRQ6mbmkZKiQ3xHisFOG9xTkrEO31BfA+nKxUOTtXiZtoHTOWK9+H67QKd19BTRn/vJrwhTUsYqyOBAoFQjDjpAbhRNgs4YxHJz2jn1rmeE8kotf3LsfBrws07Mu9O9CnEcJKsqgJW+ezbHCO/HjLfpul/v0HtF/UQM00v5J2mDFz/ii8OWQ41TjYgkAHhtXIkMDQiM6K1x+gsaq0wm4QDX+Akg3r4sFqzhKsIuSLr1QTAMh9nn9G2asQvVJNNgH1QFvuLMF3bX1xp4l79/xoCEAWqlxx1mScYcmGFtYtQd107U5qPcHrR66vTMV5VqiZ0XapJympE+D5xIiSb4CTFGpl9+PSBk69MjynMEbGsLsudYWp6HZA5CyosxoStXxR1fD+ypqsSyzynSpThZ6IpFJ7Pk95GR3Z78CPhkNZvBvJ62xW/6/hAykWcelRHZy0N5XT2+HP+xcx77Fpqj8ZEAI6ECHNnnZ1KQROodu5LI06oZ2hiM1P1gdBx6xrljg="
17 |
18 | before_install:
19 | - eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) nightly-x64"
20 | - if [ $TRAVIS_OS_NAME == "linux" ]; then
21 | export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0;
22 | sh -e /etc/init.d/xvfb start;
23 | sleep 3;
24 | fi
25 |
26 | install:
27 | - npm install -g gulp;
28 | - npm install;
29 |
30 | script:
31 | - gulp
32 | - npm test --silent;
33 |
34 | before_deploy:
35 | - npm install -g vsce;
36 | - vsce package;
37 |
38 | deploy:
39 | - provider: releases
40 | api_key:
41 | secure: YQLI+5JqIZj4XNrVO6EUrahICsfQVZ64wWmu8mMOj2rOaEid3dIL1Q69YbzQWIbcLt3y4oBGeefrakWdr/k/xgrnrkoEj3XnzgIp2E+e7rJvwnH4tM6tV191iq4wXdTo6vf0Ha/Bo6LpibP/LgPOXOY64/qZ0HtS1zqAxQLz+9b1O2knGnAQnaE0sqf0xQwZBl5kd/ChRV/+IIJJb5p3Pok9idbTW54O9BRb2ue720cvOR3afyIau2njVB8INgvNU9b2cYqg6RLAUOj2RaenuaH7GLI2dIYj9a8wgJyxliNTMGNFRhz+KmXie3tUZDuRytqxIq2SD7FHl744+F4L2YQyMiMMs4bF0jLkeDVwHExQsrdXlQ1pW2GLR7YQQpcr202jBkq+CNC7DBNyQlXwe/21M5kxYMTEJMqTMdPDfPgmhshf6VWqTSDczLDxue72m+gWxwv6kseFSQxwvRXly8hW0ev2rddMt9nu73hAZ+Lkmu16qArQ8HxAQUrBASaDYa0RAqJ3bNj6RwKFsa9/HK27XRrUY5GViMSQSeaEv3EO9Nc0ibMbFFL8EEBB9wXDS75jmlAioQcl1B1rzcKbSW37wSOJH1WUJCpM0+xdQVo8Gngld0LAyugOikir+mcnnEkGCeo2ZdeMEy63iqhCKwz2au4+XbEttBgfhd/una4=
42 | file_glob: true
43 | file: "*.vsix"
44 | skip_cleanup: true
45 | on:
46 | repo: VSCodeVim/Vim
47 | tags: true
48 | condition: $TRAVIS_OS_NAME = linux
49 | - provider: script
50 | script: vsce publish -p $VS_TOKEN
51 | skip_cleanup: true
52 | on:
53 | repo: VSCodeVim/Vim
54 | tags: true
55 | condition: $TRAVIS_OS_NAME = linux
56 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that compiles the extension and then opens it inside a new window
2 | {
3 | "version": "0.1.0",
4 | "configurations": [
5 | {
6 | "name": "Build, Run Extension",
7 | "type": "extensionHost",
8 | "request": "launch",
9 | "runtimeExecutable": "${execPath}",
10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
11 | "stopOnEntry": false,
12 | "sourceMaps": true,
13 | "outFiles": [ "${workspaceRoot}/{out, node_modules}/**/*.js" ],
14 | "preLaunchTask": "build",
15 | "internalConsoleOptions": "openOnSessionStart"
16 | },
17 | {
18 | "name": "Run Extension",
19 | "type": "extensionHost",
20 | "request": "launch",
21 | "runtimeExecutable": "${execPath}",
22 | "args": [
23 | "--extensionDevelopmentPath=${workspaceRoot}"
24 | ],
25 | "stopOnEntry": false,
26 | "sourceMaps": true,
27 | "outFiles": [ "${workspaceRoot}/{out, node_modules}/**/*.js" ]
28 | },
29 | {
30 | "name": "Run Tests",
31 | "type": "extensionHost",
32 | "request": "launch",
33 | "runtimeExecutable": "${execPath}",
34 | "args": [
35 | "--extensionDevelopmentPath=${workspaceRoot}",
36 | "--extensionTestsPath=${workspaceRoot}/out/test"
37 | ],
38 | "stopOnEntry": false,
39 | "sourceMaps": true,
40 | "outFiles": [ "${workspaceRoot}/{out, node_modules}/**/*.js" ],
41 | "preLaunchTask": "build",
42 | "internalConsoleOptions": "openOnSessionStart"
43 | }
44 | ]
45 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.trimTrailingWhitespace": true,
3 | "files.exclude": {
4 | "out": false // set this to true to hide the "out" folder with the compiled JS files
5 | },
6 | "search.exclude": {
7 | "out": true // set this to false to include "out" folder in search results
8 | },
9 | "typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version
10 | "editor.tabSize": 2,
11 | "editor.insertSpaces": true,
12 | "editor.formatOnSave": true
13 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | // Available variables which can be used inside of strings.
2 | // ${workspaceRoot}: the root folder of the team
3 | // ${file}: the current opened file
4 | // ${fileBasename}: the current opened file's basename
5 | // ${fileDirname}: the current opened file's dirname
6 | // ${fileExtname}: the current opened file's extension
7 | // ${cwd}: the current working directory of the spawned process
8 |
9 | {
10 | "version": "0.1.0",
11 | "command": "gulp",
12 | "isShellCommand": true,
13 | "suppressTaskName": true,
14 | "tasks": [
15 | {
16 | "taskName": "build",
17 | "args": [],
18 | "isBuildCommand": true,
19 | "isWatching": false,
20 | "problemMatcher": "$tsc-watch"
21 | },
22 |
23 | {
24 | "taskName": "yolo",
25 | "args": ["nothing"],
26 | "isBuildCommand": true,
27 | "isWatching": false,
28 | "problemMatcher": "$tsc-watch"
29 | }
30 |
31 | ]
32 | }
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .github/**
2 | .vscode/**
3 | .vscode-test/**
4 | typings/**
5 | out/test/**
6 | test/**
7 | **/*.ts
8 | **/*.map
9 | .gitignore
10 | tsconfig.json
11 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | ## Our Standards
4 | Be nice. Please. Everybody contributing to open source contributes out of good will in their own free time.
5 |
6 | ## Our Responsibilities
7 |
8 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
9 |
10 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 VSCode-Extension
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
VSCodeNeoVim
2 |
Vim emulation for Visual Studio Code.
3 |
4 |
5 |
6 |
7 | VSCodeNeoVim is a [Visual Studio Code](https://code.visualstudio.com/) rewrite of VSCodeVim, changing everything to be backed by Neovim.
8 |
9 | This is the temporary repo for VSCodeNeovim for development purposes. Please submit PRs/issues here. This extension will not be released on the marketplace, but I will be providing a .vsix for testing purposes.
10 |
11 | Some notes on contributing:
12 | * Much of the VSCodeVim code is still in here. The only places it's used are things like some utility Position functions, etc.
13 | * Most of the "hard" work is in extension.ts.
14 | * The rest of the work is in srcNV. NvUtil contains a lot of utility functions with working with neovim rpc requests. RPCHandlers contain handlers for RPC requests.
15 | * You need to have the newest nvim (installed from nightly/master) installed. At the very least, you need a version of neovim that has this issue fixed: https://github.com/neovim/neovim/issues/6166
16 | * The easiest way to test is to have the neovim instance for VSCode be created by connecting to a pipe. In order to do so, set NVIM_LISTEN_ADDRESS equal to `/tmp/nvim`, open a neovim instance, and then open the extension. This allows you to see what's happening on the neovim side (any errors/prompts/etc.) This is how my typical setup for development looks: . There's some code to do this automatically, but it doesn't check if `/tmp/nvim` is a socket, so it may still fail. Also, I think performance is slightly worse when you do this.
17 |
18 |
19 | Other helpful documentation links:
20 | https://vscodevim.slack.com/files/U3EUW86U9/F62R31A5V/Integrating_Neovim_into_VSCode "Design" doc
21 | https://neovim.io/doc/user/api.html#api-global Neovim RPC API documentation
22 | https://neovim.io/doc/user/ui.html Neovim remote UI documentation. We currently aren't using it but will likely use it at some point in the future.
23 | https://github.com/neovim/node-client The node client we're using
24 | https://github.com/lunixbochs/ActualVim Another neovim backed vim plugin (for sublime)
25 |
26 |
27 | Important discussions links:
28 | https://gitter.im/neovim/neovim For talking to the neovim devs
29 | https://gitter.im/neovim/node-client For talking to the neovim node-client devs
30 | https://vscodevim.slack.com/ For talking to the VSCodeVim devs
31 |
32 | Important Neovim PRs to follow:
33 | https://github.com/neovim/neovim/pull/5269 Text Diffs (so we don't have to sync the entire buffer each time)
34 |
35 | Some screenshots (kinda hard to show what's changed without at least a gif...):
36 | Wildmenu working!
37 | 
38 | Autocomplete working!
39 | 
40 |
--------------------------------------------------------------------------------
/ROADMAP.md:
--------------------------------------------------------------------------------
1 | ## Key
2 |
3 | :white_check_mark: - command done
4 |
5 | :white_check_mark: :star: - command done with VS Code specific customization
6 |
7 | :warning: - some variations of the command are not supported
8 |
9 | :running: - work in progress
10 |
11 | :arrow_down: - command is low priority; open an issue (or thumbs up the relevant issue) if you want to see it sooner
12 |
13 | :x: - command impossible with current VSCode API
14 |
15 | :1234: - command accepts numeric prefix
16 |
17 | ## Roadmap
18 |
19 | These are the big Vim features, put generally in the order in which we plan to implement them.
20 |
21 | Status | Command
22 | ---|--------
23 | :white_check_mark: | Normal Mode
24 | :white_check_mark: | Insert Mode
25 | :white_check_mark: | Visual Mode
26 | :white_check_mark: | Visual Line Mode
27 | :white_check_mark: | Number Prefixes
28 | :white_check_mark: | . Operator
29 | :white_check_mark: | Searching with / and ?
30 | :white_check_mark: | Correct Undo/Redo
31 | :warning: | Command Remapping
32 | :warning: | Marks
33 | :white_check_mark: | Text Objects
34 | :white_check_mark: | Visual Block Mode
35 | :white_check_mark: | Replace Mode
36 | :white_check_mark: | Multiple Select Mode
37 | :warning: | Macros
38 | :warning: | Buffer/Window/Tab
39 |
40 |
41 | Now follows an exhaustive list of every known Vim command that we could find.
42 |
43 | ## Custom commands
44 |
45 | * `gh` - show the hover tooltip.
46 | * `gb` - add an additional cursor at the next place that matches `*`.
47 |
48 | ## Left-right motions
49 |
50 | Status | Command | Description
51 | ---|--------|------------
52 | :white_check_mark: |:1234: h | left (also: CTRL-H, BS, or Left key)
53 | :white_check_mark: |:1234: l | right (also: Space or Right key)
54 | :white_check_mark: | 0 | to first character in the line (also: Home key)
55 | :white_check_mark: | ^ | to first non-blank character in the line
56 | :white_check_mark: |:1234: $ | to the last character in the line (N-1 lines lower) (also: End key)
57 | :white_check_mark: | g0 | to first character in screen line (differs from "0" when lines wrap)
58 | :white_check_mark: | g^ | to first non-blank character in screen line (differs from "^" when lines wrap)
59 | :white_check_mark: |:1234: g$ | to last character in screen line (differs from "$" when lines wrap)
60 | :white_check_mark: | gm | to middle of the screen line
61 | :white_check_mark: |:1234: \| | to column N (default: 1)
62 | :white_check_mark: |:1234: f{char} | to the Nth occurrence of {char} to the right
63 | :white_check_mark: |:1234: F{char} | to the Nth occurrence of {char} to the left
64 | :white_check_mark: |:1234: t{char} | till before the Nth occurrence of {char} to the right
65 | :white_check_mark: |:1234: T{char} | till before the Nth occurrence of {char} to the left
66 | :white_check_mark: |:1234: ; | repeat the last "f", "F", "t", or "T" N times
67 | :white_check_mark: |:1234: , | repeat the last "f", "F", "t", or "T" N times in opposite direction
68 |
69 | ## Up-down motions
70 |
71 | Status | Command | Description
72 | ---|--------|------------
73 | :white_check_mark: | :1234: k | up N lines (also: CTRL-P and Up)
74 | :white_check_mark: | :1234: j | up N lidown N lines (also: CTRL-J, CTRL-N, NL, and Down)
75 | :white_check_mark: | :1234: - | up N lines, on the first non-blank character
76 | :white_check_mark: | :1234: + | down N lines, on the first non-blank character (also: CTRL-M and CR)
77 | :white_check_mark: | :1234: _ | down N-1 lines, on the first non-blank character
78 | :white_check_mark: | :1234: G | goto line N (default: last line), on the first non-blank character
79 | :white_check_mark: | :1234: gg | goto line N (default: first line), on the first non-blank character
80 | :white_check_mark: | :1234: % | goto line N percentage down in the file; N must be given, otherwise it is the |%| command
81 | :white_check_mark: | :1234: gk | up N screen lines (differs from "k" when line wraps)
82 | :white_check_mark: | :1234: gj | own N screen lines (differs from "j" when line wraps)
83 |
84 | ## Text object motions
85 |
86 | Status | Command | Description
87 | ---|--------|------------
88 | :white_check_mark: | :1234: w | N words forward
89 | :white_check_mark: | :1234: W | N blank-separated |WORD|s forward
90 | :white_check_mark: | :1234: e | N words forward to the end of the Nth word
91 | :white_check_mark: | :1234: E | N words forward to the end of the Nth blank-separated |WORD|
92 | :white_check_mark: | :1234: b | N words backward
93 | :white_check_mark: | :1234: B | N blank-separated |WORD|s backward
94 | :white_check_mark: | :1234: ge | N words backward to the end of the Nth word
95 | :white_check_mark: | :1234: gE | N words backward to the end of the Nth blank-separated |WORD|
96 | :white_check_mark: | :1234: ) | N sentences forward
97 | :white_check_mark: | :1234: ( | N sentences backward
98 | :white_check_mark: | :1234: } | N paragraphs forward
99 | :white_check_mark: | :1234: { | N paragraphs backward
100 | :white_check_mark: | :1234: ]] | N sections forward, at start of section
101 | :white_check_mark: | :1234: [[ | N sections backward, at start of section
102 | :white_check_mark: | :1234: ][ | N sections forward, at end of section
103 | :white_check_mark: | :1234: [] | N sections backward, at end of section
104 | :white_check_mark: | :1234: [( | N times back to unclosed '('
105 | :white_check_mark: | :1234: [{ | N times back to unclosed '{'
106 | :arrow_down: | :1234: [m | N times back to start of method (for Java)
107 | :arrow_down: | :1234: [M | N times back to end of method (for Java)
108 | :white_check_mark: | :1234: ]) | N times forward to unclosed ')'
109 | :white_check_mark: | :1234: ]} | N times forward to unclosed '}'
110 | :arrow_down: | :1234: ]m | N times forward to start of method (for Java)
111 | :arrow_down: | :1234: ]M | N times forward to end of method (for Java)
112 | :arrow_down: | :1234: [# | N times back to unclosed "#if" or "#else"
113 | :arrow_down: | :1234: ]# | N times forward to unclosed "#else" or "#endif"
114 | :arrow_down: | :1234: [* | N times back to start of a C comment "/*"
115 | :arrow_down: | :1234: ]* | N times forward to end of a C comment "*/"
116 |
117 | ## Pattern searches
118 |
119 | Status | Command | Description | Note
120 | ---|--------|------------|------------------
121 | :white_check_mark: :star: | :1234: `/{pattern}[/[offset]]` | search forward for the Nth occurrence of {pattern} | Currently we only support JavaScript Regex but not Vim's in-house Regex engine.
122 | :white_check_mark: :star: | :1234: `?{pattern}[?[offset]]` | search backward for the Nth occurrence of {pattern} | Currently we only support JavaScript Regex but not Vim's in-house Regex engine.
123 | :warning: | :1234: `/` | repeat last search, in the forward direction | {count} is not supported.
124 | :warning: | :1234: `?` | repeat last search, in the backward direction | {count} is not supported.
125 | :warning: | :1234: n | repeat last search | {count} is not supported.
126 | :warning: | :1234: N | repeat last search, in opposite direction | {count} is not supported.
127 | :white_check_mark: | :1234: * | search forward for the identifier under the cursor
128 | :white_check_mark: | :1234: # | search backward for the identifier under the cursor
129 | :arrow_down: | :1234: g* | like "*", but also find partial matches
130 | :arrow_down: | :1234: g# | like "#", but also find partial matches
131 | :white_check_mark: | gd | goto local declaration of identifier under the cursor
132 | :arrow_down: | gD | goto global declaration of identifier under the cursor
133 |
134 | ## Marks and motions
135 |
136 | Status | Command | Description
137 | ---|--------|------------------------------
138 | :white_check_mark: | m{a-zA-Z} | mark current position with mark {a-zA-Z}
139 | :white_check_mark:| `{a-z} | go to mark {a-z} within current file
140 | :white_check_mark:| `{A-Z} | go to mark {A-Z} in any file
141 | :white_check_mark:| `{0-9} | go to the position where Vim was previously exited
142 | :arrow_down: | `` | go to the position before the last jump
143 | :arrow_down: | `" | go to the position when last editing this file
144 | :arrow_down: | `[ | go to the start of the previously operated or put text
145 | :arrow_down: | `] | go to the end of the previously operated or put text
146 | :arrow_down: | `< | go to the start of the (previous) Visual area
147 | :arrow_down: | `> | go to the end of the (previous) Visual area
148 | :arrow_down: | `. | go to the position of the last change in this file
149 | :arrow_down: | '{a-zA-Z0-9[]'"<>.} | same as `, but on the first non-blank in the line
150 | :arrow_down: | :marks | print the active marks
151 | :arrow_down: | :1234: CTRL-O | go to Nth older position in jump list
152 | :arrow_down: | :1234: CTRL-I | go to Nth newer position in jump list
153 | :arrow_down: | :ju[mps] | print the jump list
154 |
155 | ## Various motions
156 |
157 | Status | Command | Description
158 | ---|--------|------------------------------
159 | :white_check_mark: | % | find the next brace, bracket, comment, or "#if"/ "#else"/"#endif" in this line and go to its match
160 | :white_check_mark: |:1234: H | go to the Nth line in the window, on the first non-blank
161 | :white_check_mark: | M | go to the middle line in the window, on the first non-blank
162 | :white_check_mark: |:1234: L | go to the Nth line from the bottom, on the first non-blank
163 | :arrow_down:|:1234: go | go to Nth byte in the buffer
164 | :arrow_down:|:[range]go[to] [off] | go to [off] byte in the buffer
165 |
166 | ## Using tags
167 |
168 | The following are all marked low priority because VSCode has very good support for tags with Goto Symbol. Try it from the command palette if you haven't yet!
169 |
170 | Status | Command | Description
171 | ---|--------|------------------------------
172 | :arrow_down:| :ta[g][!] {tag} | jump to tag {tag}
173 | :arrow_down:| :[count]ta[g][!] | jump to [count]'th newer tag in tag list
174 | :arrow_down:| CTRL-] | jump to the tag under cursor, unless changes have been made
175 | :arrow_down:| :ts[elect][!] [tag] | list matching tags and select one to jump to
176 | :arrow_down:| :tj[ump][!] [tag] | jump to tag [tag] or select from list when there are multiple matches
177 | :arrow_down:| :lt[ag][!] [tag] | jump to tag [tag] and add matching tags to the location list
178 | :arrow_down:| :tagsa | print tag list
179 | :arrow_down:| :1234: CTRL-T | jump back from Nth older tag in tag list
180 | :arrow_down:| :[count]po[p][!] | jump back from [count]'th older tag in tag list
181 | :arrow_down:| :[count]tn[ext][!] | jump to [count]'th next matching tag
182 | :arrow_down:| :[count]tp[revious][!] | jump to [count]'th previous matching tag
183 | :arrow_down:| :[count]tr[ewind][!] | jump to [count]'th matching tag
184 | :arrow_down:| :tl[ast][!] | jump to last matching tag
185 | :arrow_down:| :pt[ag] {tag} | open a preview window to show tag {tag}
186 | :arrow_down:| CTRL-W } | like CTRL-] but show tag in preview window
187 | :arrow_down:| :pts[elect] | like ":tselect" but show tag in preview window
188 | :arrow_down:| :ptj[ump] | like ":tjump" but show tag in preview window
189 | :arrow_down:| :pc[lose] | close tag preview window
190 | :arrow_down:| CTRL-W z | close tag preview window`
191 |
192 | ## Scrolling
193 |
194 | Status | Command | Description
195 | ---|--------|------------------------------
196 | :white_check_mark: | :1234: CTRL-E | window N lines downwards (default: 1)
197 | :white_check_mark: | :1234: CTRL-D | window N lines Downwards (default: 1/2 window)
198 | :white_check_mark: | :1234: CTRL-F | window N pages Forwards (downwards)
199 | :white_check_mark: | :1234: CTRL-Y | window N lines upwards (default: 1)
200 | :white_check_mark: | :1234: CTRL-U | window N lines Upwards (default: 1/2 window)
201 | :white_check_mark: | :1234: CTRL-B | window N pages Backwards (upwards)
202 | :white_check_mark: | z CR or zt | redraw, current line at top of window
203 | :white_check_mark: | z. or zz | redraw, current line at center of window
204 | :white_check_mark: | z- or zb | redraw, current line at bottom of window
205 |
206 | These only work when 'wrap' is off:
207 |
208 | Status | Command | Description | Note
209 | ---|--------|------------------|------------
210 | :white_check_mark: :star: | :1234: zh | scroll screen N characters to the right | In Code, the cursor wil always move when you run this command, whether the horizontal scrollbar moves or not.
211 | :white_check_mark: :star: | :1234: zl | scroll screen N characters to the left | As above
212 | :white_check_mark: :star: | :1234: zH | scroll screen half a screenwidth to the right | As above
213 | :white_check_mark: :star: | :1234: zL | scroll screen half a screenwidth to the left | As above
214 |
215 | ## Inserting text
216 |
217 | Status | Command | Description
218 | ---|--------|------------------------------
219 | :white_check_mark: | :1234: a | append text after the cursor (N times)
220 | :white_check_mark: | :1234: A | append text at the end of the line (N times)
221 | :white_check_mark: | :1234: i | insert text before the cursor (N times) (also: Insert)
222 | :white_check_mark: | :1234: I | insert text before the first non-blank in the line (N times)
223 | :white_check_mark: | :1234: gI | insert text in column 1 (N times)
224 | :white_check_mark: | :1234: o | open a new line below the current line, append text (N times)
225 | :white_check_mark: | :1234: O | open a new line above the current line, append text (N times)
226 |
227 | in Visual block mode:
228 |
229 | Status | Command | Description
230 | ---|--------|------------------------------
231 | :white_check_mark:| I | insert the same text in front of all the selected lines
232 | :white_check_mark:| A | append the same text after all the selected lines
233 |
234 | ## Insert mode keys
235 |
236 | leaving Insert mode:
237 |
238 | Status | Command | Description
239 | ---|--------|------------------------------
240 | :white_check_mark: | Esc | end Insert mode, back to Normal mode
241 | :white_check_mark: | CTRL-C | like Esc, but do not use an abbreviation
242 | :white_check_mark: | CTRL-O {command} | execute {command} and return to Insert mode
243 |
244 | moving around:
245 |
246 | Status | Command | Description
247 | ---|--------|------------------------------
248 | :white_check_mark: | cursor keys | move cursor left/right/up/down
249 | :white_check_mark: | shift-left/right | one word left/right
250 | :white_check_mark: | shift-up/down | one screenful backward/forward
251 | :white_check_mark: | End | cursor after last character in the line
252 | :white_check_mark: | Home | cursor to first character in the line
253 |
254 | ## Special keys in Insert mode
255 |
256 | Status | Command | Description | Note
257 | ---|--------|-----------|-------------------
258 | :arrow_down: |CTRL-V {char}.. | insert character literally, or enter decimal byte value
259 | :warning: | NL or CR or CTRL-M or CTRL-J | begin new line | CTRL-M and CTRL-J are not supported
260 | :white_check_mark: | CTRL-E | insert the character from below the cursor
261 | :white_check_mark: | CTRL-Y | insert the character from above the cursor
262 | :white_check_mark: :star: | CTRL-A | insert previously inserted text | We apply previously document change made in previous Insert session and we only apply changes that happen under cursor
263 | :white_check_mark: :star: | CTRL-@ | insert previously inserted text and stop Insert mode | As above
264 | :white_check_mark: | CTRL-R {0-9a-z%#:.-="} | insert the contents of a register
265 | :white_check_mark: | CTRL-N | insert next match of identifier before the cursor
266 | :white_check_mark: | CTRL-P | insert previous match of identifier before the cursor
267 | :arrow_down:| CTRL-X ... | complete the word before the cursor in various ways
268 | :white_check_mark: | BS or CTRL-H | delete the character before the cursor
269 | :white_check_mark: | Del | delete the character under the cursor
270 | :white_check_mark: | CTRL-W | delete word before the cursor
271 | :white_check_mark: | CTRL-U | delete all entered characters in the current line
272 | :white_check_mark: | CTRL-T | insert one shiftwidth of indent in front of the current line
273 | :white_check_mark: | CTRL-D | delete one shiftwidth of indent in front of the current line
274 | :arrow_down: | 0 CTRL-D | delete all indent in the current line
275 | :arrow_down: | ^ CTRL-D | delete all indent in the current line, restore indent in next line
276 |
277 | ## Digraphs
278 |
279 | Status | Command | Description
280 | ---|--------|------------------------------
281 | :arrow_down: | :dig[raphs] | show current list of digraphs
282 | :arrow_down: | :dig[raphs] {char1}{char2} {number} ... | add digraph(s) to the list
283 |
284 | ## Special inserts
285 |
286 | Status | Command | Description
287 | ---|--------|------------------------------
288 | :warning: | :r [file] | insert the contents of [file] below the cursor
289 | :warning: | :r! {command} | insert the standard output of {command} below the cursor
290 |
291 | ## Deleting text
292 |
293 | Status | Command | Description
294 | ---|--------|------------------------------
295 | :white_check_mark: | :1234: x | delete N characters under and after the cursor
296 | :white_check_mark: | :1234: Del | delete N characters under and after the cursor
297 | :white_check_mark: | :1234: X | delete N characters before the cursor
298 | :white_check_mark: | :1234: d{motion} | delete the text that is moved over with {motion}
299 | :white_check_mark: | {visual}d | delete the highlighted text
300 | :white_check_mark: | :1234: dd | delete N lines
301 | :white_check_mark: | :1234: D | delete to the end of the line (and N-1 more lines)
302 | :white_check_mark: | :1234: J | join N-1 lines (delete EOLs)
303 | :white_check_mark: | {visual}J | join the highlighted lines
304 | :white_check_mark: | :1234: gJ | like "J", but without inserting spaces
305 | :white_check_mark:| {visual}gJ | like "{visual}J", but without inserting spaces
306 | :white_check_mark:| :[range]d [x] | delete [range] lines [into register x]
307 |
308 | ## Copying and moving text
309 |
310 | Miscellanea:
311 |
312 | * We don't support read only registers.
313 |
314 | Status | Command | Description | Note
315 | ---|--------|-------------|-----------------
316 | :warning: | "{char} | use register {char} for the next delete, yank, or put | read only registers are not supported
317 | :white_check_mark: | "* | use register `*` to access system clipboard
318 | :white_check_mark: | :reg | show the contents of all registers
319 | :white_check_mark: | :reg {arg} | show the contents of registers mentioned in {arg}
320 | :white_check_mark: | :1234: y{motion} | yank the text moved over with {motion} into a register
321 | :white_check_mark: | {visual}y | yank the highlighted text into a register
322 | :white_check_mark: | :1234: yy | yank N lines into a register
323 | :white_check_mark: | :1234: Y | yank N lines into a register
324 | :white_check_mark: | :1234: p | put a register after the cursor position (N times)
325 | :white_check_mark: | :1234: P | put a register before the cursor position (N times)
326 | :white_check_mark: | :1234: ]p | like p, but adjust indent to current line
327 | :white_check_mark: | :1234: [p | like P, but adjust indent to current line
328 | :white_check_mark: | :1234: gp | like p, but leave cursor after the new text
329 | :white_check_mark: | :1234: gP | like P, but leave cursor after the new text
330 |
331 | ## Changing text
332 |
333 | Status | Command | Description | Note
334 | ---|--------|------------|------------------
335 | :white_check_mark: | :1234: r{char} | replace N characters with {char}
336 | :arrow_down: | :1234: gr{char} | replace N characters without affecting layout
337 | :white_check_mark: :star: | :1234: R | enter Replace mode (repeat the entered text N times) | {count} is not supported
338 | :arrow_down: | :1234: gR | enter virtual Replace mode: Like Replace mode but without affecting layout
339 | :white_check_mark:| {visual}r{char} | in Visual block, visual, or visual line modes: Replace each char of the selected text with {char}
340 |
341 | (change = delete text and enter Insert mode)
342 |
343 | Status | Command | Description
344 | ---|--------|------------------------------
345 | :white_check_mark: | :1234: c{motion} | change the text that is moved over with {motion}
346 | :white_check_mark: | {visual}c | change the highlighted text
347 | :white_check_mark: | :1234: cc | change N lines
348 | :white_check_mark: | :1234: S | change N lines
349 | :white_check_mark: | :1234: C | change to the end of the line (and N-1 more lines)
350 | :white_check_mark: | :1234: s | change N characters
351 | :white_check_mark: | {visual}c | in Visual block mode: Change each of the selected lines with the entered text
352 | :white_check_mark: | {visual}C | in Visual block mode: Change each of the selected lines until end-of-line with the entered text
353 | :white_check_mark: | switch case for highlighted text
354 | :white_check_mark: | {visual}u | make highlighted text lowercase
355 | :white_check_mark: | {visual}U | make highlighted text uppercase
356 | :white_check_mark: | g~{motion} | switch case for the text that is moved over with {motion}
357 | :white_check_mark: | gu{motion} | make the text that is moved over with {motion} lowercase
358 | :white_check_mark: | gU{motion} | make the text that is moved over with {motion} uppercase
359 | :arrow_down: | {visual}g? | perform rot13 encoding on highlighted text
360 | :arrow_down: | g?{motion} | perform rot13 encoding on the text that is moved over with {motion}
361 | :white_check_mark: | :1234: CTRL-A | add N to the number at or after the cursor
362 | :white_check_mark: | :1234: CTRL-X | subtract N from the number at or after the cursor
363 | :white_check_mark: | :1234: <{motion} | move the lines that are moved over with {motion} one shiftwidth left
364 | :white_check_mark: | :1234: << | move N lines one shiftwidth left
365 | :white_check_mark: | :1234: >{motion} | move the lines that are moved over with {motion} one shiftwidth right
366 | :white_check_mark: | :1234: >> | move N lines one shiftwidth right
367 | :white_check_mark:| :1234: gq{motion}| format the lines that are moved over with {motion} to 'textwidth' length
368 | :arrow_down: | :[range]ce[nter] [width] | center the lines in [range]
369 | :arrow_down: | :[range]le[ft] [indent] | left-align the lines in [range] (with [indent])
370 | :arrow_down: | :[ranee]ri[ght] [width] | right-align the lines in [range]
371 |
372 | ## Complex changes
373 |
374 | Status | Command | Description | Note
375 | ---|--------|------------------|------------
376 | :arrow_down: | :1234: `!{motion}{command}` | filter the lines that are moved over through {command}
377 | :arrow_down: | :1234: `!!{command}` | filter N lines through {command}
378 | :arrow_down: | `{visual}!{command}` | filter the highlighted lines through {command}
379 | :arrow_down: | `:[range]! {command}` | filter [range] lines through {command}
380 | :white_check_mark: | :1234: ={motion} | filter the lines that are moved over through 'equalprg'
381 | :arrow_down:| :1234: == | filter N lines through 'equalprg'
382 | :white_check_mark: | {visual}= | filter the highlighted lines through 'equalprg'
383 | :white_check_mark: :star: :warning: | :[range]s[ubstitute]/{pattern}/{string}/[g][c] | substitute {pattern} by {string} in [range] lines; with [g], replace all occurrences of {pattern}; with [c], confirm each replacement | Currently we only support JavaScript Regex and only options `gi` are implemented
384 | :arrow_down: | :[range]s[ubstitute] [g][c] | repeat previous ":s" with new range and options
385 | :arrow_down: | & | Repeat previous ":s" on current line without options
386 | :arrow_down: | :[range]ret[ab][!] [tabstop] | set 'tabstop' to new value and adjust white space accordingly
387 |
388 | ## Visual mode
389 |
390 | Status | Command | Description
391 | ---|--------|------------------------------
392 | :white_check_mark: | v | start highlighting characters
393 | :white_check_mark: | V | start highlighting linewise
394 | :white_check_mark:| o | exchange cursor position with start of highlighting
395 | :white_check_mark:| gv | start highlighting on previous visual area
396 | :white_check_mark: | v | highlight characters or stop highlighting
397 | :white_check_mark: | V | highlight linewise or stop highlighting
398 | :white_check_mark: | CTRL-V | highlight blockwise or stop highlighting
399 |
400 | ## Text objects (only in Visual mode or after an operator)
401 |
402 | Status | Command | Description
403 | ---|--------|------------------------------
404 | :white_check_mark: | :1234: aw | Select "a word"
405 | :white_check_mark: | :1234: iw | Select "inner word"
406 | :white_check_mark: | :1234: aW | Select "a |WORD|"
407 | :white_check_mark: | :1234: iW | Select "inner |WORD|"
408 | :white_check_mark: | :1234: as | Select "a sentence"
409 | :white_check_mark: | :1234: is | Select "inner sentence"
410 | :white_check_mark: | :1234: ap | Select "a paragraph"
411 | :white_check_mark: | :1234: ip | Select "inner paragraph"
412 | :white_check_mark: | :1234: a], a[ | select '[' ']' blocks
413 | :white_check_mark: | :1234: i], i[ | select inner '[' ']' blocks
414 | :white_check_mark: | :1234: ab, a(, a) | Select "a block" (from "[(" to "])")
415 | :white_check_mark: | :1234: ib, i), i( | Select "inner block" (from "[(" to "])")
416 | :white_check_mark: | :1234: a>, a< | Select "a <> block"
417 | :white_check_mark: | :1234: i>, i< | Select "inner <> block"
418 | :white_check_mark: | :1234: aB, a{, a} | Select "a Block" (from "[{" to "]}")
419 | :white_check_mark: | :1234: iB, i{, i} | Select "inner Block" (from "[{" to "]}")
420 | :white_check_mark: | :1234: at | Select "a tag block" (from <aaa> to </aaa>)
421 | :white_check_mark: | :1234: it | Select "inner tag block" (from <aaa> to </aaa>)
422 | :white_check_mark: | :1234: a' | Select "a single quoted string"
423 | :white_check_mark: | :1234: i' | Select "inner single quoted string"
424 | :white_check_mark: | :1234: a" | Select "a double quoted string"
425 | :white_check_mark: | :1234: i" | Select "inner double quoted string"
426 | :white_check_mark: | :1234: a` | Select "a backward quoted string"
427 | :white_check_mark: | :1234: i` | Select "inner backward quoted string"
428 |
429 | ## Repeating commands
430 |
431 | Status | Command | Description | Note
432 | ---|--------|--------------|----------------
433 | :white_check_mark: :star: | :1234: . | repeat last change (with count replaced with N) | Content changes that don't happen under cursor can not be repeated.
434 | :white_check_mark:| q{a-z} | record typed characters into register {a-z}
435 | :arrow_down: | q{A-Z} | record typed characters, appended to register {a-z}
436 | :white_check_mark:| q | stop recording
437 | :white_check_mark:| :1234: @{a-z} | execute the contents of register {a-z} (N times)
438 | :white_check_mark:| :1234: @@ | repeat previous @{a-z} (N times)
439 | :arrow_down: | :@{a-z} | execute the contents of register {a-z} as an Ex command
440 | :arrow_down: | :@@ | repeat previous :@{a-z}
441 | :arrow_down: | :[range]g[lobal]/{pattern}/[cmd] | execute Ex command [cmd] (default: ":p") on the lines within [range] where {pattern} matches
442 | :arrow_down: | :[range]g[lobal]!/{pattern}/[cmd] | execute Ex command [cmd] (default: ":p") on the lines within [range] where {pattern} does NOT match
443 | :arrow_down: | :so[urce] {file} | read Ex commands from {file}
444 | :arrow_down: | :so[urce]! {file} | read Vim commands from {file}
445 | :arrow_down: | :sl[eep] [sec] | don't do anything for [sec] seconds
446 | :arrow_down: | :1234: gs | goto Sleep for N seconds
447 |
448 | ## options
449 |
450 | Status | Command | Description | Note
451 | ---|--------|---------|---------------------
452 | :arrow_down: | :se[t] | show all modified options
453 | :arrow_down: | :se[t] all | show all non-termcap options
454 | :arrow_down: | :se[t] termcap | show all termcap options
455 | :white_check_mark: | :se[t] {option} | set boolean option (switch it on), show string or number option
456 | :white_check_mark: | :se[t] no{option} | reset boolean option (switch it off)
457 | :white_check_mark: | :se[t] inv{option} |invert boolean option
458 | :white_check_mark: | :se[t] {option}={value} | set string/number option to {value}
459 | :white_check_mark: | :se[t] {option}+={value} | append {value} to string option, add {value} to number option
460 | :white_check_mark: :star:| :se[t] {option}-={value} | remove {value} to string option, subtract {value} from number option | We don't support string option here.
461 | :white_check_mark: | :se[t] {option}? | show value of {option}
462 | :arrow_down: | :se[t] {option}& | reset {option} to its default value
463 | :arrow_down: | :setl[ocal] | like ":set" but set the local value for options that have one
464 | :arrow_down: | :setg[lobal] | like ":set" but set the global value of a local option
465 | :arrow_down: | :fix[del] | set value of 't_kD' according to value of 't_kb'
466 | :arrow_down: | :opt[ions] | open a new window to view and set options, grouped by functionality, a one line explanation and links to the help
467 |
468 | Since the list is too long, now we just put those already supported options here.
469 |
470 | Status | Command | Default Value | Description
471 | ---|--------|-------|------------------------------
472 | :white_check_mark:| tabstop (ts) | 4. we use Code's default value `tabSize` instead of Vim | number of spaces that <Tab> in file uses
473 | :white_check_mark:| hlsearch (hls) | false | When there is a previous search pattern, highlight all its matches.
474 | :white_check_mark:| ignorecase (ic) | true | Ignore case in search patterns.
475 | :white_check_mark:| smartcase (scs) | true | Override the 'ignorecase' option if the search pattern contains upper case characters.
476 | :white_check_mark:| iskeyword (isk) | `@,48-57,_,128-167,224-235` | keywords contain alphanumeric characters and '_'. If there is no user setting for `iskeyword`, we use `editor.wordSeparators` properties.
477 | :white_check_mark:| scroll (scr) | 20 | Number of lines to scroll with CTRL-U and CTRL-D commands.
478 | :white_check_mark:| expandtab (et) | True. we use Code's default value `inserSpaces` instead of Vim | use spaces when <Tab> is inserted
479 | :white_check_mark:| autoindent | true | Keep indentation when doing `cc` or `S` in normal mode to replace a line.
480 |
481 | ## Undo/Redo commands
482 |
483 | Status | Command | Description | Note
484 | ---|--------|-------|------------------------------
485 | :white_check_mark: | :1234: u | undo last N changes | Current implementation may not cover every case perfectly.
486 | :white_check_mark: | :1234: CTRL-R | redo last N undone changes | As above.
487 | :arrow_down: | U | restore last changed line
488 |
489 | ## External commands
490 |
491 | Status | Command | Description
492 | ---|--------|-----------------
493 | :arrow_down: | :sh[ell] | start a shell
494 | :arrow_down: | :!{command} | execute {command} with a shell
495 | :arrow_down: | K | lookup keyword under the cursor with 'keywordprg' program (default: "man")
496 |
497 | ## Ex ranges
498 |
499 | Status | Command | Description | Note
500 | ---|--------|-------|------------------------------
501 | :white_check_mark: | , | separates two line numbers
502 | :white_check_mark: :star: | ; | idem, set cursor to the first line number before interpreting the second one | The cursor movement is not included.
503 | :white_check_mark: | {number} | an absolute line number
504 | :white_check_mark: | . | the current line
505 | :white_check_mark: | $ | the last line in the file
506 | :white_check_mark: | % | equal to 1,$ (the entire file)
507 | :white_check_mark: | * | equal to '<,'> (visual area)
508 | :white_check_mark: | 't | position of mark t
509 | :arrow_down: | /{pattern}[/] | the next line where {pattern} matches
510 | :arrow_down: | ?{pattern}[?] | the previous line where {pattern} matches
511 | :white_check_mark: | +[num] | add [num] to the preceding line number (default: 1)
512 | :white_check_mark: | -[num] | subtract [num] from the preceding line number (default: 1)
513 |
514 | ## Editing a file
515 |
516 | Status | Command | Description | Note
517 | ---|--------|------------------|-----------
518 | :white_check_mark: :star: | :e[dit] {file} | Edit {file}. | We will open file in a new Tab of current Grouped Editor instead of opening in current tab.
519 |
520 | ## Multi-window commands
521 |
522 | Status | Command | Description | Note
523 | ---|--------|-----------------|-------------
524 | :white_check_mark: :star: | :e[dit] {file} | Edit {file}. | We will open file in a new Tab of current Grouped Editor instead of opening in current tab.
525 | :white_check_mark: :star: | <ctrl-w> hl | Switching between windows. | As we don't have the concept of Window in VS Code, we are mapping these commands to switching between Grouped Editors.
526 | :x: | :sp {file} | Split current window in two. | VS Code doesn't support split Window horizontally.
527 | :white_check_mark: :star: | :vsp {file} | Split vertically current window in two. | VS Code only supports three vertical window at most and that's the limitation of this command.
528 | :x: | :new | Create a new window horizontally and start editing an empty file in it. | VS Code doesn't support split Window horizontally.
529 | :white_check_mark: :star: | :vne[w] | Create a new window vertically and start editing an empty file in it. | VS Code only supports three vertical window at most and that's the limitation of this command.
530 |
531 |
532 | ## Tabs
533 |
534 | Status | Command | Description | Note
535 | ---|--------|------------------|------------
536 | :white_check_mark: | :tabn[ext] :1234: | Go to next tab page or tab page {count}. The first tab page has number one.
537 | :white_check_mark: | {count}<C-PageDown>, {count}gt | Same as above
538 | :white_check_mark: | :tabp[revious] :1234: | Go to the previous tab page. Wraps around from the first one to the last one.
539 | :white_check_mark: | :tabN[ext] :1234: | Same as above
540 | :white_check_mark: | {count}<C-PageUp>, {count}gT | Same as above
541 | :white_check_mark: | :tabfir[st] | Go to the first tab page.
542 | :white_check_mark: | :tabl[ast] | Go to the last tab page.
543 | :white_check_mark: | :tabe[dit] {file} | Open a new tab page with an empty window, after the current tab page
544 | :arrow_down: | :[count]tabe[dit], :[count]tabnew | Same as above | [count] is not supported.
545 | :white_check_mark: | :tabnew {file} | Open a new tab page with an empty window, after the current tab page
546 | :arrow_down:| :[count]tab {cmd} | Execute {cmd} and when it opens a new window open a new tab page instead.
547 | :white_check_mark: :star: | :tabc[lose][!] :1234: | Close current tab page or close tab page {count}. | Code will close tab directly without saving.
548 | :white_check_mark: :star: | :tabo[nly][!] | Close all other tab pages. | `!` is not supported, Code will close tab directly without saving.
549 | :white_check_mark: | :tabm[ove] [N] | Move the current tab page to after tab page N.
550 | :arrow_down:| :tabs | List the tab pages and the windows they contain. | You can always use Code's built-in shortcut: `cmd/ctrl+p`
551 | :arrow_down:| :tabd[o] {cmd} | Execute {cmd} in each tab page.
552 |
553 | ## Folding
554 | ### Fold methods
555 | The folding method can be set with the 'foldmethod' option. This is currently not possible as we are relying on Code's Fold logic.
556 |
557 | ### Fold commands
558 |
559 | Pretty much everything fold-related is blocked by [this issue](https://github.com/VSCodeVim/Vim/issues/1004).
560 |
561 | Status | Command | Description
562 | ---|--------|------------------------------
563 | :arrow_down: | zf{motion} or {Visual}zf | Operator to create a fold.
564 | :arrow_down: | zF | Create a fold for [count] lines. Works like "zf".
565 | :arrow_down: | zd | Delete one fold at the cursor.
566 | :arrow_down: | zD | Delete folds recursively at the cursor.
567 | :arrow_down: | zE | Eliminate all folds in the window.
568 | :white_check_mark: | zo | Open one fold under the cursor.When a count is given, that many folds deep will be opened.
569 | :white_check_mark: | zO | Open all folds under the cursor recursively.
570 | :white_check_mark: | zc | Close one fold under the cursor. When a count is given, that many folds deep are closed.
571 | :white_check_mark:| zC | Close all folds under the cursor recursively.
572 | :arrow_down: | za | When on a closed fold: open it. When on an open fold: close it and set 'foldenable'.
573 | :arrow_down: | zA | When on a closed fold: open it recursively. When on an open fold: close it recursively and set 'foldenable'.
574 | :arrow_down: | zv | View cursor line: Open just enough folds to make the line in which the cursor is located not folded.
575 | :arrow_down: | zx | Update folds: Undo manually opened and closed folds: re-apply 'foldlevel', then do "zv": View cursor line.
576 | :arrow_down: | zX | Undo manually opened and closed folds
577 | :arrow_down: | zm | Fold more: Subtract one from 'foldlevel'.
578 | :white_check_mark: | zM | Close all folds: set 'foldlevel' to 0. 'foldenable' will be set.
579 | :arrow_down: | zr | Reduce folding: Add one to 'foldlevel'.
580 | :white_check_mark: | zR | Open all folds. This sets 'foldlevel' to highest fold level.
581 | :arrow_down: | zn | Fold none: reset 'foldenable'. All folds will be open.
582 | :arrow_down: | zN | Fold normal: set 'foldenable'. All folds will be as they were before.
583 | :arrow_down: | zi | Invert 'foldenable'.
584 | :arrow_down: | [z | Move to the start of the current open fold.
585 | :arrow_down: | ]z | Move to the end of the current open fold.
586 | :arrow_down: | zj | Move downwards to the start of the next fold.
587 | :arrow_down: | zk | Move upwards to the end of the previous fold.
588 |
589 | ### Fold options
590 |
591 | Currently we don't support any fold option and we are following Code configurations.
592 |
--------------------------------------------------------------------------------
/STYLE.md:
--------------------------------------------------------------------------------
1 | ## Style Guide
2 |
3 | In addition, to VS Code's [coding guidelines](https://github.com/Microsoft/vscode/wiki/Coding-Guidelines), please adhere to the following:
4 |
5 | * Use `for ... of` whenever possible
6 |
7 | **Rationale:** `for ... of` is awesome. It's more readable than any other variant.
8 |
9 | * Don't use `any` as much as possible
10 |
11 | **Rationale:** The language is called *Type*Script, not *Untyped*Script. :wink: Static typing is wonderful. It catches bugs and improves readability. We should strive to use it as much as possible.
12 |
13 | * Use `const` wherever possible.
14 |
15 | **Rationale:** Instead of reading `const` as "constant value," read it as "single assignment." Yes, it means "constant value" in other programming languages, but it's a little different in JavaScript.
16 |
17 | * When we can't use `const`, use `let`; never `var`
18 |
19 | **Rationale:** `var` trips up programmers in a number of cases - hoisting and closure capture are two big ones. Consider the difference between
20 |
21 | ```
22 | for (var j = 0; j < 5; j++) { setTimeout(() => console.log(j), 5) }
23 | ```
24 |
25 | and
26 |
27 | ```
28 | for (let j = 0; j < 5; j++) { setTimeout(() => console.log(j), 5) }
29 | ```
30 |
31 | Even if you're not capturing the variable, who knows if someone else might later?
32 |
33 |
--------------------------------------------------------------------------------
/designdoc.md:
--------------------------------------------------------------------------------
1 | # Integrating Neovim into VSCode
2 |
3 | ## Things we will not port over from Vim (for now). As in, we will have our own implementations that do not try to match vim behavior
4 | 1. Folds
5 | 2. Splits
6 | 3. Intellisense/autocomplete (this includes go to definition, autocomplete, etc.)
7 | 4. Syntax highlighting
8 | These are all things that I see no benefit in including from vim.
9 |
10 | ## Philosophy
11 | As much as possible, we need to pretend like we're in neovim. That means that when we override `gd`, it needs to look exactly like we just did a `gd`. When we're doing autocomplete, it needs to look like the user typed in the text to neovim.
12 |
13 | ## Overarching strategy
14 | 1. Pass all relevant input to neovim.
15 | 2. Get all relevant information back (text, cursor position, mode, tabline)
16 | Simple enough.
17 |
18 | ## Things I need to figure out
19 | 1. Multicursor.
20 | * How do I ensure that some commands are only performed once?
21 | For example, undo.
22 | * How do I handle operations that are local to each cursor. For example, copy and paste.
23 | * Maybe we can use this? https://github.com/terryma/vim-multiple-cursors
24 | * Will be handled by core neovim (eventually, says @justinmk http://i.imgur.com/jPQtHoU.jpg).
25 |
26 | 2. Handling operators properly
27 | * https://github.com/neovim/neovim/issues/6166
28 | * Done through a hack right now
29 | * This is annoying. We don't want to need to maintain state on the vscode side. This is why commands like 2dd or gqq don't work in ActualVim.
30 |
31 | 3. Ensuring that actions coming in are performed in the correct order.
32 | * Transformation queue?
33 | * I don't think this is an issue if we don't do multiple cursors? nvim.input() isn't blocking, but I'm not sure.
34 |
35 | 4. Handling cross file jumping for commands that we're overriding (gd for example)
36 | * Just open files regularly on editor side, feed it back to neovim, and then handle it regularly.
37 | Flow of events:
38 | 1. "gd" (or other) is pressed in neovim.
39 | 2. A RPC request is made to VSCode.
40 | 3. VSCode receives the request, opens up the necessary file on the neovim side.
41 | 4. nvim.eval("m'") and then make the right jumps through setpos() and such.
42 |
43 | 5. Handling splits/folds.
44 | * All of this should be handled through editor commands.
45 | * We can override in vimrc through a map to a rpc call.
46 | * We need some kind of API for this though, to handle keybindings properly.
47 | * Maybe folds are possible to play nice, but they both seem like fundamental ui incompatibilities.
48 |
49 | 6. Handling settings that must be handled on the vscode side.
50 | * I wonder whether there are some things that won't play nice that we might want to lint for.
51 | * Sync them up either with a .vimrc or at startup. I'm leaning towards in the .vimrc (to maintain transparency)
52 |
53 | 7. Snippets?
54 | * no clue how these are implemented.
55 |
56 | 8. Insert mode autocomplete and such.
57 | * This is tricky. There's a lot of things that mess up the autocompletion engine.
58 |
59 | 9. Editor inserted text
60 | * If we can get a diff we can insert it on the vim side as another action?
61 |
62 | 10. Handling opening files and other such things.
63 | * Autocommands that sync up VSCode and neovim state
64 |
65 | 11. Handling commands that we want vscode to handle.
66 | * Don't pass anything that's not a single character//.
67 | * Have an "ignore this" array.
68 |
69 | 12. Mouse
--------------------------------------------------------------------------------
/extension.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from 'fs';
5 | import * as _ from 'lodash';
6 | import { attach } from 'neovim';
7 | import { NeovimClient } from 'neovim/lib/api/client';
8 | import { TaskQueue } from 'aurelia-task-queue';
9 | import { Position } from './src/common/motion/position';
10 | import { Globals } from './src/globals';
11 | import { Configuration } from './src/configuration/configuration';
12 |
13 | import { spawn } from 'child_process';
14 | import { NvUtil } from './srcNV/nvUtil';
15 | import { RpcRequest } from './srcNV/rpcHandlers';
16 | import { TextEditor } from './src/textEditor';
17 | import { Screen, IgnoredKeys } from './srcNV/screen';
18 | import { VimSettings } from './srcNV/vimSettings';
19 | import { VscHandlers } from './srcNV/vscHandlers';
20 |
21 | interface VSCodeKeybinding {
22 | key: string;
23 | command: string;
24 | when: string;
25 | vimKey: string;
26 | }
27 |
28 | const packagejson: {
29 | contributes: {
30 | keybindings: VSCodeKeybinding[];
31 | };
32 | } = require('../package.json'); // out/../package.json
33 |
34 | export namespace Vim {
35 | export let nv: NeovimClient;
36 | export let channelId: number;
37 | export let mode: { mode: string; blocking: boolean } = { mode: 'n', blocking: false };
38 | export let screen: Screen;
39 | export let prevState: { bufferTick: number } = {
40 | bufferTick: -1,
41 | };
42 | export let numVimChangesToApply = 0;
43 | export let taskQueue = new TaskQueue();
44 | // We're connecting to an already existing terminal instance, so externalized ui won't work.
45 | export let DEBUG: boolean;
46 | }
47 |
48 | export async function activate(context: vscode.ExtensionContext) {
49 | vscode.workspace.onDidCloseTextDocument(async event => {
50 | const deleted_file = event.fileName;
51 | let buf_id = await nvim.call('bufnr', [`^${deleted_file}$`]);
52 | if (buf_id === -1) {
53 | return;
54 | }
55 | // await nvim.command(`noautocmd ${buf_id}bw!`);
56 | });
57 |
58 | vscode.window.onDidChangeActiveTextEditor(VscHandlers.handleActiveTextEditorChange, this);
59 |
60 | vscode.window.onDidChangeTextEditorSelection(async e => {
61 | if (e.kind === vscode.TextEditorSelectionChangeKind.Mouse) {
62 | if (e.selections[0]) {
63 | await NvUtil.setSelection(e.selections[0]);
64 | }
65 | }
66 | });
67 | vscode.workspace.onDidChangeTextDocument(VscHandlers.handleTextDocumentChange);
68 |
69 | // Event to update active configuration items when changed without restarting vscode
70 | vscode.workspace.onDidChangeConfiguration((e: void) => {
71 | Configuration.updateConfiguration();
72 | });
73 |
74 | overrideCommand(context, 'type', async args => {
75 | Vim.taskQueue.queueMicroTask(() => {
76 | VscHandlers.handleKeyEventNV(args.text);
77 | });
78 | });
79 |
80 | const keysToBind = packagejson.contributes.keybindings;
81 | const ignoreKeys = Configuration.ignoreKeys;
82 |
83 | for (let key of keysToBind) {
84 | if (ignoreKeys.all.indexOf(key.vimKey) !== -1) {
85 | continue;
86 | }
87 | vscode.commands.executeCommand('setContext', `vim.use_${key.vimKey}`, true);
88 | registerCommand(context, key.command, () => {
89 | Vim.taskQueue.queueMicroTask(() => {
90 | VscHandlers.handleKeyEventNV(`${key.vimKey}`);
91 | });
92 | });
93 | }
94 |
95 | const proc = spawn(
96 | Configuration.neovimPath,
97 | [
98 | // '-u',
99 | // 'NONE',
100 | '-N',
101 | '--embed',
102 | vscode.window.activeTextEditor ? vscode.window.activeTextEditor!.document.fileName : '',
103 | ],
104 | {
105 | cwd: __dirname,
106 | }
107 | );
108 |
109 | proc.on('error', function (err) {
110 | console.log(err);
111 | vscode.window.showErrorMessage('Unable to setup neovim instance! Check your path.');
112 | });
113 | let nvim: NeovimClient;
114 | if (fs.existsSync('/tmp/nvim') && fs.lstatSync('/tmp/nvim').isSocket()) {
115 | nvim = attach({ socket: '/tmp/nvim' });
116 | Vim.DEBUG = true;
117 | } else {
118 | nvim = attach({ proc: proc });
119 | Vim.DEBUG = false;
120 | }
121 | Vim.nv = nvim;
122 |
123 | Vim.channelId = (await nvim.requestApi())[0] as number;
124 |
125 | const WIDTH = 50;
126 | const HEIGHT = 36;
127 | nvim.uiAttach(WIDTH, HEIGHT, { ext_cmdline: true, ext_wildmenu: true });
128 | Vim.screen = new Screen({ width: WIDTH, height: HEIGHT });
129 |
130 | const code = `
131 | function _vscode_copy_text(text, line, char)
132 | vim.api.nvim_command('undojoin')
133 | vim.api.nvim_buf_set_lines(0, 0, -1, true, text)
134 | vim.api.nvim_call_function('setpos', {'.', {0, line, char, false}})
135 | end
136 | `;
137 |
138 | await Vim.nv.lua(code, []);
139 | await nvim.command('autocmd!');
140 |
141 | // todo(chilli): Create this map just from RPCHandlers and a decorator.
142 | const autocmdMap: { [autocmd: string]: string } = {
143 | BufWriteCmd: 'writeBuf',
144 | QuitPre: 'closeBuf',
145 | BufEnter: 'enterBuf',
146 | TabNewEntered: 'newTabEntered',
147 | };
148 |
149 | for (const autocmd of Object.keys(autocmdMap)) {
150 | await nvim.command(
151 | `autocmd ${autocmd} * :call rpcrequest(${Vim.channelId}, "${autocmdMap[
152 | autocmd
153 | ]}", expand(""), fnamemodify(expand(''), ':p'), expand(""))`
154 | );
155 | }
156 |
157 | // Overriding commands to handle them on the vscode side.
158 | // await nvim.command(`nnoremap gd :call rpcrequest(${Vim.channelId},"goToDefinition")`);
159 |
160 | await NvUtil.setSettings(['noswapfile', 'hidden']);
161 | nvim.on('notification', (method: any, args: any) => {
162 | if (vscode.window.activeTextEditor && method === 'redraw') {
163 | Vim.screen.redraw(args);
164 | }
165 | });
166 |
167 | nvim.on('request', async (method: string, args: Array, resp: any) => {
168 | if (RpcRequest[method] !== undefined) {
169 | const f = RpcRequest[method];
170 | f(args, resp);
171 | } else {
172 | console.log(`${method} is not defined!`);
173 | }
174 | });
175 |
176 | if (vscode.window.activeTextEditor) {
177 | await VscHandlers.handleActiveTextEditorChange();
178 | }
179 | }
180 |
181 | function overrideCommand(
182 | context: vscode.ExtensionContext,
183 | command: string,
184 | callback: (...args: any[]) => any
185 | ) {
186 | let disposable = vscode.commands.registerCommand(command, async args => {
187 | if (!vscode.window.activeTextEditor) {
188 | return;
189 | }
190 |
191 | if (
192 | vscode.window.activeTextEditor.document &&
193 | vscode.window.activeTextEditor.document.uri.toString() === 'debug:input'
194 | ) {
195 | await vscode.commands.executeCommand('default:' + command, args);
196 | return;
197 | }
198 |
199 | callback(args);
200 | });
201 | context.subscriptions.push(disposable);
202 | }
203 |
204 | function registerCommand(
205 | context: vscode.ExtensionContext,
206 | command: string,
207 | callback: (...args: any[]) => any
208 | ) {
209 | let disposable = vscode.commands.registerCommand(command, async args => {
210 | if (!vscode.window.activeTextEditor) {
211 | return;
212 | }
213 |
214 | callback(args);
215 | });
216 | context.subscriptions.push(disposable);
217 | }
218 |
219 | process.on('unhandledRejection', function (reason: any, p: any) {
220 | console.log('Unhandled Rejection at: Promise ', p, ' reason: ', reason);
221 | });
222 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | bump = require('gulp-bump'),
3 | git = require('gulp-git'),
4 | inject = require('gulp-inject-string'),
5 | merge = require('merge-stream'),
6 | tag_version = require('gulp-tag-version'),
7 | tslint = require('gulp-tslint'),
8 | typings = require('gulp-typings'),
9 | shell = require('gulp-shell');
10 |
11 | var paths = {
12 | src_ts: "src/**/*.ts",
13 | tests_ts: "test/**/*.ts"
14 | };
15 |
16 | function versionBump(semver) {
17 | return gulp.src(['./package.json'])
18 | .pipe(bump({type: semver}))
19 | .pipe(gulp.dest('./'))
20 | .pipe(git.commit('bump package version'))
21 | .pipe(tag_version());
22 | }
23 |
24 | gulp.task('typings', function () {
25 | return gulp.src('./typings.json')
26 | .pipe(typings());
27 | });
28 |
29 | gulp.task('typings-vscode-definitions', ['typings'], function() {
30 | // add vscode definitions
31 | return gulp.src('./typings/index.d.ts').pipe(gulp.dest('./typings'));
32 | })
33 |
34 | gulp.task('tslint', function() {
35 | var tslintOptions = {
36 | summarizeFailureOutput: true
37 | };
38 |
39 | var srcs = gulp.src(paths.src_ts)
40 | .pipe(tslint({ formatter: 'verbose' }))
41 | .pipe(tslint.report(tslintOptions));
42 | var tests = gulp.src(paths.tests_ts)
43 | .pipe(tslint({ formatter: 'verbose' }))
44 | .pipe(tslint.report(tslintOptions));
45 | return merge(srcs, tests);
46 | });
47 |
48 | gulp.task('default', ['tslint', 'compile']);
49 |
50 | gulp.task('compile', shell.task(['npm run vscode:prepublish']));
51 | gulp.task('watch', shell.task(['npm run compile']));
52 | gulp.task('init', ['typings', 'typings-vscode-definitions']);
53 |
54 | gulp.task('patch', ['default'], function() { return versionBump('patch'); })
55 | gulp.task('minor', ['default'], function() { return versionBump('minor'); })
56 | gulp.task('major', ['default'], function() { return versionBump('major'); })
57 |
--------------------------------------------------------------------------------
/images/design/vscodevim-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chillee/VSCodeNeovim/ec22b1ca3d6bb2899ed74516ba8719b6d4f651b9/images/design/vscodevim-logo.png
--------------------------------------------------------------------------------
/images/design/vscodevim-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
30 |
--------------------------------------------------------------------------------
/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chillee/VSCodeNeovim/ec22b1ca3d6bb2899ed74516ba8719b6d4f651b9/images/icon.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "activationEvents": [
3 | "*"
4 | ],
5 | "bugs": {
6 | "url": "https://github.com/VSCodeVim/Vim/issues"
7 | },
8 | "categories": [
9 | "Other",
10 | "Keymaps"
11 | ],
12 | "contributes": {
13 | "commands": [],
14 | "configuration": {
15 | "properties": {
16 | "vim.enableHighlights": {
17 | "default": true
18 | },
19 | "vim.ignoreKeys": {
20 | "default": {
21 | "all": [
22 | "",
23 | "",
24 | "",
25 | "",
26 | "",
27 | "",
28 | ""
29 | ],
30 | "normal": [],
31 | "insert": [
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | "",
39 | "",
40 | ""
41 | ],
42 | "visual": []
43 | }
44 | },
45 | "vim.neovimPath": {
46 | "type": "string",
47 | "description": "Path to run neovim executable. For example, /usr/bin/nvim, or C:\\Program Files\\Neovim\\bin\\nvim.exe",
48 | "default": "nvim"
49 | }
50 | },
51 | "title": "Vim Configuration",
52 | "type": "object"
53 | },
54 | "keybindings": [
55 | {
56 | "key": "ctrl+space",
57 | "command": "vim.",
58 | "when": "vim.use_",
59 | "vimKey": ""
60 | },
61 | {
62 | "key": "space",
63 | "command": "vim.",
64 | "when": "vim.use_",
65 | "vimKey": ""
66 | },
67 | {
68 | "key": "ctrl+left",
69 | "command": "vim.",
70 | "when": "vim.use_",
71 | "vimKey": ""
72 | },
73 | {
74 | "key": "left",
75 | "command": "vim.",
76 | "when": "vim.use_",
77 | "vimKey": ""
78 | },
79 | {
80 | "key": "ctrl+right",
81 | "command": "vim.",
82 | "when": "vim.use_",
83 | "vimKey": ""
84 | },
85 | {
86 | "key": "right",
87 | "command": "vim.",
88 | "when": "vim.use_",
89 | "vimKey": ""
90 | },
91 | {
92 | "key": "ctrl+up",
93 | "command": "vim.",
94 | "when": "vim.use_",
95 | "vimKey": ""
96 | },
97 | {
98 | "key": "up",
99 | "command": "vim.",
100 | "when": "vim.use_",
101 | "vimKey": ""
102 | },
103 | {
104 | "key": "ctrl+down",
105 | "command": "vim.",
106 | "when": "vim.use_",
107 | "vimKey": ""
108 | },
109 | {
110 | "key": "down",
111 | "command": "vim.",
112 | "when": "vim.use_",
113 | "vimKey": ""
114 | },
115 | {
116 | "key": "ctrl+Escape",
117 | "command": "vim.",
118 | "when": "vim.use_",
119 | "vimKey": ""
120 | },
121 | {
122 | "key": "Escape",
123 | "command": "vim.",
124 | "when": "vim.use_",
125 | "vimKey": ""
126 | },
127 | {
128 | "key": "ctrl+backspace",
129 | "command": "vim.",
130 | "when": "vim.use_",
131 | "vimKey": ""
132 | },
133 | {
134 | "key": "backspace",
135 | "command": "vim.",
136 | "when": "vim.use_",
137 | "vimKey": ""
138 | },
139 | {
140 | "key": "ctrl+tab",
141 | "command": "vim.",
142 | "when": "vim.use_",
143 | "vimKey": ""
144 | },
145 | {
146 | "key": "tab",
147 | "command": "vim.",
148 | "when": "vim.use_",
149 | "vimKey": ""
150 | },
151 | {
152 | "key": "ctrl+enter",
153 | "command": "vim.",
154 | "when": "vim.use_",
155 | "vimKey": ""
156 | },
157 | {
158 | "key": "enter",
159 | "command": "vim.",
160 | "when": "vim.use_",
161 | "vimKey": ""
162 | },
163 | {
164 | "key": "ctrl+0",
165 | "command": "vim.",
166 | "when": "vim.use_",
167 | "vimKey": ""
168 | },
169 | {
170 | "key": "ctrl+7",
171 | "command": "vim.",
172 | "when": "vim.use_",
173 | "vimKey": ""
174 | },
175 | {
176 | "key": "ctrl+n",
177 | "command": "vim.",
178 | "when": "vim.use_",
179 | "vimKey": ""
180 | },
181 | {
182 | "key": "ctrl+$",
183 | "command": "vim.",
184 | "when": "vim.use_",
185 | "vimKey": ""
186 | },
187 | {
188 | "key": "ctrl++",
189 | "command": "vim.",
190 | "when": "vim.use_",
191 | "vimKey": ""
192 | },
193 | {
194 | "key": "ctrl+.",
195 | "command": "vim.",
196 | "when": "vim.use_",
197 | "vimKey": ""
198 | },
199 | {
200 | "key": "ctrl+_",
201 | "command": "vim.",
202 | "when": "vim.use_",
203 | "vimKey": ""
204 | },
205 | {
206 | "key": "ctrl+:",
207 | "command": "vim.",
208 | "when": "vim.use_",
209 | "vimKey": ""
210 | },
211 | {
212 | "key": "ctrl+b",
213 | "command": "vim.",
214 | "when": "vim.use_",
215 | "vimKey": ""
216 | },
217 | {
218 | "key": "ctrl+e",
219 | "command": "vim.",
220 | "when": "vim.use_",
221 | "vimKey": ""
222 | },
223 | {
224 | "key": "ctrl+j",
225 | "command": "vim.",
226 | "when": "vim.use_",
227 | "vimKey": ""
228 | },
229 | {
230 | "key": "ctrl+|",
231 | "command": "vim.",
232 | "when": "vim.use_",
233 | "vimKey": ""
234 | },
235 | {
236 | "key": "ctrl+^",
237 | "command": "vim.",
238 | "when": "vim.use_",
239 | "vimKey": ""
240 | },
241 | {
242 | "key": "ctrl+(",
243 | "command": "vim.",
244 | "when": "vim.use_",
245 | "vimKey": ""
246 | },
247 | {
248 | "key": "ctrl+3",
249 | "command": "vim.",
250 | "when": "vim.use_",
251 | "vimKey": ""
252 | },
253 | {
254 | "key": "ctrl+1",
255 | "command": "vim.",
256 | "when": "vim.use_",
257 | "vimKey": ""
258 | },
259 | {
260 | "key": "ctrl+8",
261 | "command": "vim.",
262 | "when": "vim.use_",
263 | "vimKey": ""
264 | },
265 | {
266 | "key": "ctrl+!",
267 | "command": "vim.",
268 | "when": "vim.use_",
269 | "vimKey": ""
270 | },
271 | {
272 | "key": "ctrl+~",
273 | "command": "vim.",
274 | "when": "vim.use_",
275 | "vimKey": ""
276 | },
277 | {
278 | "key": "ctrl+h",
279 | "command": "vim.",
280 | "when": "vim.use_",
281 | "vimKey": ""
282 | },
283 | {
284 | "key": "ctrl+5",
285 | "command": "vim.",
286 | "when": "vim.use_",
287 | "vimKey": ""
288 | },
289 | {
290 | "key": "ctrl+*",
291 | "command": "vim.",
292 | "when": "vim.use_",
293 | "vimKey": ""
294 | },
295 | {
296 | "key": "ctrl+6",
297 | "command": "vim.",
298 | "when": "vim.use_",
299 | "vimKey": ""
300 | },
301 | {
302 | "key": "ctrl+4",
303 | "command": "vim.",
304 | "when": "vim.use_",
305 | "vimKey": ""
306 | },
307 | {
308 | "key": "ctrl+q",
309 | "command": "vim.",
310 | "when": "vim.use_",
311 | "vimKey": ""
312 | },
313 | {
314 | "key": "ctrl+i",
315 | "command": "vim.",
316 | "when": "vim.use_",
317 | "vimKey": ""
318 | },
319 | {
320 | "key": "ctrl+m",
321 | "command": "vim.",
322 | "when": "vim.use_",
323 | "vimKey": ""
324 | },
325 | {
326 | "key": "ctrl+g",
327 | "command": "vim.",
328 | "when": "vim.use_",
329 | "vimKey": ""
330 | },
331 | {
332 | "key": "ctrl+s",
333 | "command": "vim.",
334 | "when": "vim.use_",
335 | "vimKey": ""
336 | },
337 | {
338 | "key": "ctrl+z",
339 | "command": "vim.",
340 | "when": "vim.use_",
341 | "vimKey": ""
342 | },
343 | {
344 | "key": "ctrl+t",
345 | "command": "vim.",
346 | "when": "vim.use_",
347 | "vimKey": ""
348 | },
349 | {
350 | "key": "ctrl+>",
351 | "command": "vim.>",
352 | "when": "vim.use_>",
353 | "vimKey": ">"
354 | },
355 | {
356 | "key": "ctrl+l",
357 | "command": "vim.",
358 | "when": "vim.use_",
359 | "vimKey": ""
360 | },
361 | {
362 | "key": "ctrl+\"",
363 | "command": "vim.",
364 | "when": "vim.use_",
365 | "vimKey": ""
366 | },
367 | {
368 | "key": "ctrl+a",
369 | "command": "vim.",
370 | "when": "vim.use_",
371 | "vimKey": ""
372 | },
373 | {
374 | "key": "ctrl+u",
375 | "command": "vim.",
376 | "when": "vim.use_",
377 | "vimKey": ""
378 | },
379 | {
380 | "key": "ctrl+<",
381 | "command": "vim.",
382 | "when": "vim.use_",
383 | "vimKey": ""
384 | },
385 | {
386 | "key": "ctrl+f",
387 | "command": "vim.",
388 | "when": "vim.use_",
389 | "vimKey": ""
390 | },
391 | {
392 | "key": "ctrl+`",
393 | "command": "vim.",
394 | "when": "vim.use_",
395 | "vimKey": ""
396 | },
397 | {
398 | "key": "ctrl+#",
399 | "command": "vim.",
400 | "when": "vim.use_",
401 | "vimKey": ""
402 | },
403 | {
404 | "key": "ctrl+p",
405 | "command": "vim.",
406 | "when": "vim.use_",
407 | "vimKey": ""
408 | },
409 | {
410 | "key": "ctrl+2",
411 | "command": "vim.",
412 | "when": "vim.use_",
413 | "vimKey": ""
414 | },
415 | {
416 | "key": "ctrl+,",
417 | "command": "vim.",
418 | "when": "vim.use_",
419 | "vimKey": ""
420 | },
421 | {
422 | "key": "ctrl+9",
423 | "command": "vim.",
424 | "when": "vim.use_",
425 | "vimKey": ""
426 | },
427 | {
428 | "key": "ctrl+'",
429 | "command": "vim.",
430 | "when": "vim.use_",
431 | "vimKey": ""
432 | },
433 | {
434 | "key": "ctrl+?",
435 | "command": "vim.",
436 | "when": "vim.use_",
437 | "vimKey": ""
438 | },
439 | {
440 | "key": "ctrl+o",
441 | "command": "vim.",
442 | "when": "vim.use_",
443 | "vimKey": ""
444 | },
445 | {
446 | "key": "ctrl+}",
447 | "command": "vim.",
448 | "when": "vim.use_",
449 | "vimKey": ""
450 | },
451 | {
452 | "key": "ctrl+-",
453 | "command": "vim.",
454 | "when": "vim.use_",
455 | "vimKey": ""
456 | },
457 | {
458 | "key": "ctrl+)",
459 | "command": "vim.",
460 | "when": "vim.use_",
461 | "vimKey": ""
462 | },
463 | {
464 | "key": "ctrl+]",
465 | "command": "vim.",
466 | "when": "vim.use_",
467 | "vimKey": ""
468 | },
469 | {
470 | "key": "ctrl+c",
471 | "command": "vim.",
472 | "when": "vim.use_",
473 | "vimKey": ""
474 | },
475 | {
476 | "key": "ctrl+v",
477 | "command": "vim.",
478 | "when": "vim.use_",
479 | "vimKey": ""
480 | },
481 | {
482 | "key": "ctrl+x",
483 | "command": "vim.",
484 | "when": "vim.use_",
485 | "vimKey": ""
486 | },
487 | {
488 | "key": "ctrl+%",
489 | "command": "vim.",
490 | "when": "vim.use_",
491 | "vimKey": ""
492 | },
493 | {
494 | "key": "ctrl+y",
495 | "command": "vim.",
496 | "when": "vim.use_",
497 | "vimKey": ""
498 | },
499 | {
500 | "key": "ctrl+;",
501 | "command": "vim.",
502 | "when": "vim.use_",
503 | "vimKey": "