├── .gitignore
├── .travis.yml
├── CHANGES.txt
├── Default.sublime-keymap
├── Default.sublime-mousemap
├── Development
└── Default.sublime-keymap
├── LICENSE.txt
├── Preferences.sublime-settings
├── README.md
├── Vintageous.sublime-build
├── Vintageous.sublime-commands
├── Vintageous.sublime-project
├── VintageousEx Cmdline.JSON-tmLanguage
├── VintageousEx Cmdline.sublime-settings
├── VintageousEx Cmdline.tmLanguage
├── __init__.py
├── appveyor.yml
├── bin
├── Build.ps1
├── Config.ps1
├── Publish.ps1
├── Push.ps1
├── Stats.ps1
├── build.sh
├── builder.py
├── check.py
├── make_version.py
└── toplist.py
├── dev_cmds.py
├── ex
├── __init__.py
├── completions.py
├── ex_error.py
├── ex_location.py
├── parser
│ ├── __init__.py
│ ├── nodes.py
│ ├── parser.py
│ ├── scanner.py
│ ├── scanner_command_abbreviate.py
│ ├── scanner_command_browse.py
│ ├── scanner_command_buffers.py
│ ├── scanner_command_cd_command.py
│ ├── scanner_command_cdd_command.py
│ ├── scanner_command_copy.py
│ ├── scanner_command_cquit.py
│ ├── scanner_command_delete.py
│ ├── scanner_command_double_ampersand.py
│ ├── scanner_command_edit.py
│ ├── scanner_command_exit.py
│ ├── scanner_command_file.py
│ ├── scanner_command_global.py
│ ├── scanner_command_goto.py
│ ├── scanner_command_let.py
│ ├── scanner_command_map.py
│ ├── scanner_command_move.py
│ ├── scanner_command_new.py
│ ├── scanner_command_nmap.py
│ ├── scanner_command_nunmap.py
│ ├── scanner_command_omap.py
│ ├── scanner_command_only.py
│ ├── scanner_command_ounmap.py
│ ├── scanner_command_print.py
│ ├── scanner_command_print_working_dir.py
│ ├── scanner_command_quit_all_command.py
│ ├── scanner_command_quit_command.py
│ ├── scanner_command_read_shell_out.py
│ ├── scanner_command_register.py
│ ├── scanner_command_set.py
│ ├── scanner_command_set_local.py
│ ├── scanner_command_shell.py
│ ├── scanner_command_shell_out.py
│ ├── scanner_command_substitute.py
│ ├── scanner_command_tab_first_command.py
│ ├── scanner_command_tab_last_command.py
│ ├── scanner_command_tab_next_command.py
│ ├── scanner_command_tab_only_command.py
│ ├── scanner_command_tab_open_command.py
│ ├── scanner_command_tab_prev_command.py
│ ├── scanner_command_unabbreviate.py
│ ├── scanner_command_unmap.py
│ ├── scanner_command_unvsplit.py
│ ├── scanner_command_vmap.py
│ ├── scanner_command_vsplit.py
│ ├── scanner_command_vunmap.py
│ ├── scanner_command_write.py
│ ├── scanner_command_write_all.py
│ ├── scanner_command_write_and_quit_all.py
│ ├── scanner_command_write_and_quit_command.py
│ ├── scanner_command_yank.py
│ ├── state.py
│ ├── subscanners.py
│ ├── tokens.py
│ └── tokens_base.py
├── plat
│ ├── __init__.py
│ ├── linux.py
│ ├── osx.py
│ └── windows.py
└── shell.py
├── ex_commands.py
├── ex_main.py
├── ex_motions.py
├── jump_list_cmds.py
├── manifest.json
├── messages.json
├── messages
├── 2.9.1.txt
├── 2.9.10.txt
├── 2.9.11.txt
├── 2.9.2.txt
├── 2.9.3.txt
├── 2.9.4.txt
├── 2.9.5.txt
├── 2.9.6.txt
├── 2.9.7.txt
├── 2.9.8.txt
├── 2.9.9.txt
├── 3.0.0.txt
├── 3.0.1.txt
├── 3.0.2.txt
├── 3.5.0.txt
├── 3.5.1.txt
├── 3.5.10.txt
├── 3.5.11.txt
├── 3.5.12.txt
├── 3.5.13.txt
├── 3.5.14.txt
├── 3.5.2.txt
├── 3.5.3.txt
├── 3.5.4.txt
├── 3.5.5.txt
├── 3.5.6.txt
├── 3.5.7.txt
├── 3.5.8.txt
├── 3.5.9.txt
├── 3.6.0.txt
├── 3.6.1.txt
├── 3.6.2.txt
├── 3.6.3.txt
├── 3.6.4.txt
├── 3.6.6.txt
├── 3.6.7.txt
├── 3.6.8.txt
├── 3.8.0.txt
├── 3.8.1.txt
├── 3.8.10.txt
├── 3.8.2.txt
├── 3.8.3.txt
├── 3.8.4.txt
├── 3.8.5.txt
├── 3.8.6.txt
├── 3.8.7.txt
├── 3.8.8.txt
├── 3.8.9.txt
├── 4.0.0.txt
├── 4.0.1.txt
├── 4.0.2.txt
├── 4.0.3.txt
├── 4.0.4.txt
├── 4.0.5.txt
├── 4.0.6.txt
├── 4.0.7.txt
└── install.txt
├── modelines.py
├── plugins
├── __init__.py
└── plugins.py
├── state.py
├── test_runner.py
├── tests
├── __init__.py
├── cmd_tester.py
├── commands
│ ├── __init__.py
│ ├── test__ctrl_x_and__ctrl_a.py
│ ├── test__vi_antilambda.py
│ ├── test__vi_b.py
│ ├── test__vi_big_a.py
│ ├── test__vi_big_e.py
│ ├── test__vi_big_f.py
│ ├── test__vi_big_g.py
│ ├── test__vi_big_i.py
│ ├── test__vi_big_j.py
│ ├── test__vi_big_s.py
│ ├── test__vi_big_t.py
│ ├── test__vi_cc.py
│ ├── test__vi_ctrl_r.py
│ ├── test__vi_dd.py
│ ├── test__vi_dollar.py
│ ├── test__vi_e.py
│ ├── test__vi_f.py
│ ├── test__vi_g_g.py
│ ├── test__vi_h.py
│ ├── test__vi_hat.py
│ ├── test__vi_j.py
│ ├── test__vi_k.py
│ ├── test__vi_l.py
│ ├── test__vi_octothorp.py
│ ├── test__vi_percent.py
│ ├── test__vi_repeat_search.py
│ ├── test__vi_s.py
│ ├── test__vi_search.py
│ ├── test__vi_star.py
│ ├── test__vi_t.py
│ ├── test__vi_underscore.py
│ ├── test__vi_visual_o.py
│ ├── test__vi_zero.py
│ ├── test_all_cmds.py
│ ├── test_vi_big_b.py
│ ├── test_vi_big_p.py
│ ├── vi_big_x-internal-normal-mode.cmd-test
│ ├── vi_cc-internal-normal-mode.cmd-test
│ ├── vi_dd-internal-normal-mode.cmd-test
│ ├── vi_dd-internal-normal.cmd-test
│ ├── vi_gm-normal-mode.cmd-test
│ ├── vi_l-normal-mode.cmd-test
│ ├── vi_right_brace-normal-mode.cmd-test
│ └── vi_x-internal-normal-mode.cmd-test
├── data
│ └── Default.sublime-keymap_
├── ex
│ ├── __init__.py
│ ├── parsers
│ │ ├── __init__.py
│ │ └── new
│ │ │ ├── __init__.py
│ │ │ ├── test_nodes.py
│ │ │ ├── test_parser.py
│ │ │ ├── test_parser_state.py
│ │ │ ├── test_scanner.py
│ │ │ └── test_scanner_state.py
│ ├── test_commands.py
│ ├── test_copy.py
│ ├── test_delete.py
│ ├── test_location.py
│ ├── test_move.py
│ └── test_shell_out.py
├── test_entering_normal_mode.py
├── test_state.py
└── vi
│ ├── __init__.py
│ ├── test_a_word.py
│ ├── test_big_word.py
│ ├── test_big_word_reverse.py
│ ├── test_find_paragraph_text_object.py
│ ├── test_keys.py
│ ├── test_mappings.py
│ ├── test_marks.py
│ ├── test_move_by_word_ends.py
│ ├── test_registers.py
│ ├── test_search.py
│ ├── test_settings.py
│ ├── test_tag_text_object.py
│ ├── test_text_objects.py
│ ├── test_variables.py
│ ├── test_word.py
│ ├── test_word_reverse.py
│ └── test_word_start_reverse.py
├── vi
├── __init__.py
├── abbrev.py
├── cmd_base.py
├── cmd_defs.py
├── constants.py
├── contexts.py
├── core.py
├── dot_file.py
├── extend.py
├── inputs.py
├── jump_list.py
├── keys.py
├── macros.py
├── mappings.py
├── marks.py
├── registers.py
├── search.py
├── settings.py
├── sublime.py
├── text_objects.py
├── units.py
├── utils.py
└── variables.py
├── xactions.py
├── xmotions.py
├── xsupport.py
└── xsupport_mouse.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 |
6 | # Distribution / packaging
7 | dist/
8 |
9 |
10 | # Editors
11 | *.sublime-workspace
12 | *.sublime-package
13 |
14 | *~
15 | *.TMP
16 | *.swp
17 | *.swo
18 | *.swm
19 | *.swn
20 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os:
2 | - linux
3 | - osx
4 |
5 | env:
6 | global:
7 | - PACKAGE="Vintageous"
8 | matrix:
9 | - SUBLIME_TEXT_VERSION="3"
10 |
11 | before_install:
12 | - curl -OL https://raw.githubusercontent.com/randy3k/UnitTesting/master/sbin/travis.sh
13 |
14 | install:
15 | - sh travis.sh bootstrap
16 |
17 | script:
18 | - sh travis.sh run_tests
19 |
20 | notifications:
21 | email: false
22 |
--------------------------------------------------------------------------------
/Default.sublime-mousemap:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/Development/Default.sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["f5"], "command": "run_tests_for_active_view", "context": [{ "key": "vi_command_mode_aware"}]},
3 | { "keys": ["ctrl+f5"], "command": "run_all_tests", "context": [{ "key": "vi_command_mode_aware"}]}
4 | ]
5 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | License
2 | =======
3 |
4 | Vintageous is made available under the MIT license:
5 |
6 | Copyright (c) 2010 Guillermo López-Anglada (SublimeModelines)
7 | Copyright (c) 2011 Sublime HQ Pty Ltd (Vintage)
8 | Copyright (c) 2011 Guillermo López-Anglada (VintageEx)
9 | Copyright (c) 2013 Guillermo López-Anglada (Vintageous)
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Preferences.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | // If true, debug information will be printed to the console.
3 | "vintageous_verbose": false,
4 |
5 | // If true, some key bindings prefaced by the CTRL modifier will override default Sublime Text
6 | // key bindings.
7 | "vintageous_use_ctrl_keys": false,
8 |
9 | // If true, search occurrences will be highlighted in '/', '?', etc.
10 | // (Disabled.)
11 | "vintageous_hlsearch": true,
12 |
13 | // If true, search patterns will be applied incrementally as they are typed in.
14 | // (Disabled.)
15 | "vintageous_incsearch": true,
16 |
17 | // If true, ':' and ex commands will be available.
18 | "vintageous_enable_cmdline_mode": true,
19 |
20 | // If true, the current mode will be reset to normal mode when a tab gets activated.
21 | "vintageous_reset_mode_when_switching_tabs": true,
22 |
23 | // If true, some commands will take the current indentation level into account.
24 | // (Disabled.)
25 | "vintageous_autoindent": true,
26 |
27 | // If true, copy actions will always propagate to the system clipboard.
28 | "vintageous_use_sys_clipboard": false,
29 |
30 | // If true, / and ? will use regular expressions.
31 | // If false, smart case will be used instead: the pattern will be interpreted literally and, if
32 | // it's either all lowercase or all uppercase, case will be ignored too.
33 | "vintageous_magic": true,
34 |
35 | // If true, /, ?, * and # will always ignore case.
36 | "vintageous_ignorecase": true,
37 |
38 | // Logging level. Used for diagnostics and troubleshooting. Common valid
39 | // values are 'debug', 'info', 'error', 'critical'. Most users should
40 | // not need to modify the default value.
41 | "vintageous_log_level": "error"
42 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/guillermooo/Vintageous) [](https://ci.appveyor.com/project/guillermooo/vintageous/branch/master)
2 |
3 | ## Vintageous
4 |
5 |
6 |
7 |
8 | **Vintageous** is a comprehensive vi/Vim emulation layer for Sublime Text 3.
9 |
10 | Vintageous has been discontinued.
11 |
12 | The successor to Vintageous is Sublime Six.
13 |
14 | See you in Sublime Six.
15 |
16 | https://github.com/guillermooo/Six
17 |
18 | http://sublimesix.com/
19 |
20 |
21 | ### Installing
22 |
23 | **Make sure that Vintage
24 | is in the `ignored_packages` list
25 | in your user preferences.**
26 |
27 | You can install Vintageous in multiple ways:
28 |
29 |
30 | ##### Using Package Control
31 |
32 | Search for 'Vintageous' and install.
33 |
34 |
35 | ##### Using a Pre-built Version
36 |
37 | 1. Download the [current build](https://bitbucket.org/guillermooo/vintageous/downloads/Vintageous.sublime-package)
38 | 2. Copy *Vintageous.sublime-package* to the *Installed Packages* folder located under the data directory.
39 |
40 |
41 | ##### Building from Source
42 |
43 | 1. Clone this repository
44 | 2. Optionally, update to a specific tag
45 | 3. Run `./bin/build.sh` (OS X/Linux) or `bin/Publish.ps1` (Windows).
46 |
47 | Refer to the [wiki](https://github.com/guillermooo/Vintageous/wiki) for more information.
48 |
49 |
50 | ### Documentation
51 |
52 | Refer to the [wiki](https://github.com/guillermooo/Vintageous/wiki).
53 |
54 |
55 | ### Settings
56 |
57 | See [Vintageous/Preferences.sublime-settings](https://github.com/guillermooo/Vintageous/blob/master/Preferences.sublime-settings) for a comprehensive list of settings.
58 |
--------------------------------------------------------------------------------
/Vintageous.sublime-build:
--------------------------------------------------------------------------------
1 | {
2 | "shell_cmd": "./build.sh",
3 | "windows":
4 | {
5 | "shell_cmd": "powershell -noninteractive -file \"$project_path\\bin\\Build.ps1\""
6 | },
7 | "working_dir": "${project_path}",
8 |
9 | "variants": [
10 | {
11 | "name": "Vintageous - Test (All)",
12 | "target": "run_vintageous_tests",
13 | },
14 |
15 | {
16 | "name": "Vintageous - Test (This File Only)",
17 | "target": "run_vintageous_tests",
18 | "active_file_only": true
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/Vintageous.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | { "caption": "Vintageous: Reset", "command": "reset_vintageous" },
3 | { "caption": "Vintageous: Toggle Vim Ctrl Keys", "command": "vintageous_toggle_ctrl_keys" },
4 | { "caption": "Vintageous: Exit from command mode", "command": "force_exit_from_command_mode" },
5 | { "caption": "Vintageous: Open .vintageousrc", "command": "vintageous_open_config_file" }
6 | ]
--------------------------------------------------------------------------------
/Vintageous.sublime-project:
--------------------------------------------------------------------------------
1 | {
2 | "folders":
3 | [
4 | {
5 | "follow_symlinks": true,
6 | "path": "."
7 | }
8 | ],
9 |
10 | "settings":
11 | {
12 | "ensure_new_line_at_eof_on_save": true,
13 | "trim_trailing_white_space_on_save": true,
14 | "default_line_ending": "unix",
15 | "translate_tabs_to_spaces": false
16 | },
17 |
18 | "SublimeLinter":
19 | {
20 | "@python": 3.4
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/VintageousEx Cmdline.JSON-tmLanguage:
--------------------------------------------------------------------------------
1 | { "name": "Vintageous Command Line",
2 | "scopeName": "text.excmdline",
3 | "uuid": "eb9bb9a2-ab05-4edf-aee1-22d79cc9d9b0",
4 |
5 | "patterns": [
6 | {"match": "^(:)(?:(\\d+)|(cd(?:d)?|w(?:rite|q|all)?|e(?:dit|new|xit)?|pw(?:d)?|buffers|files|ls|reg(?:isters)?|map|ab(?:breviate)?|q(:?uit|all)?|r(?:ead)?|as(?:cii)?|f(?:ile)?|move|co(?:py)?|t(?:abfirst|abprev|abedit|abe|abnext|abn|ablast|abl|abonly|abo)?|setl(:?ocal)?|se(?:t)?|s(?:ubstitute|hell|h)?|&&|d(?:elete)?|g(?:lobal)?|p(?:rint)?|P(?:rint)?|bro(?:owse)?|cq(?:uit)?|x(?:it)?|on(?:ly)?|new|y(?:ank)?|(?:un)?vs(?:plit)?)(!)?)?",
7 | "captures": {
8 | "1": {"name": "keyword.excmdline"},
9 | "2": {"name": "constant.numeric.excmdline"},
10 | "3": {"name": "support.function.excmdline"},
11 | "4": {"name": "keyword.excmdline"}
12 | }
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/VintageousEx Cmdline.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | "auto_match_enabled": false
3 | }
4 |
--------------------------------------------------------------------------------
/VintageousEx Cmdline.tmLanguage:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Vintageous Command Line
7 | patterns
8 |
9 |
10 | captures
11 |
12 | 1
13 |
14 | name
15 | keyword.excmdline
16 |
17 | 2
18 |
19 | name
20 | constant.numeric.excmdline
21 |
22 | 3
23 |
24 | name
25 | support.function.excmdline
26 |
27 | 4
28 |
29 | name
30 | keyword.excmdline
31 |
32 |
33 | match
34 | ^(:)(?:(\d+)|(cd(?:d)?|w(?:rite|q|all)?|e(?:dit|new|xit)?|pw(?:d)?|buffers|files|ls|reg(?:isters)?|map|ab(?:breviate)?|q(:?uit|all)?|r(?:ead)?|as(?:cii)?|f(?:ile)?|move|co(?:py)?|t(?:abfirst|abprev|abedit|abe|abnext|abn|ablast|abl|abonly|abo)?|setl(:?ocal)?|se(?:t)?|s(?:ubstitute|hell|h)?|&&|d(?:elete)?|g(?:lobal)?|p(?:rint)?|P(?:rint)?|bro(?:owse)?|cq(?:uit)?|x(?:it)?|on(?:ly)?|new|y(?:ank)?|(?:un)?vs(?:plit)?)(!)?)?
35 |
36 |
37 | scopeName
38 | text.excmdline
39 | uuid
40 | eb9bb9a2-ab05-4edf-aee1-22d79cc9d9b0
41 |
42 |
43 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | environment:
2 | global:
3 | PACKAGE: "Vintageous"
4 |
5 | matrix:
6 | - SUBLIME_TEXT_VERSION: "3"
7 |
8 | clone_depth: 1
9 |
10 | install:
11 | - ps: start-filedownload "https://raw.githubusercontent.com/randy3k/UnitTesting/master/sbin/appveyor.ps1"
12 | - ps: .\appveyor.ps1 "bootstrap" -verbose
13 |
14 | build: off
15 |
16 | test_script:
17 | - ps: .\appveyor.ps1 "run_tests" -verbose
18 |
--------------------------------------------------------------------------------
/bin/Build.ps1:
--------------------------------------------------------------------------------
1 | param([switch]$Release, [switch]$NoRestartEditor=$False)
2 |
3 | push-location $PSScriptRoot
4 | . '.\Config.ps1'
5 | if(!$?){
6 | write-error "Could not read config."
7 | exit 1
8 | }
9 | pop-location
10 |
11 | push-location "$PSScriptRoot\.."
12 | & (join-path $PSScriptRoot '.\Publish.ps1') @PSBoundParameters
13 | if ($LASTEXITCODE -ne 0) {
14 | write-error "Could not publish package."
15 | pop-location
16 | exit 1
17 | }
18 | pop-location
19 |
20 | if ($NoRestartEditor) { exit 0 }
21 |
22 | get-process "sublime_text" -ea silentlycontinue | stop-process
23 | write-output "Trying to restart Sublime Text..."
24 | start-sleep -milliseconds 250
25 |
26 | $editor = (GetConfigValue 'global-win' 'editor')
27 | if(!$?){
28 | write-error "Could not locate editor command."
29 | exit 1
30 | }
31 |
32 | &$editor
33 |
--------------------------------------------------------------------------------
/bin/Config.ps1:
--------------------------------------------------------------------------------
1 | # Helpers to read files in this format:
2 | #
3 | # global-win editor path/to/some/bin
4 | # project-foo deploy-url http://some/url/here
5 | # ...
6 |
7 | function GetConfig {
8 | $path = "~/.sublime-package-dev"
9 |
10 | if(!(test-path $path)){
11 | write-error "Could not find personal configuration in $path."
12 | exit 1
13 | }
14 | get-content $path
15 | }
16 |
17 | $script:configData = GetConfig
18 |
19 | function GetConfigValue {
20 | param($section, $key)
21 | $section = $section.ToLower()
22 | $key = $key.ToLower()
23 | foreach($item in $configData){
24 | if(!$item.Trim()){
25 | continue
26 | }
27 | $s, $k, $v = $item.ToLower() -split ' ',3
28 | if(($s -eq $section) -and ($k -eq $key)){
29 | if(!$v){
30 | throw "No value found for '${section}:$key'."
31 | }
32 | return $v
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/bin/Publish.ps1:
--------------------------------------------------------------------------------
1 | param([switch]$Release, [switch]$DontUpload)
2 |
3 | $script:thisDir = split-path $MyInvocation.MyCommand.Path -parent
4 | # Don't resolve-path because it may not exist yet.
5 | $script:distDir = join-path $thisDir "../dist"
6 |
7 | . (join-path $script:thisDir "Config.ps1")
8 | if(!$?){
9 | write-error "Could not read config."
10 | exit 1
11 | }
12 |
13 | & "py.exe" "-3" (join-path $script:thisDir "check.py") $typeOfBuild
14 | if ($LASTEXITCODE -ne 0) {
15 | "publish aborted"
16 | exit 1
17 | }
18 |
19 | $typeOfBuild = if ($Release) {"release"} else {"dev"}
20 | # Run with the required Python version.
21 | & "py.exe" "-3" (join-path $script:thisDir "builder.py") "--release" $typeOfBuild
22 |
23 | if ($LASTEXITCODE -ne 0) {
24 | write-error "could not run builder.py"
25 | exit 1
26 | }
27 |
28 | $installedPackages = (GetConfigValue 'global-win' 'installed-packages')
29 | if(!$?){
30 | throw "Could not retrieve Installed Packages location from confige"
31 | exit 1
32 | }
33 | $targetDir = resolve-path ($installedPackages)
34 |
35 | copy-item (join-path $distDir "Vintageous.sublime-package") $targetDir -force
36 |
37 | if ($Release -and (!$DontUpload)) {
38 | $deployUrl = (GetConfigValue 'project-vintageous' 'deploy-url')
39 | if(!$?){
40 | throw "Could not retrieve deploy url from config."
41 | exit 1
42 | }
43 | start-process $deployUrl
44 | (resolve-path $distDir).path | clip.exe
45 | }
46 |
--------------------------------------------------------------------------------
/bin/Push.ps1:
--------------------------------------------------------------------------------
1 | # This script ensures that we abort pushing if we have unfinzalied Mercurial patches.
2 | #
3 | # hg-git has bug that will break the local repository if we do all the following things:
4 | # 1. we push changes in A.patch to Github without finalizing the patch first
5 | # 2. we make further changes to the patch locally and refresh
6 | # 3. we finalize and push A.patch to Github again
7 |
8 | if (& hg qseries) {
9 | write-host "Cannot push: unfinalized patches!" -foregroundcolor RED
10 | exit
11 | }
12 |
13 | # Override .hg/hgrc
14 | & hg --config "alias.push=push" push bb
15 | & hg --config "alias.push=push" push git
16 |
--------------------------------------------------------------------------------
/bin/Stats.ps1:
--------------------------------------------------------------------------------
1 | # Gather some metrics about this project.
2 |
3 | push-location $PSSCriptRoot\..
4 | $code = get-content (
5 | get-childitem . *.py -recurse |
6 | select-object -expandproperty fullname) |
7 | select-string -notmatch "^\s*#" |
8 | measure-object -line
9 |
10 |
11 | $comments = get-content (
12 | get-childitem . *.py -recurse |
13 | select-object -expandproperty fullname) |
14 | select-string "^\s*#" |
15 | measure-object -line
16 |
17 |
18 | $tests = get-content (
19 | get-childitem .\tests *.py -recurse |
20 | select-object -expandproperty fullname) |
21 | select-string -notmatch "^\s*#" |
22 | measure-object -line
23 |
24 | pop-location
25 |
26 | write-output "-----------------------------------------------"
27 | write-output "SLOC (Application): $($code.lines - $tests.lines)"
28 | write-output "SLOC (Tests): $($tests.lines)"
29 | write-output "SLOC (Comments): $($comments.lines)"
30 | write-output "SLOC (Total): $($code.lines + $comments.lines)"
31 |
--------------------------------------------------------------------------------
/bin/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
3 |
4 | e=1
5 | if python "$DIR/builder.py"; then
6 | case "$(uname)" in
7 | Linux)
8 | cp -f "$DIR/../dist/Vintageous.sublime-package"\
9 | "${HOME}/.config/sublime-text-3/Installed Packages"
10 | e=$?
11 | ;;
12 | Darwin)
13 | cp -f "$DIR/../dist/Vintageous.sublime-package"\
14 | "${HOME}/Library/Application Support/Sublime Text 3/Installed Packages/"
15 | e=$?
16 | ;;
17 | *)
18 | echo "Vintageous: no build script for $(uname) :_("
19 | ;;
20 | esac
21 | else
22 | echo "Failed to execute $DIR/builder.py"
23 | e=2
24 | fi
25 |
26 | exit $e
27 |
--------------------------------------------------------------------------------
/bin/builder.py:
--------------------------------------------------------------------------------
1 | from fnmatch import fnmatch
2 | from itertools import chain
3 | from zipfile import ZipFile
4 | from zipfile import ZIP_DEFLATED
5 | import argparse
6 | import glob
7 | import json
8 | import os
9 |
10 |
11 | THIS_DIR = os.path.abspath(os.path.dirname(__file__))
12 | PROJECT_ROOT = os.path.dirname(THIS_DIR)
13 | RESERVED = ['manifest.json', 'dist']
14 |
15 |
16 | parser = argparse.ArgumentParser(
17 | description="Builds .sublime-package archives.")
18 | parser.add_argument('-d', dest='target_dir', default='./dist',
19 | help="output directory")
20 | parser.add_argument('--release', dest='release', default='dev',
21 | help="type of build (e.g. 'dev', 'release'...)")
22 |
23 |
24 | def get_manifest():
25 | path = os.path.join(PROJECT_ROOT, 'manifest.json')
26 | with open(path) as f:
27 | return json.load(f)
28 |
29 |
30 | def unwanted(fn, pats):
31 | return any(fnmatch(fn, pat) for pat in pats + RESERVED)
32 |
33 |
34 | def ifind_files(patterns):
35 | for fn in (fn for (pat, exclude) in patterns
36 | for fn in glob.iglob(pat)
37 | if not unwanted(fn, exclude)):
38 | yield fn
39 |
40 |
41 | def build(target_dir="dist", release="dev"):
42 | os.chdir(PROJECT_ROOT)
43 | manifest = get_manifest()
44 | name = manifest['name'] + '.sublime-package'
45 |
46 | target_dir = os.path.join(PROJECT_ROOT, target_dir)
47 | if not os.path.exists(target_dir):
48 | os.mkdir(target_dir)
49 |
50 | target_file = os.path.join(target_dir, name)
51 | if os.path.exists(target_file):
52 | os.unlink(target_file)
53 |
54 | with ZipFile(target_file, 'a', compression=ZIP_DEFLATED) as package:
55 | for fn in ifind_files(manifest['include'][release]):
56 | package.write(fn)
57 |
58 |
59 | if __name__ == '__main__':
60 | args = parser.parse_args()
61 | build(args.target_dir, args.release)
62 |
--------------------------------------------------------------------------------
/bin/check.py:
--------------------------------------------------------------------------------
1 | """
2 | check for common build errors
3 | """
4 |
5 | import json
6 | import os
7 | import sys
8 |
9 |
10 | _this_dir = os.path.dirname(__file__)
11 | _parent = os.path.realpath(os.path.join(_this_dir, '..'))
12 |
13 |
14 | def check_messages():
15 | _messages = os.path.realpath(os.path.join(_parent, 'messages.json'))
16 | _messages_dir = os.path.realpath(os.path.join(_parent, 'messages'))
17 |
18 | msg_paths = None
19 | try:
20 | with open(_messages, 'r') as f:
21 | msg_paths = json.load(f)
22 | except Exception as e:
23 | print('syntax error in messages.json')
24 | print('=' * 80)
25 | print(e)
26 | print('=' * 80)
27 | sys.exit(1)
28 |
29 | def exists(path):
30 | if os.path.exists(os.path.join(_parent, path)):
31 | return True
32 |
33 | def is_name_correct(key, path):
34 | name = os.path.basename(path)
35 | return (key == os.path.splitext(name)[0])
36 |
37 | # is there a file for each message?
38 | for (key, rel_path) in msg_paths.items():
39 | if not is_name_correct(key, rel_path):
40 | print('file name not correct: {0} ==> {1}'.format(key, rel_path))
41 | sys.exit(1)
42 |
43 | if not exists(rel_path):
44 | print('message file not found: {0}'.format(rel_path))
45 | sys.exit(1)
46 |
47 |
48 | if __name__ == '__main__':
49 | check_messages()
50 |
--------------------------------------------------------------------------------
/bin/toplist.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import json
3 | import os
4 | import plistlib
5 |
6 |
7 | THIS_DIR = os.path.abspath(os.path.dirname(__file__))
8 |
9 |
10 | parser = argparse.ArgumentParser(
11 | description="Builds .tmLanguage files out of .JSON-tmLanguage files.")
12 | parser.add_argument('-s', dest='source',
13 | help="source .JSON-tmLanguage file")
14 |
15 | def build(source):
16 | with open(source, 'r') as f:
17 | json_data = json.load(f)
18 | plistlib.writePlist(json_data, os.path.splitext(source)[0] + '.tmLanguage')
19 |
20 |
21 | if __name__ == '__main__':
22 | args = parser.parse_args()
23 | if args.source:
24 | build(args.source)
25 |
--------------------------------------------------------------------------------
/ex/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | Misc stuff needed for ex commands.
3 | '''
4 |
5 | # Used to provide completions on the ex command line.
6 | command_names = []
7 |
8 |
9 | def command(name, abbrev):
10 | """
11 | Registers the name of an ex command with `command_names`.
12 |
13 | Meant to be imported like this:
14 |
15 | from Vintageous import ex
16 |
17 | ...
18 |
19 | @ex.command('foo', 'f')
20 | class ExFooCommand(...):
21 | ...
22 | """
23 | command_names.append((name, abbrev))
24 | def inner(f):
25 | return f
26 | return inner
27 |
--------------------------------------------------------------------------------
/ex/parser/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guillermooo/Vintageous/f958207009902052aed5fcac09745f1742648604/ex/parser/__init__.py
--------------------------------------------------------------------------------
/ex/parser/scanner_command_abbreviate.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_ABBREVIATE
4 | from .tokens_base import TokenOfCommand
5 |
6 | from Vintageous.ex.ex_error import ERR_INVALID_ARGUMENT
7 | from Vintageous.ex.ex_error import VimError
8 | from Vintageous import ex
9 |
10 |
11 | @ex.command('abbreviate', 'ab')
12 | class TokenCommandAbbreviate(TokenOfCommand):
13 | def __init__(self, params, *args, **kwargs):
14 | super().__init__(params,
15 | TOKEN_COMMAND_ABBREVIATE,
16 | 'write', *args, **kwargs)
17 | self.target_command = 'ex_abbreviate'
18 |
19 | @property
20 | def short(self):
21 | return self.params['short']
22 |
23 | @property
24 | def full(self):
25 | return self.params['full']
26 |
27 |
28 | def scan_command_abbreviate(state):
29 | params = {
30 | 'short': None,
31 | 'full': None,
32 | }
33 |
34 | state.expect(' ')
35 | state.skip(' ')
36 | state.ignore()
37 |
38 | if state.consume() == EOF:
39 | return None, [TokenCommandAbbreviate({}), TokenEof()]
40 |
41 | state.backup()
42 |
43 | m = state.match(r'(?P.+?)(?: +(?P.+))?$')
44 | params.update(m.groupdict())
45 |
46 | return None, [TokenCommandAbbreviate(params), TokenEof()]
47 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_browse.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_BROWSE
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('browse', 'bro')
9 | class TokenBrowse(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_BROWSE,
13 | 'browse', *args, **kwargs)
14 | self.target_command = 'ex_browse'
15 |
16 |
17 | def scan_command_browse(state):
18 | params = {
19 | 'cmd': None,
20 | }
21 |
22 | state.skip(' ')
23 | state.ignore()
24 |
25 | m = state.match(r'(?P.*)$')
26 | params.update(m.groupdict())
27 |
28 | if params ['cmd']:
29 | raise NotImplementedError('parameter not implemented')
30 |
31 | return None, [TokenBrowse(params), TokenEof()]
32 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_buffers.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_BUFFERS
4 | from .tokens_base import TokenOfCommand
5 |
6 | from Vintageous.ex.ex_error import ERR_INVALID_ARGUMENT
7 | from Vintageous.ex.ex_error import VimError
8 | from Vintageous import ex
9 |
10 |
11 | @ex.command('buffers', 'buffers')
12 | @ex.command('files', 'files')
13 | @ex.command('ls', 'ls')
14 | class TokenCommandBuffers(TokenOfCommand):
15 | def __init__(self, *args, **kwargs):
16 | super().__init__({},
17 | TOKEN_COMMAND_BUFFERS,
18 | 'write', *args, **kwargs)
19 | self.target_command = 'ex_prompt_select_open_file'
20 |
21 |
22 | def scan_command_buffers(state):
23 | try:
24 | state.expect(EOF)
25 | except ValueError:
26 | raise VimError('trailing characters')
27 |
28 | return None, [TokenCommandBuffers(), TokenEof()]
29 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_cd_command.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_CD_COMMAND
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('cd', 'cd')
9 | class TokenCdCommand(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_CD_COMMAND,
13 | 'cd', *args, **kwargs)
14 | self.target_command = 'ex_cd'
15 |
16 | @property
17 | def path(self):
18 | return self.params['path']
19 |
20 | @property
21 | def must_go_back(self):
22 | return self.params['-']
23 |
24 |
25 | def scan_command_cd_command(state):
26 | params = {
27 | 'path': None,
28 | '-': None,
29 | }
30 |
31 | bang = state.consume() == '!'
32 |
33 | if not bang:
34 | state.backup()
35 |
36 | state.skip(' ')
37 | state.ignore()
38 |
39 | c = state.consume()
40 |
41 | if c == '-':
42 | params['-'] = '-'
43 | state.expect(EOF)
44 | raise NotImplementedError('parameter not implemented')
45 |
46 | elif c != EOF:
47 | state.backup()
48 | m = state.match(r'(?P.+?)\s*$')
49 | params.update(m.groupdict())
50 |
51 | return None, [TokenCdCommand(params, forced=bang), TokenEof()]
52 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_cdd_command.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_CDD_COMMAND
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('cdd', 'cdd')
9 | class TokenCddCommand(TokenOfCommand):
10 | def __init__(self, *args, **kwargs):
11 | super().__init__({},
12 | TOKEN_COMMAND_CDD_COMMAND,
13 | 'cdd', *args, **kwargs)
14 | self.target_command = 'ex_cdd'
15 |
16 |
17 | def scan_command_cdd_command(state):
18 | c = state.consume()
19 |
20 | if c == EOF:
21 | return None, [TokenCddCommand(), TokenEof()]
22 |
23 | bang = c == '!'
24 | if not bang:
25 | state.backup()
26 |
27 | state.expect(EOF)
28 |
29 | return None, [TokenCddCommand(forced=bang), TokenEof()]
30 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_copy.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_COPY
4 | from .tokens_base import TokenOfCommand
5 | from .parser import parse_command_line
6 | from Vintageous import ex
7 |
8 |
9 | @ex.command('copy', 'co')
10 | class TokenCopy(TokenOfCommand):
11 | def __init__(self, params, *args, **kwargs):
12 | super().__init__(params,
13 | TOKEN_COMMAND_COPY,
14 | 'copy', *args, **kwargs)
15 | self.addressable = True
16 | self.target_command = 'ex_copy'
17 |
18 | @property
19 | def address(self):
20 | return self.params['address']
21 |
22 | def calculate_address(self):
23 | # TODO: must calc only the first line ref?
24 | calculated = parse_command_line(self.address)
25 | if calculated is None:
26 | return None
27 |
28 | assert calculated.command is None, 'bad address'
29 | assert calculated.line_range.separator is None, 'bad address'
30 |
31 | return calculated.line_range
32 |
33 |
34 | def scan_command_copy(state):
35 | params = {
36 | 'address': None
37 | }
38 |
39 | m = state.expect_match(r'\s*(?P.+?)\s*$')
40 | params.update(m.groupdict())
41 |
42 | return None, [TokenCopy(params), TokenEof()]
43 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_cquit.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_CQUIT
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('cquit', 'cq')
9 | class TokenCquit(TokenOfCommand):
10 | def __init__(self, *args, **kwargs):
11 | super().__init__({},
12 | TOKEN_COMMAND_CQUIT,
13 | 'cquit', *args, **kwargs)
14 | self.target_command = 'ex_cquit'
15 |
16 |
17 | def scan_command_cquit(state):
18 | state.expect(EOF)
19 |
20 | return None, [TokenCquit(), TokenEof()]
21 |
22 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_delete.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_DELETE
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('delete', 'd')
9 | class TokenDelete(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_DELETE,
13 | 'delete', *args, **kwargs)
14 | self.addressable = True
15 | self.target_command = 'ex_delete'
16 |
17 | @property
18 | def register(self):
19 | return self.params['register']
20 |
21 | @property
22 | def count(self):
23 | return self.params['count']
24 |
25 |
26 | def scan_command_delete(state):
27 | params = {
28 | 'register': '"',
29 | 'count': None,
30 | }
31 |
32 | state.skip(' ')
33 | state.ignore()
34 |
35 | c = state.consume()
36 |
37 | if c == EOF:
38 | return None, [TokenDelete(params), TokenEof()]
39 |
40 | state.backup()
41 | state.skip(' ')
42 | state.ignore()
43 |
44 | m = state.expect_match(r'(?P[a-zA-Z0-9"])(?:\s+(?P\d+))?\s*$')
45 | params.update(m.groupdict())
46 |
47 | if params ['count']:
48 | raise NotImplementedError('parameter not implemented')
49 |
50 | return None, [TokenDelete(params), TokenEof()]
51 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_double_ampersand.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_DOUBLE_AMPERSAND
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('&&', '&&')
9 | class TokenDoubleAmpersand(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_DOUBLE_AMPERSAND,
13 | '&&', *args, **kwargs)
14 | self.addressable = True
15 | self.target_command = 'ex_double_ampersand'
16 |
17 |
18 | def scan_command_double_ampersand(state):
19 | params = {
20 | 'flags': [],
21 | 'count': '',
22 | }
23 |
24 | m = state.match(r'\s*([cgr])*\s*(\d*)\s*$')
25 | params['flags'] = list(m.group(1)) if m.group(1) else []
26 | params['count'] = m.group(2) or ''
27 |
28 | state.expect(EOF)
29 |
30 | return None, [TokenDoubleAmpersand(params), TokenEof()]
31 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_exit.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_EXIT
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('exit', 'exi')
9 | @ex.command('xit', 'x')
10 | class TokenCommandExit(TokenOfCommand):
11 | def __init__(self, params, *args, **kwargs):
12 | super().__init__(params,
13 | TOKEN_COMMAND_EXIT,
14 | 'exit', *args, **kwargs)
15 | self.addressable = True
16 | self.target_command = 'ex_exit'
17 |
18 |
19 | def scan_command_exit(state):
20 | params = {
21 | 'file_name': '',
22 | }
23 |
24 | bang = state.consume()
25 |
26 | if bang == EOF:
27 | return None, [TokenCommandExit(params), TokenEof()]
28 |
29 | bang = bang == '!'
30 | if not bang:
31 | state.backup()
32 |
33 | state.skip(' ')
34 | state.ignore()
35 |
36 | while True:
37 | c = state.consume()
38 |
39 | if c == EOF:
40 | return None, [TokenCommandExit(params, forced=bang), TokenEof()]
41 |
42 | if c == '+':
43 | state.expect('+')
44 | state.ignore()
45 | # TODO: expect_match should work with emit()
46 | # http://vimdoc.sourceforge.net/htmldoc/editing.html#[++opt]
47 | m = state.expect_match(
48 | r'(?:f(?:ile)?f(?:ormat)?|(?:file)?enc(?:oding)?|(?:no)?bin(?:ary)?|bad|edit)(?=\s|$)',
49 | lambda: VimError(ERR_INVALID_ARGUMENT))
50 | name = m.group(0)
51 | params['++'] = plus_plus_translations.get(name, name)
52 | state.ignore()
53 | continue
54 |
55 | if c != ' ':
56 | state.match(r'.*')
57 | params['file_name'] = state.emit().strip()
58 | state.skip(' ')
59 | state.ignore()
60 |
61 | state.expect(EOF)
62 | return None, [TokenCommandExit (params, forced=bang == '!'), TokenEof ()]
--------------------------------------------------------------------------------
/ex/parser/scanner_command_file.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_FILE
4 | from .tokens_base import TokenOfCommand
5 |
6 | from Vintageous.ex.ex_error import ERR_TRAILING_CHARS
7 | from Vintageous.ex.ex_error import VimError
8 | from Vintageous import ex
9 |
10 |
11 | @ex.command('file', 'f')
12 | class TokenCommandFile(TokenOfCommand):
13 | def __init__(self, *args, **kwargs):
14 | super().__init__({},
15 | TOKEN_COMMAND_FILE,
16 | 'file', *args, **kwargs)
17 | self.target_command = 'ex_file'
18 |
19 |
20 | def scan_command_file(state):
21 | bang = state.consume()
22 |
23 | if bang == EOF:
24 | return None, [TokenCommandFile(), TokenEof()]
25 |
26 | bang = bang == '!'
27 | if not bang:
28 | raise VimError(ERR_TRAILING_CHARS)
29 |
30 | state.expect(EOF, on_error=lambda: VimError(ERR_TRAILING_CHARS))
31 |
32 | return None, [TokenCommandFile (forced=bang == '!'), TokenEof ()]
33 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_global.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_GLOBAL
4 | from .tokens_base import TokenOfCommand
5 | from .parser import parse_command_line
6 | from Vintageous import ex
7 |
8 |
9 | @ex.command('global', 'g')
10 | class TokenCommandGlobal(TokenOfCommand):
11 | def __init__(self, params, *args, **kwargs):
12 | super().__init__(params,
13 | TOKEN_COMMAND_GLOBAL,
14 | 'global', *args, **kwargs)
15 | self.addressable = True
16 | self.target_command = 'ex_global'
17 |
18 | @property
19 | def pattern(self):
20 | return self.params['pattern']
21 |
22 | @property
23 | def subcommand(self):
24 | return self.params['subcommand']
25 |
26 |
27 | def scan_command_global(state):
28 | params = {
29 | 'pattern': None,
30 | 'subcommand': parse_command_line('print').command
31 | }
32 |
33 | c = state.consume()
34 |
35 | bang = c == '!'
36 | sep = c if not bang else c.consume()
37 | # TODO: we're probably missing legal separators.
38 | assert c in '!:?/\\&$', 'bad separator'
39 |
40 | state.ignore()
41 |
42 | while True:
43 | c = state.consume()
44 |
45 | if c == EOF:
46 | raise ValueError('unexpected EOF in: ' + state.source)
47 |
48 | if c == sep:
49 | state.backup()
50 | params['pattern'] = state.emit()
51 | state.consume()
52 | state.ignore()
53 | break
54 |
55 | command = state.match(r'.*$').group(0).strip()
56 | command = parse_command_line(command).command or params['subcommand']
57 | params['subcommand'] = command
58 |
59 | return None, [TokenCommandGlobal(params, forced=bang), TokenEof()]
60 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_goto.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_GOTO
4 | from .tokens_base import TokenOfCommand
5 |
6 |
7 | # This command cannot be scanned; it's the default command when no command is
8 | # named.
9 | class TokenCommandGoto(TokenOfCommand):
10 | def __init__(self, *args, **kwargs):
11 | super().__init__([],
12 | TOKEN_COMMAND_GOTO,
13 | 'goto', *args, **kwargs)
14 | self.target_command = 'ex_goto'
15 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_let.py:
--------------------------------------------------------------------------------
1 | from Vintageous.ex.ex_error import ERR_UNDEFINED_VARIABLE
2 | from Vintageous.ex.ex_error import VimError
3 |
4 | from .state import EOF
5 | from .tokens import TokenEof
6 | from .tokens_base import TOKEN_COMMAND_LET
7 | from .tokens_base import TokenOfCommand
8 | from Vintageous import ex
9 |
10 |
11 | @ex.command('let', 'let')
12 | class TokenCommandLet(TokenOfCommand):
13 | def __init__(self, params, *args, **kwargs):
14 | super().__init__(params,
15 | TOKEN_COMMAND_LET,
16 | 'let', *args, **kwargs)
17 | self.target_command = 'ex_let'
18 |
19 | @property
20 | def variable_name(self):
21 | return self.params['name']
22 |
23 | @property
24 | def variable_value(self):
25 | return self.params['value']
26 |
27 |
28 | def scan_command_let(state):
29 | params = {
30 | 'name': None,
31 | 'value': None,
32 | }
33 |
34 | # TODO(guillermooo): :let has many more options.
35 |
36 | m = state.expect_match(r'(?P.+?)\s*=\s*(?P.+?)\s*$',
37 | on_error=lambda: VimError(ERR_UNDEFINED_VARIABLE))
38 |
39 | params.update(m.groupdict())
40 |
41 | return None, [TokenCommandLet(params), TokenEof()]
42 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_map.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_MAP
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('map', 'map')
9 | class TokenCommandMap(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_MAP,
13 | 'map', *args, **kwargs)
14 | self.target_command = 'ex_map'
15 |
16 | @property
17 | def keys(self):
18 | return self.params['keys']
19 |
20 | @property
21 | def command(self):
22 | return self.params['command']
23 |
24 |
25 | def scan_command_map(state):
26 | params = {
27 | 'keys': None,
28 | 'command': None,
29 | }
30 |
31 | m = state.match(r'\s*(?P.+?)\s+(?P.+?)\s*$')
32 |
33 | if m:
34 | params.update(m.groupdict())
35 |
36 | return None, [TokenCommandMap(params), TokenEof()]
37 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_move.py:
--------------------------------------------------------------------------------
1 | from .parser import parse_command_line
2 | from .state import EOF
3 | from .tokens import TokenEof
4 | from .tokens_base import TOKEN_COMMAND_MOVE
5 | from .tokens_base import TokenOfCommand
6 | from Vintageous import ex
7 |
8 |
9 | @ex.command('move', 'm')
10 | class TokenMove(TokenOfCommand):
11 | def __init__(self, params, *args, **kwargs):
12 | super().__init__(params,
13 | TOKEN_COMMAND_MOVE,
14 | 'move', *args, **kwargs)
15 | self.addressable = True
16 | self.target_command = 'ex_move'
17 |
18 | @property
19 | def address(self):
20 | return self.params['address']
21 |
22 |
23 | def scan_command_move(state):
24 | params = {
25 | 'address': None
26 | }
27 |
28 | state.skip (' ')
29 | state.ignore()
30 |
31 | m = state.match(r'(?P.*$)')
32 | if m:
33 | address_command_line = m.group(0).strip() or '.'
34 | params['address'] = parse_command_line(address_command_line).line_range
35 |
36 | return None, [TokenMove(params), TokenEof()]
37 |
38 |
39 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_new.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_NEW
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | plus_plus_translations = {
9 | 'ff': 'fileformat',
10 | 'bin': 'binary',
11 | 'enc': 'fileencoding',
12 | 'nobin': 'nobinary',
13 | }
14 |
15 |
16 | @ex.command('new', 'new')
17 | class TokenNew(TokenOfCommand):
18 | def __init__(self, params, *args, **kwargs):
19 | super().__init__(params,
20 | TOKEN_COMMAND_NEW,
21 | 'new', *args, **kwargs)
22 | self.target_command = 'ex_new'
23 |
24 |
25 | def scan_command_new(state):
26 | params = {
27 | '++': None,
28 | 'cmd': None,
29 | }
30 | state.skip(' ')
31 | state.ignore()
32 |
33 | c = state.consume()
34 |
35 | if c == '+':
36 | state.expect('+')
37 | state.ignore()
38 | # TODO: expect_match should work with emit()
39 | # http://vimdoc.sourceforge.net/htmldoc/editing.html#[++opt]
40 | m = state.expect_match(
41 | r'(?:f(?:ile)?f(?:ormat)?|(?:file)?enc(?:oding)?|(?:no)?bin(?:ary)?|bad|edit)(?=\s|$)',
42 | lambda: VimError(ERR_INVALID_ARGUMENT))
43 | name = m.group(0)
44 | params['++'] = plus_plus_translations.get(name, name)
45 | state.ignore()
46 | raise NotImplementedError(':new not fully implemented')
47 |
48 | m = state.match(r'.+$')
49 | if m:
50 | params ['cmd'] = m.group(0).strip()
51 | raise NotImplementedError(':new not fully implemented')
52 |
53 | return None, [TokenNew(params), TokenEof()]
54 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_nmap.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_NMAP
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('nmap', 'nm')
9 | class TokenCommandNmap(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_NMAP,
13 | 'nmap', *args, **kwargs)
14 | self.target_command = 'ex_nmap'
15 |
16 | @property
17 | def keys(self):
18 | return self.params['keys']
19 |
20 | @property
21 | def command(self):
22 | return self.params['command']
23 |
24 |
25 | def scan_command_nmap(state):
26 | params = {
27 | 'keys': None,
28 | 'command': None,
29 | }
30 |
31 | m = state.match(r'\s*(?P.+?)\s+(?P.+?)\s*$')
32 |
33 | if m:
34 | params.update(m.groupdict())
35 |
36 | return None, [TokenCommandNmap(params), TokenEof()]
37 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_nunmap.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_NUNMAP
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('nunmap', 'nun')
9 | class TokenCommandNunmap(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_NUNMAP,
13 | 'nunmap', *args, **kwargs)
14 | self.target_command = 'ex_nunmap'
15 |
16 | @property
17 | def keys(self):
18 | return self.params['keys']
19 |
20 |
21 | def scan_command_nunmap(state):
22 | params = {
23 | 'keys': None,
24 | }
25 |
26 | m = state.match(r'\s*(?P.+?)\s*$')
27 |
28 | if m:
29 | params.update(m.groupdict())
30 |
31 | return None, [TokenCommandNunmap(params), TokenEof()]
32 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_omap.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_OMAP
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('omap', 'om')
9 | class TokenCommandOmap(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_OMAP,
13 | 'omap', *args, **kwargs)
14 | self.target_command = 'ex_omap'
15 |
16 | @property
17 | def keys(self):
18 | return self.params['keys']
19 |
20 | @property
21 | def command(self):
22 | return self.params['command']
23 |
24 |
25 | def scan_command_omap(state):
26 | params = {
27 | 'keys': None,
28 | 'command': None,
29 | }
30 |
31 | m = state.match(r'\s*(?P.+?)\s+(?P.+?)\s*$')
32 |
33 | if m:
34 | params.update(m.groupdict())
35 |
36 | return None, [TokenCommandOmap(params), TokenEof()]
37 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_only.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_ONLY
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('only', 'on')
9 | class TokenCommandOnly(TokenOfCommand):
10 | def __init__(self, *args, **kwargs):
11 | super().__init__({},
12 | TOKEN_COMMAND_ONLY,
13 | 'only', *args, **kwargs)
14 | self.target_command = 'ex_only'
15 |
16 |
17 | def scan_command_only(state):
18 | bang = state.consume()
19 |
20 | if bang == '!':
21 | state.ignore()
22 | state.expect(EOF)
23 | return None, [TokenCommandOnly(forced=True), TokenEof()]
24 |
25 | assert bang == EOF, 'trailing characters'
26 | return None, [TokenCommandOnly(), TokenEof()]
27 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_ounmap.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_OUNMAP
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('ounmap', 'ounm')
9 | class TokenCommandOunmap(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_OUNMAP,
13 | 'ounmap', *args, **kwargs)
14 | self.target_command = 'ex_ounmap'
15 |
16 | @property
17 | def keys(self):
18 | return self.params['keys']
19 |
20 |
21 | def scan_command_ounmap(state):
22 | params = {
23 | 'keys': None,
24 | }
25 |
26 | m = state.match(r'\s*(?P.+?)\s*$')
27 |
28 | if m:
29 | params.update(m.groupdict())
30 |
31 | return None, [TokenCommandOunmap(params), TokenEof()]
32 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_print.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_PRINT
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('print', 'p')
9 | class TokenCommandPrint(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_PRINT,
13 | 'print', *args, **kwargs)
14 | self.addressable = True
15 | self.cooperates_with_global = True
16 | self.target_command = 'ex_print'
17 |
18 | def __str__(self):
19 | return "{0} {1} {2}".format(self.content, ''.join(self.flags), self.count).strip()
20 |
21 | @property
22 | def count(self):
23 | return self.params['count']
24 |
25 | @property
26 | def flags(self):
27 | return self.params['flags']
28 |
29 |
30 | def scan_command_print(state):
31 | params = {
32 | 'count': '',
33 | 'flags': [],
34 | }
35 |
36 | while True:
37 | c = state.consume()
38 |
39 | state.skip(' ')
40 | state.ignore()
41 |
42 | if c == EOF:
43 | return None, [TokenCommandPrint(params), TokenEof()]
44 |
45 | if c.isdigit():
46 | state.match(r'\d*')
47 | params['count'] = state.emit()
48 | continue
49 |
50 | m = state.expect_match(r'[l#p]+')
51 | params['flags'] = list(m.group(0))
52 | state.ignore()
53 | state.expect(EOF)
54 | break
55 |
56 | return None, [TokenCommandPrint(params), TokenEof()]
57 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_print_working_dir.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_PRINT_WORKING_DIR
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('pwd', 'pwd')
9 | class TokenPrintWorkingDir(TokenOfCommand):
10 | def __init__(self, *args, **kwargs):
11 | super().__init__({},
12 | TOKEN_COMMAND_PRINT_WORKING_DIR,
13 | 'pwd', *args, **kwargs)
14 | self.target_command = 'ex_print_working_dir'
15 |
16 |
17 | def scan_command_print_working_dir(state):
18 | state.expect(EOF)
19 | return None, [TokenPrintWorkingDir(), TokenEof()]
20 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_quit_all_command.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_QUIT_ALL_COMMAND
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('quall', 'qa')
9 | class TokenQuitAllCommand(TokenOfCommand):
10 | def __init__(self, *args, **kwargs):
11 | super().__init__({},
12 | TOKEN_COMMAND_QUIT_ALL_COMMAND,
13 | 'qall', *args, **kwargs)
14 | self.target_command = 'ex_quit_all'
15 |
16 |
17 | def scan_command_quit_all_command(state):
18 | c = state.consume()
19 |
20 | bang = c == '!'
21 |
22 | state.expect(EOF)
23 |
24 | return None, [TokenQuitAllCommand(forced=bang), TokenEof()]
25 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_quit_command.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_QUIT_COMMAND
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('quit', 'q')
9 | class TokenQuitCommand(TokenOfCommand):
10 | def __init__(self, *args, **kwargs):
11 | super().__init__({},
12 | TOKEN_COMMAND_QUIT_COMMAND,
13 | 'quit', *args, **kwargs)
14 | self.target_command = 'ex_quit'
15 |
16 |
17 | def scan_command_quit_command(state):
18 | c = state.consume()
19 |
20 | bang = c == '!'
21 |
22 | state.expect(EOF)
23 |
24 | return None, [TokenQuitCommand(forced=bang), TokenEof()]
25 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_register.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_REGISTERS
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('registers', 'reg')
9 | class TokenCommandRegisters(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_REGISTERS,
13 | 'registers', *args, **kwargs)
14 | self.target_command = 'ex_list_registers'
15 |
16 |
17 | def scan_command_register(state):
18 | state.skip(' ')
19 | state.ignore()
20 |
21 | params = {
22 | 'names': []
23 | }
24 |
25 | while True:
26 | c = state.consume()
27 |
28 | if c == EOF:
29 | return None, [TokenCommandRegisters(params), TokenEof()]
30 |
31 | elif c.isalpha() or c.isdigit():
32 | params['names'].append(c)
33 |
34 | else:
35 | raise ValueError('wrong arguments')
36 |
--------------------------------------------------------------------------------
/ex/parser/scanner_command_set.py:
--------------------------------------------------------------------------------
1 | from .state import EOF
2 | from .tokens import TokenEof
3 | from .tokens_base import TOKEN_COMMAND_SET
4 | from .tokens_base import TokenOfCommand
5 | from Vintageous import ex
6 |
7 |
8 | @ex.command('set', 'set')
9 | class TokenSet(TokenOfCommand):
10 | def __init__(self, params, *args, **kwargs):
11 | super().__init__(params,
12 | TOKEN_COMMAND_SET,
13 | 'set', *args, **kwargs)
14 | self.target_command = 'ex_set'
15 |
16 | @property
17 | def value(self):
18 | return self.params ['value']
19 |
20 | @property
21 | def option(self):
22 | return self.params ['option']
23 |
24 |
25 | def scan_command_set(state):
26 | params = {
27 | 'option': None,
28 | 'value': None,
29 | }
30 |
31 | state.skip(' ')
32 | state.ignore()
33 |
34 | # TODO(guillermooo): implement other options.
35 | m = state.expect_match(r'(?P