├── .eslintrc.json
├── .gitignore
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── keymaps
└── markdown-table-editor.json
├── lib
├── controller.js
├── editor-controller.js
├── markdown-table-editor.js
└── text-editor-interface.js
├── menus
└── markdown-table-editor.json
├── package-lock.json
├── package.json
└── spec
├── .eslintrc.json
├── markdown-table-editor-spec.js
└── text-editor-interface-spec.js
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "parserOptions": {
3 | "ecmaVersion": 8,
4 | "sourceType": "module"
5 | },
6 | "env": {
7 | "es6": true,
8 | "node": true,
9 | "browser": true
10 | },
11 | "globals": {
12 | "atom": true
13 | },
14 | "extends": "eslint:recommended",
15 | "rules": {
16 | "for-direction": ["warn"],
17 | "getter-return": ["error"],
18 | "no-cond-assign": ["warn", "always"],
19 | "no-control-regex": ["off"],
20 | "no-template-curly-in-string": ["warn"],
21 | "no-unsafe-negation": ["error"],
22 | "valid-jsdoc": ["warn", {
23 | "requireParamDescription": false,
24 | "requireReturnDescription": false }],
25 |
26 | "array-callback-return": ["error"],
27 | "consistent-return": ["error"],
28 | "curly": ["error"],
29 | "default-case": ["error"],
30 | "dot-location": ["error", "property"],
31 | "eqeqeq": ["error"],
32 | "no-alert": ["error"],
33 | "no-caller": ["error"],
34 | "no-eval": ["error"],
35 | "no-extend-native": ["error"],
36 | "no-extra-bind": ["error"],
37 | "no-extra-label": ["error"],
38 | "no-floating-decimal": ["error"],
39 | "no-implicit-coercion": ["error", {
40 | "allow": ["!!"] }],
41 | "no-implicit-globals": ["error"],
42 | "no-implied-eval": ["error"],
43 | "no-invalid-this": ["warn"],
44 | "no-iterator": ["error"],
45 | "no-lone-blocks": ["error"],
46 | "no-loop-func": ["error"],
47 | "no-multi-str": ["error"],
48 | "no-new": ["error"],
49 | "no-param-reassign": ["error"],
50 | "no-proto": ["error"],
51 | "no-return-assign": ["error"],
52 | "no-return-await": ["error"],
53 | "no-self-compare": ["error"],
54 | "no-sequences": ["error"],
55 | "no-throw-literal": ["warn"],
56 | "no-unmodified-loop-condition": ["error"],
57 | "no-unused-expressions": ["error"],
58 | "no-useless-call": ["error"],
59 | "no-useless-concat": ["error"],
60 | "no-useless-return": ["error"],
61 | "no-void": ["error"],
62 | "no-warning-comments": ["warn"],
63 | "no-with": ["error"],
64 | "require-await": ["warn"],
65 | "wrap-iife": ["error"],
66 |
67 | "strict": ["error"],
68 |
69 | "no-label-var": ["error"],
70 | "no-shadow-restricted-names": ["error"],
71 | "no-unused-vars": ["error", {
72 | "args": "none" }],
73 | "no-use-before-define": ["error", {
74 | "functions": false,
75 | "classes": false }],
76 |
77 | "array-bracket-spacing": ["error", "never"],
78 | "block-spacing": ["error", "always"],
79 | "brace-style": ["error", "stroustrup", {
80 | "allowSingleLine": true }],
81 | "camelcase": ["error", {
82 | "properties": "never" }],
83 | "comma-dangle": ["error", "only-multiline"],
84 | "comma-spacing": ["error", {
85 | "before": false,
86 | "after": true }],
87 | "comma-style": ["error", "last"],
88 | "computed-property-spacing": ["error", "never"],
89 | "eol-last": ["error"],
90 | "func-call-spacing": ["error", "never"],
91 | "func-name-matching": ["error"],
92 | "func-style": ["error", "declaration", {
93 | "allowArrowFunctions": true }],
94 | "indent": ["error", 2, {
95 | "VariableDeclarator": {
96 | "var": 2,
97 | "let": 2,
98 | "const": 3 },
99 | "ignoredNodes": ["ConditionalExpression"] }],
100 | "jsx-quotes": ["error", "prefer-double"],
101 | "key-spacing": ["error", {
102 | "beforeColon": false,
103 | "afterColon": true,
104 | "align": "colon" }],
105 | "keyword-spacing": ["error", {
106 | "before": true,
107 | "after": true }],
108 | "linebreak-style": ["error", "unix"],
109 | "lines-between-class-members": ["error", "always", {
110 | "exceptAfterSingleLine": true }],
111 | "max-len": ["error", {
112 | "code": 100,
113 | "ignoreComments": true,
114 | "ignoreStrings": true,
115 | "ignoreTemplateLiterals": true,
116 | "ignoreRegExpLiterals": true }],
117 | "new-cap": ["error"],
118 | "new-parens": ["error"],
119 | "no-array-constructor": ["error"],
120 | "no-multi-assign": ["error"],
121 | "no-multiple-empty-lines": ["error", {
122 | "max": 2,
123 | "maxBOF": 0,
124 | "maxEOF": 0 }],
125 | "no-new-object": ["error"],
126 | "no-plusplus": ["error", {
127 | "allowForLoopAfterthoughts": true }],
128 | "no-tabs": ["error"],
129 | "no-trailing-spaces": ["error"],
130 | "no-unneeded-ternary": ["error"],
131 | "no-whitespace-before-property": ["error"],
132 | "object-curly-spacing": ["error", "always"],
133 | "operator-linebreak": ["error", "before", {
134 | "overrides": {
135 | "=": "after",
136 | "+=": "after",
137 | "-=": "after",
138 | "*=": "after",
139 | "/=": "after",
140 | "%=": "after",
141 | "**=": "after",
142 | "<<=": "after",
143 | ">>=": "after",
144 | ">>>=": "after",
145 | "&=": "after",
146 | "^=": "after",
147 | "|=": "after" } }],
148 | "padded-blocks": ["error", "never"],
149 | "quote-props": ["error", "consistent-as-needed"],
150 | "quotes": ["error", "double"],
151 | "semi": ["error", "always"],
152 | "semi-spacing": ["error", {
153 | "before": false,
154 | "after": true }],
155 | "semi-style": ["error", "last"],
156 | "space-before-blocks": ["error", "always"],
157 | "space-before-function-paren": ["error", {
158 | "anonymous": "always",
159 | "named": "never" }],
160 | "space-in-parens": ["error", "never"],
161 | "space-infix-ops": ["error"],
162 | "space-unary-ops": ["error", {
163 | "words": true,
164 | "nonwords": false }],
165 | "spaced-comment": ["error", "always"],
166 | "switch-colon-spacing": ["error", {
167 | "before": false,
168 | "after": true }],
169 | "template-tag-spacing": ["error", "never"],
170 | "unicode-bom": ["error", "never"],
171 |
172 | "arrow-body-style": ["error", "as-needed"],
173 | "arrow-parens": ["error", "as-needed"],
174 | "arrow-spacing": ["error", {
175 | "before": true,
176 | "after": true }],
177 | "generator-star-spacing": ["error", {
178 | "before": false,
179 | "after": true,
180 | "method": {
181 | "before": true,
182 | "after": false } }],
183 | "no-duplicate-imports": ["error"],
184 | "no-useless-computed-key": ["error"],
185 | "no-var": ["error"],
186 | "prefer-arrow-callback": ["error"],
187 | "prefer-const": ["error"],
188 | "prefer-numeric-literals": ["error"],
189 | "prefer-rest-params": ["error"],
190 | "prefer-spread": ["error"],
191 | "require-yield": ["warn"],
192 | "rest-spread-spacing": ["error", "never"],
193 | "yield-star-spacing": ["error", {
194 | "before": false,
195 | "after": true }]
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### https://raw.github.com/github/gitignore/e9c3096114fd81b92cf989f7343d7b168b80d994/Node.gitignore
2 |
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 |
10 | # Runtime data
11 | pids
12 | *.pid
13 | *.seed
14 | *.pid.lock
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Bower dependency directory (https://bower.io/)
29 | bower_components
30 |
31 | # node-waf configuration
32 | .lock-wscript
33 |
34 | # Compiled binary addons (https://nodejs.org/api/addons.html)
35 | build/Release
36 |
37 | # Dependency directories
38 | node_modules/
39 | jspm_packages/
40 |
41 | # TypeScript v1 declaration files
42 | typings/
43 |
44 | # Optional npm cache directory
45 | .npm
46 |
47 | # Optional eslint cache
48 | .eslintcache
49 |
50 | # Optional REPL history
51 | .node_repl_history
52 |
53 | # Output of 'npm pack'
54 | *.tgz
55 |
56 | # Yarn Integrity file
57 | .yarn-integrity
58 |
59 | # dotenv environment variables file
60 | .env
61 |
62 | # next.js build output
63 | .next
64 |
65 | # Temporary/working files
66 | temp/
67 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.1.3
2 | * Fix [#31](https://github.com/susisu/atom-markdown-table-editor/issues/31)
3 | * Update Unicode East Asian Width to 13.0.0
4 |
5 | ## 1.1.2
6 | * Update dependencies
7 | * In particular, update Unicode East Asian Width to 12.1.0
8 |
9 | ## 1.1.1
10 | * Add "Set Format Type" commands that can explicitly change "Format Type" config
11 | * Show notifications when config is changed by the commands
12 |
13 | ## 1.1.0
14 | * Add "Left Margin Characters" config
15 | - For example, you can enable markdown-table-editor in JavaScript comments by adding `comment.block.documentation.js` to "Scopes" and `*` to "Left Margin Characters".
16 |
17 | ## 1.0.2
18 | * Disable Esc keymap in [vim-mode-plus](https://atom.io/packages/vim-mode-plus)
19 |
20 | ## 1.0.1
21 | * Fix a problem about smart cursor
22 |
23 | ## 1.0.0
24 | * Overhauled using [mte-kernel](https://github.com/susisu/mte-kernel)
25 | * Add "Format All" command
26 | * Add "Format On Save" option and "Toggle Format On Save" command
27 | * Add "Unicode Normalization" option for computing text widths
28 | * Enable "Smart Cursor" by default
29 | * Rename some options (old ones will be automatically migrated to the new ones)
30 |
31 | ## 0.6.4
32 | * Add "Move Row" and "Move Column" commands
33 |
34 | ## 0.6.3
35 | * Add config to change default cell alignment and header cell alignment
36 |
37 | ## 0.6.2
38 | * Add menu items
39 | * Add "Format Type" config, which specifies how a table is formatted on each operation
40 | * Add a command to switch the format type
41 |
42 | ## 0.6.1
43 | * Fix error when trying to align a column but the cursor is out of the table ([#4](https://github.com/susisu/markdown-table-editor/issues/4))
44 |
45 | ## 0.6.0
46 | * Use scopes instead of grammar to determine active or not
47 | - The default config is changed from `source.gfm, text.md` to `table.gfm, table.storage.md`
48 |
49 | ## 0.5.2
50 | * Small improvements
51 |
52 | ## 0.5.1
53 | * Replace library for computing East Asian Width property
54 |
55 | ## 0.5.0
56 | * Always enable Unicode East Asian Width features
57 | * Disable "Treat East Asian Ambiguous Characters As Wide" by default
58 |
59 | ## 0.4.4
60 | * Add "Always Wide/Narrow Characters" settings, allows to override character width
61 |
62 | ## 0.4.3
63 | * Small change
64 |
65 | ## 0.4.2
66 | * Add "Treat East Asian Ambiguous Characters As Wide" option
67 |
68 | ## 0.4.1
69 | * Improve settings' descriptions
70 |
71 | ## 0.4.0
72 | * Modify behavior of "Next Cell"
73 | - To move to the next row from the right end, press `enter` instead of `tab`
74 |
75 | ## 0.3.0
76 | * Add "Smart Cursor" option, which enables more sophisticated cursor movement (like MS Office)
77 | * Small changes
78 |
79 | ## 0.2.0
80 | * Add more commands
81 | * Small improvements
82 |
83 | ## 0.1.1
84 | * Adds description in `package.json`
85 |
86 | ## 0.1.0
87 | * First release
88 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 Susisu
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # markdown-table-editor
2 | Markdown table editor/formatter
3 |
4 | 
5 |
6 | ## Quick guide
7 | 0. Set editor's grammar to `GitHub Markdown` or `Markdown`.
8 | 1. Input a pipe `|` and some content (the cursor position is indicated by `_`).
9 | ``` markdown
10 | | foo_
11 | ```
12 | (If you are using [language-markdown](https://atom.io/packages/language-markdown), don't forget a space after a pipe.)
13 | 2. Hit tab to move to the next cell.
14 | ``` markdown
15 | | foo | _
16 | | --- |
17 | ```
18 | 3. Continue typing.
19 | ``` markdown
20 | | foo | bar | _
21 | | --- | --- |
22 | ```
23 | 4. Hit enter to move to the next row.
24 | ``` markdown
25 | | foo | bar |
26 | | --- | --- |
27 | | _ | |
28 | ```
29 | 5. Continue typing...
30 | ``` markdown
31 | | foo | bar |
32 | | --- | --- |
33 | | baz | _ |
34 | ```
35 | 6. Hit esc to finish editing the table.
36 | ``` markdown
37 | | foo | bar |
38 | | --- | --- |
39 | | baz | |
40 | _
41 | ```
42 |
43 | ## Features
44 | * Format tables
45 | * Move the cursor from cell to cell
46 | * Alter column's alignment
47 | * Insert and delete rows and columns
48 |
49 | ### Commands
50 | | Name | Description | Keybinding |
51 | | ---------------------- | ---------------------------------------- | --------------------------------- |
52 | | Next Cell | Move to the next cell | tab |
53 | | Previous Cell | Move to the previous cell | shift + tab |
54 | | Next Row | Move to the next row | enter |
55 | | Escape | Escape from the table | escape |
56 | | Format | Just format the table | |
57 | | Format All | Format all the tables in the text editor | |
58 | | Align Left | Left-align the column | |
59 | | Align Right | Right-align the column | |
60 | | Align Center | Center-align the column | |
61 | | Align None | Unset alignment of the column | |
62 | | Select Cell | Select the cell content | |
63 | | Move Left | Move to the left cell | |
64 | | Move Right | Move to the right cell | |
65 | | Move Up | Move to the upper cell | |
66 | | Move Down | Move to the lower cell | |
67 | | Insert Row | Insert an empty row | |
68 | | Delete Row | Delete the row | |
69 | | Move Row Up | Move the row up | |
70 | | Move Row Down | Move the row down | |
71 | | Insert Column | Insert an empty column | |
72 | | Delete Column | Delete the column | |
73 | | Move Column Left | Move the column left | |
74 | | Move Column Right | Move the column right | |
75 | | Toggle Format On Save | Toggle "Format On Save" config | |
76 | | Switch Format Type | Switch "Format Type" config | |
77 | | Set Format Type Normal | Set "Format Type" config to "Normal" | |
78 | | Set Format Type Weak | Set "Format Type" config to "Weak" | |
79 |
80 | (To input a newline in a table, press shift + enter (or some equivalent) instead.)
81 |
82 | You can execute commands from the command palette (Windows, Linux: ctrl + shift + p / macOS: cmd + shift + p) or from the Packages menu.
83 |
84 | It will be more convenient if you add some keybindings to your `keymap.cson`.
85 | Here are the ones which I use:
86 |
87 | ``` coffee
88 | 'atom-text-editor:not(.mini):not(.autocomplete-active).markdown-table-editor-active':
89 | 'cmd-left' : 'markdown-table-editor:move-left'
90 | 'cmd-right' : 'markdown-table-editor:move-right'
91 | 'cmd-up' : 'markdown-table-editor:move-up'
92 | 'cmd-down' : 'markdown-table-editor:move-down'
93 | 'shift-cmd-left' : 'markdown-table-editor:align-left'
94 | 'shift-cmd-right' : 'markdown-table-editor:align-right'
95 | 'shift-cmd-up' : 'markdown-table-editor:align-center'
96 | 'shift-cmd-down' : 'markdown-table-editor:align-none'
97 | 'alt-shift-cmd-left' : 'markdown-table-editor:move-column-left'
98 | 'alt-shift-cmd-right': 'markdown-table-editor:move-column-right'
99 | 'alt-shift-cmd-up' : 'markdown-table-editor:move-row-up'
100 | 'alt-shift-cmd-down' : 'markdown-table-editor:move-row-down'
101 | 'cmd-k cmd-i' : 'markdown-table-editor:insert-row'
102 | 'cmd-k alt-cmd-i' : 'markdown-table-editor:delete-row'
103 | 'cmd-k cmd-j' : 'markdown-table-editor:insert-column'
104 | 'cmd-k alt-cmd-j' : 'markdown-table-editor:delete-column'
105 | ```
106 |
107 | ## FAQ
108 | ### Q. My table does not align well when dealing with Chinese characters
109 | A. Use a monospaced font that includes glyphs for Chinese characters, such as [Noto Sans Mono CJK](https://github.com/googlei18n/noto-cjk).
110 | markdown-table-editor supports East Asian characters including Chinese characters :)
111 |
112 | ## For developers
113 | This package is based on [markdown-table-editor kernel](https://github.com/susisu/mte-kernel), which provides a text editor independent implementation of the functionality of the package.
114 | You can create a markdown-table-editor plugin for your favorite text editor with ease!
115 |
--------------------------------------------------------------------------------
/keymaps/markdown-table-editor.json:
--------------------------------------------------------------------------------
1 | {
2 | "atom-text-editor:not(.mini):not(.autocomplete-active).markdown-table-editor-active": {
3 | "tab" : "markdown-table-editor:next-cell",
4 | "shift-tab": "markdown-table-editor:previous-cell",
5 | "enter" : "markdown-table-editor:next-row"
6 | },
7 | "atom-text-editor:not(.mini):not(.autocomplete-active):not(.vim-mode-plus).markdown-table-editor-active": {
8 | "escape": "markdown-table-editor:escape"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/lib/controller.js:
--------------------------------------------------------------------------------
1 | import { CompositeDisposable } from "atom";
2 | import { FormatType } from "@susisu/mte-kernel";
3 |
4 | import EditorController from "./editor-controller.js";
5 |
6 | const COMMAND_TARGET = "atom-text-editor:not(.mini):not(.autocomplete-active)";
7 | const EDITOR_COMMAND_TARGET = COMMAND_TARGET + ".markdown-table-editor-active";
8 | const NAMESPACE = "markdown-table-editor";
9 |
10 | const FORMAT_TYPES = [FormatType.NORMAL, FormatType.WEAK];
11 | const FORMAT_TYPE_NAMES = {
12 | [FormatType.NORMAL]: "Normal",
13 | [FormatType.WEAK] : "Weak"
14 | };
15 |
16 | export default class Controller {
17 | constructor() {
18 | this.editorCtrlers = new Map();
19 |
20 | // event subscriptions
21 | this.subscriptions = new CompositeDisposable();
22 |
23 | // editor
24 | this.subscriptions.add(atom.workspace.observeTextEditors(editor => {
25 | this.addEditor(editor);
26 | }));
27 | this.subscriptions.add(atom.workspace.onDidDestroyPaneItem(item => {
28 | this.removeEditor(item);
29 | }));
30 |
31 | // commands
32 | this.subscriptions.add(atom.commands.add(COMMAND_TARGET, {
33 | [`${NAMESPACE}:toggle-format-on-save`]: () => {
34 | this.toggleFormatOnSave();
35 | },
36 | [`${NAMESPACE}:switch-format-type`]: () => {
37 | this.switchFormatType();
38 | },
39 | [`${NAMESPACE}:set-format-type-normal`]: () => {
40 | this.setFormatType(FormatType.NORMAL);
41 | },
42 | [`${NAMESPACE}:set-format-type-weak`]: () => {
43 | this.setFormatType(FormatType.WEAK);
44 | },
45 | [`${NAMESPACE}:format-all`]: this.editorCommand(editorCtrler => {
46 | editorCtrler.formatAll();
47 | })
48 | }));
49 | this.subscriptions.add(atom.commands.add(EDITOR_COMMAND_TARGET, {
50 | [`${NAMESPACE}:format`]: this.editorCommand(editorCtrler => {
51 | editorCtrler.format();
52 | }),
53 | [`${NAMESPACE}:escape`]: this.editorCommand(editorCtrler => {
54 | editorCtrler.escape();
55 | }),
56 | [`${NAMESPACE}:align-left`]: this.editorCommand(editorCtrler => {
57 | editorCtrler.alignLeft();
58 | }),
59 | [`${NAMESPACE}:align-right`]: this.editorCommand(editorCtrler => {
60 | editorCtrler.alignRight();
61 | }),
62 | [`${NAMESPACE}:align-center`]: this.editorCommand(editorCtrler => {
63 | editorCtrler.alignCenter();
64 | }),
65 | [`${NAMESPACE}:align-none`]: this.editorCommand(editorCtrler => {
66 | editorCtrler.alignNone();
67 | }),
68 | [`${NAMESPACE}:align-default`]: this.editorCommand(editorCtrler => {
69 | editorCtrler.alignNone();
70 | }),
71 | [`${NAMESPACE}:select-cell`]: this.editorCommand(editorCtrler => {
72 | editorCtrler.selectCell();
73 | }),
74 | [`${NAMESPACE}:move-left`]: this.editorCommand(editorCtrler => {
75 | editorCtrler.moveLeft();
76 | }),
77 | [`${NAMESPACE}:move-right`]: this.editorCommand(editorCtrler => {
78 | editorCtrler.moveRight();
79 | }),
80 | [`${NAMESPACE}:move-up`]: this.editorCommand(editorCtrler => {
81 | editorCtrler.moveUp();
82 | }),
83 | [`${NAMESPACE}:move-down`]: this.editorCommand(editorCtrler => {
84 | editorCtrler.moveDown();
85 | }),
86 | [`${NAMESPACE}:next-cell`]: this.editorCommand(editorCtrler => {
87 | editorCtrler.nextCell();
88 | }),
89 | [`${NAMESPACE}:previous-cell`]: this.editorCommand(editorCtrler => {
90 | editorCtrler.previousCell();
91 | }),
92 | [`${NAMESPACE}:next-row`]: this.editorCommand(editorCtrler => {
93 | editorCtrler.nextRow();
94 | }),
95 | [`${NAMESPACE}:insert-row`]: this.editorCommand(editorCtrler => {
96 | editorCtrler.insertRow();
97 | }),
98 | [`${NAMESPACE}:delete-row`]: this.editorCommand(editorCtrler => {
99 | editorCtrler.deleteRow();
100 | }),
101 | [`${NAMESPACE}:move-row-up`]: this.editorCommand(editorCtrler => {
102 | editorCtrler.moveRowUp();
103 | }),
104 | [`${NAMESPACE}:move-row-down`]: this.editorCommand(editorCtrler => {
105 | editorCtrler.moveRowDown();
106 | }),
107 | [`${NAMESPACE}:insert-column`]: this.editorCommand(editorCtrler => {
108 | editorCtrler.insertColumn();
109 | }),
110 | [`${NAMESPACE}:delete-column`]: this.editorCommand(editorCtrler => {
111 | editorCtrler.deleteColumn();
112 | }),
113 | [`${NAMESPACE}:move-column-left`]: this.editorCommand(editorCtrler => {
114 | editorCtrler.moveColumnLeft();
115 | }),
116 | [`${NAMESPACE}:move-column-right`]: this.editorCommand(editorCtrler => {
117 | editorCtrler.moveColumnRight();
118 | })
119 | }));
120 | }
121 |
122 | addEditor(editor) {
123 | const editorCtrler = new EditorController(editor);
124 | this.editorCtrlers.set(editor.element, editorCtrler);
125 | }
126 |
127 | removeEditor(editor) {
128 | this.editorCtrlers.delete(editor.element);
129 | }
130 |
131 | toggleFormatOnSave() {
132 | const formatOnSave = atom.config.get(`${NAMESPACE}.formatOnSave`);
133 | atom.config.set(`${NAMESPACE}.formatOnSave`, !formatOnSave);
134 | atom.notifications.addInfo("markdown-table-editor", {
135 | detail: `"Format On Save" is turned ${!formatOnSave ? "on" : "off"}`
136 | });
137 | }
138 |
139 | switchFormatType() {
140 | const formatType = atom.config.get(`${NAMESPACE}.formatType`);
141 | const i = FORMAT_TYPES.indexOf(formatType);
142 | const newFormatType = FORMAT_TYPES[i + 1 > FORMAT_TYPES.length - 1 ? 0 : i + 1];
143 | atom.config.set(`${NAMESPACE}.formatType`, newFormatType);
144 | atom.notifications.addInfo("markdown-table-editor", {
145 | detail: `"Format Type" is switched to "${FORMAT_TYPE_NAMES[newFormatType]}"`
146 | });
147 | }
148 |
149 | setFormatType(type) {
150 | atom.config.set(`${NAMESPACE}.formatType`, type);
151 | atom.notifications.addInfo("markdown-table-editor", {
152 | detail: `"Format Type" is set to "${FORMAT_TYPE_NAMES[type]}"`
153 | });
154 | }
155 |
156 | editorCommand(callback) {
157 | return event => {
158 | if (this.editorCtrlers.has(event.currentTarget)) {
159 | callback(this.editorCtrlers.get(event.currentTarget));
160 | }
161 | };
162 | }
163 |
164 | destroy() {
165 | this.subscriptions.dispose();
166 |
167 | for (const editorCtrler of this.editorCtrlers.values()) {
168 | editorCtrler.destroy();
169 | }
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/lib/editor-controller.js:
--------------------------------------------------------------------------------
1 | import { CompositeDisposable } from "atom";
2 | import { TableEditor, options, Alignment } from "@susisu/mte-kernel";
3 |
4 | import TextEditorInterface from "./text-editor-interface.js";
5 |
6 | const NAMESPACE = "markdown-table-editor";
7 | const ACTIVE_CLASS = "markdown-table-editor-active";
8 |
9 | export default class EditorController {
10 | constructor(editor) {
11 | this.editor = editor;
12 | this.editorIntf = new TextEditorInterface(this.editor, atom.config.get(`${NAMESPACE}.scopes`));
13 | this.tableEditor = new TableEditor(this.editorIntf);
14 |
15 | this.updateActiveState();
16 |
17 | // event subscriptions
18 | this.subscriptions = new CompositeDisposable();
19 |
20 | // editor
21 | this.subscriptions.add(this.editor.onDidChangeGrammar(() => {
22 | this.updateActiveState();
23 | }));
24 | this.subscriptions.add(this.editor.onDidAddCursor(() => {
25 | this.updateActiveState();
26 | }));
27 | this.subscriptions.add(this.editor.onDidRemoveCursor(() => {
28 | this.updateActiveState();
29 | }));
30 | this.subscriptions.add(this.editor.onDidChangeCursorPosition(event => {
31 | if (!this.editorIntf.transaction
32 | && event.newBufferPosition.row !== event.oldBufferPosition.row) {
33 | this.updateActiveState();
34 | }
35 | }));
36 | this.subscriptions.add(this.editor.onDidStopChanging(() => {
37 | if (!this.editorIntf.transaction) {
38 | this.updateActiveState();
39 | }
40 | }));
41 | this.subscriptions.add(this.editorIntf.onDidFinishTransaction(() => {
42 | this.updateActiveState();
43 | }));
44 | this.subscriptions.add(this.editor.getBuffer().onWillSave(() => {
45 | if (atom.config.get(`${NAMESPACE}.formatOnSave`)) {
46 | this.formatAll();
47 | }
48 | }));
49 |
50 | // config
51 | this.subscriptions.add(atom.config.observe(`${NAMESPACE}.scopes`, scopes => {
52 | this.editorIntf.scopes = scopes;
53 | this.updateActiveState();
54 | }));
55 | }
56 |
57 | updateActiveState() {
58 | const isActive = !this.editor.hasMultipleCursors()
59 | && this.tableEditor.cursorIsInTable(this.getOptions());
60 | if (isActive) {
61 | this.editor.element.classList.add(ACTIVE_CLASS);
62 | }
63 | else {
64 | this.editor.element.classList.remove(ACTIVE_CLASS);
65 | this.tableEditor.resetSmartCursor();
66 | }
67 | }
68 |
69 | getOptions() {
70 | const configOpt = {
71 | scope: this.editor.scopeDescriptorForBufferPosition(this.editor.getCursorBufferPosition())
72 | };
73 | return options({
74 | leftMarginChars : new Set(atom.config.get(`${NAMESPACE}.leftMarginChars`, configOpt)),
75 | formatType : atom.config.get(`${NAMESPACE}.formatType`, configOpt),
76 | minDelimiterWidth: atom.config.get(`${NAMESPACE}.minDelimiterWidth`, configOpt),
77 | defaultAlignment : atom.config.get(`${NAMESPACE}.defaultAlignment`, configOpt),
78 | headerAlignment : atom.config.get(`${NAMESPACE}.headerAlignment`, configOpt),
79 | smartCursor : atom.config.get(`${NAMESPACE}.smartCursor`, configOpt),
80 | textWidthOptions : {
81 | normalize : atom.config.get(`${NAMESPACE}.normalize`, configOpt),
82 | wideChars : new Set(atom.config.get(`${NAMESPACE}.wideChars`, configOpt)),
83 | narrowChars : new Set(atom.config.get(`${NAMESPACE}.narrowChars`, configOpt)),
84 | ambiguousAsWide: atom.config.get(`${NAMESPACE}.ambiguousAsWide`, configOpt)
85 | }
86 | });
87 | }
88 |
89 | format() {
90 | this.tableEditor.format(this.getOptions());
91 | }
92 |
93 | formatAll() {
94 | this.tableEditor.formatAll(this.getOptions());
95 | }
96 |
97 | escape() {
98 | this.tableEditor.escape(this.getOptions());
99 | }
100 |
101 | alignLeft() {
102 | this.tableEditor.alignColumn(Alignment.LEFT, this.getOptions());
103 | }
104 |
105 | alignRight() {
106 | this.tableEditor.alignColumn(Alignment.RIGHT, this.getOptions());
107 | }
108 |
109 | alignCenter() {
110 | this.tableEditor.alignColumn(Alignment.CENTER, this.getOptions());
111 | }
112 |
113 | alignNone() {
114 | this.tableEditor.alignColumn(Alignment.NONE, this.getOptions());
115 | }
116 |
117 | selectCell() {
118 | this.tableEditor.selectCell(this.getOptions());
119 | }
120 |
121 | moveLeft() {
122 | this.tableEditor.moveFocus(0, -1, this.getOptions());
123 | }
124 |
125 | moveRight() {
126 | this.tableEditor.moveFocus(0, 1, this.getOptions());
127 | }
128 |
129 | moveUp() {
130 | this.tableEditor.moveFocus(-1, 0, this.getOptions());
131 | }
132 |
133 | moveDown() {
134 | this.tableEditor.moveFocus(1, 0, this.getOptions());
135 | }
136 |
137 | nextCell() {
138 | this.tableEditor.nextCell(this.getOptions());
139 | }
140 |
141 | previousCell() {
142 | this.tableEditor.previousCell(this.getOptions());
143 | }
144 |
145 | nextRow() {
146 | this.tableEditor.nextRow(this.getOptions());
147 | }
148 |
149 | insertRow() {
150 | this.tableEditor.insertRow(this.getOptions());
151 | }
152 |
153 | deleteRow() {
154 | this.tableEditor.deleteRow(this.getOptions());
155 | }
156 |
157 | moveRowUp() {
158 | this.tableEditor.moveRow(-1, this.getOptions());
159 | }
160 |
161 | moveRowDown() {
162 | this.tableEditor.moveRow(1, this.getOptions());
163 | }
164 |
165 | insertColumn() {
166 | this.tableEditor.insertColumn(this.getOptions());
167 | }
168 |
169 | deleteColumn() {
170 | this.tableEditor.deleteColumn(this.getOptions());
171 | }
172 |
173 | moveColumnLeft() {
174 | this.tableEditor.moveColumn(-1, this.getOptions());
175 | }
176 |
177 | moveColumnRight() {
178 | this.tableEditor.moveColumn(1, this.getOptions());
179 | }
180 |
181 | destroy() {
182 | this.subscriptions.dispose();
183 | this.editorIntf.destroy();
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/lib/markdown-table-editor.js:
--------------------------------------------------------------------------------
1 | import Controller from "./controller.js";
2 |
3 | const NAMESPACE = "markdown-table-editor";
4 |
5 | class MarkdownTableEditor {
6 | constructor() {
7 | this.controller = null;
8 | }
9 |
10 | activate() {
11 | this.controller = new Controller();
12 | // migrate old configurations
13 | const grammars = atom.config.get(`${NAMESPACE}.grammars`);
14 | if (grammars !== undefined) {
15 | atom.config.set(`${NAMESPACE}.scopes`, grammars);
16 | atom.config.unset(`${NAMESPACE}.grammars`);
17 | }
18 | const minimumContentWidth = atom.config.get(`${NAMESPACE}.minimumContentWidth`);
19 | if (minimumContentWidth !== undefined) {
20 | atom.config.set(`${NAMESPACE}.minDelimiterWidth`, minimumContentWidth);
21 | atom.config.unset(`${NAMESPACE}.minimumContentWidth`);
22 | }
23 | const eawAmbiguousAsWide = atom.config.get(`${NAMESPACE}.eawAmbiguousAsWide`);
24 | if (eawAmbiguousAsWide !== undefined) {
25 | atom.config.set(`${NAMESPACE}.ambiguousAsWide`, eawAmbiguousAsWide);
26 | atom.config.unset(`${NAMESPACE}.eawAmbiguousAsWide`);
27 | }
28 | const alwaysWideChars = atom.config.get(`${NAMESPACE}.alwaysWideChars`);
29 | if (alwaysWideChars !== undefined) {
30 | atom.config.set(`${NAMESPACE}.wideChars`, alwaysWideChars);
31 | atom.config.unset(`${NAMESPACE}.alwaysWideChars`);
32 | }
33 | const alwaysNarrowChars = atom.config.get(`${NAMESPACE}.alwaysNarrowChars`);
34 | if (alwaysNarrowChars !== undefined) {
35 | atom.config.set(`${NAMESPACE}.narrowChars`, alwaysNarrowChars);
36 | atom.config.unset(`${NAMESPACE}.alwaysNarrowChars`);
37 | }
38 | }
39 |
40 | deactivate() {
41 | this.controller.destroy();
42 | }
43 |
44 | serialize() {
45 | }
46 | }
47 |
48 | module.exports = new MarkdownTableEditor();
49 |
--------------------------------------------------------------------------------
/lib/text-editor-interface.js:
--------------------------------------------------------------------------------
1 | import { Emitter } from "atom";
2 | import { Point, ITextEditor } from "@susisu/mte-kernel";
3 |
4 | export default class TextEditorInterface extends ITextEditor {
5 | constructor(textEditor, scopes) {
6 | super();
7 | this.textEditor = textEditor;
8 | this.textBuffer = textEditor.getBuffer();
9 | this.scopes = scopes;
10 | this.transaction = false;
11 | this.emitter = new Emitter();
12 | }
13 |
14 | getCursorPosition() {
15 | const _pos = this.textEditor.getCursorBufferPosition();
16 | return new Point(_pos.row, _pos.column);
17 | }
18 |
19 | setCursorPosition(pos) {
20 | this.textEditor.setCursorBufferPosition([pos.row, pos.column]);
21 | }
22 |
23 | setSelectionRange(range) {
24 | this.textEditor.setSelectedBufferRange([
25 | [range.start.row, range.start.column],
26 | [range.end.row, range.end.column]
27 | ]);
28 | }
29 |
30 | getLastRow() {
31 | return this.textBuffer.getLastRow();
32 | }
33 |
34 | acceptsTableEdit(row) {
35 | const sd = this.textEditor.scopeDescriptorForBufferPosition([row, 0]).getScopesArray();
36 | for (const scope of this.scopes) {
37 | if (sd.indexOf(scope) >= 0) {
38 | return true;
39 | }
40 | }
41 | return false;
42 | }
43 |
44 | getLine(row) {
45 | return this.textBuffer.lineForRow(row);
46 | }
47 |
48 | insertLine(row, line) {
49 | const lastRow = this.textBuffer.getLastRow();
50 | if (row > lastRow) {
51 | const le = this.textBuffer.lineEndingForRow(lastRow);
52 | this.textBuffer.append("\n" + line + le, { normalizeLineEndings: true });
53 | }
54 | else {
55 | this.textBuffer.insert([row, 0], line + "\n", { normalizeLineEndings: true });
56 | }
57 | }
58 |
59 | deleteLine(row) {
60 | this.textBuffer.deleteRow(row);
61 | }
62 |
63 | replaceLines(startRow, endRow, lines) {
64 | const le = this.textBuffer.lineEndingForRow(endRow - 1);
65 | this.textBuffer.setTextInRange(
66 | [[startRow, 0], [endRow, 0]],
67 | lines.join("\n") + le,
68 | { normalizeLineEndings: true }
69 | );
70 | }
71 |
72 | transact(func) {
73 | this.transaction = true;
74 | this.textBuffer.transact(() => { func(); });
75 | this.transaction = false;
76 | this.emitter.emit("did-finish-transaction");
77 | }
78 |
79 | onDidFinishTransaction(func) {
80 | return this.emitter.on("did-finish-transaction", func);
81 | }
82 |
83 | destroy() {
84 | this.emitter.dispose();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/menus/markdown-table-editor.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": [
3 | {
4 | "label": "Packages",
5 | "submenu": [
6 | {
7 | "label": "Markdown Table Editor",
8 | "submenu": [
9 | {
10 | "label": "Format",
11 | "command": "markdown-table-editor:format"
12 | },
13 | {
14 | "type": "separator"
15 | },
16 | {
17 | "label": "Align Left",
18 | "command": "markdown-table-editor:align-left"
19 | },
20 | {
21 | "label": "Align Right",
22 | "command": "markdown-table-editor:align-right"
23 | },
24 | {
25 | "label": "Align Center",
26 | "command": "markdown-table-editor:align-center"
27 | },
28 | {
29 | "label": "Align Default",
30 | "command": "markdown-table-editor:align-default"
31 | },
32 | {
33 | "type": "separator"
34 | },
35 | {
36 | "label": "Select Cell",
37 | "command": "markdown-table-editor:select-cell"
38 | },
39 | {
40 | "type": "separator"
41 | },
42 | {
43 | "label": "Insert Row",
44 | "command": "markdown-table-editor:insert-row"
45 | },
46 | {
47 | "label": "Delete Row",
48 | "command": "markdown-table-editor:delete-row"
49 | },
50 | {
51 | "label": "Insert Column",
52 | "command": "markdown-table-editor:insert-column"
53 | },
54 | {
55 | "label": "Delete Column",
56 | "command": "markdown-table-editor:delete-column"
57 | }
58 | ]
59 | }
60 | ]
61 | }
62 | ]
63 | }
64 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "markdown-table-editor",
3 | "version": "1.1.3",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@babel/code-frame": {
8 | "version": "7.0.0",
9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
10 | "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
11 | "dev": true,
12 | "requires": {
13 | "@babel/highlight": "^7.0.0"
14 | }
15 | },
16 | "@babel/highlight": {
17 | "version": "7.0.0",
18 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
19 | "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
20 | "dev": true,
21 | "requires": {
22 | "chalk": "^2.0.0",
23 | "esutils": "^2.0.2",
24 | "js-tokens": "^4.0.0"
25 | },
26 | "dependencies": {
27 | "ansi-styles": {
28 | "version": "3.2.1",
29 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
30 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
31 | "dev": true,
32 | "requires": {
33 | "color-convert": "^1.9.0"
34 | }
35 | },
36 | "chalk": {
37 | "version": "2.4.2",
38 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
39 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
40 | "dev": true,
41 | "requires": {
42 | "ansi-styles": "^3.2.1",
43 | "escape-string-regexp": "^1.0.5",
44 | "supports-color": "^5.3.0"
45 | }
46 | },
47 | "js-tokens": {
48 | "version": "4.0.0",
49 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
50 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
51 | "dev": true
52 | },
53 | "supports-color": {
54 | "version": "5.5.0",
55 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
56 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
57 | "dev": true,
58 | "requires": {
59 | "has-flag": "^3.0.0"
60 | }
61 | }
62 | }
63 | },
64 | "@susisu/mte-kernel": {
65 | "version": "2.1.1",
66 | "resolved": "https://registry.npmjs.org/@susisu/mte-kernel/-/mte-kernel-2.1.1.tgz",
67 | "integrity": "sha512-i2lucPD0BOUNIY6P0MGIUbJ/piV8iNzwB8QU1fdkRLls85rq8NJa75oeZVWo2PLrUWjN64+3oD85kZFsx3ovyA==",
68 | "requires": {
69 | "meaw": "^5.0.0"
70 | }
71 | },
72 | "acorn": {
73 | "version": "6.1.1",
74 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
75 | "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
76 | "dev": true
77 | },
78 | "acorn-jsx": {
79 | "version": "5.0.1",
80 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
81 | "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
82 | "dev": true
83 | },
84 | "ajv": {
85 | "version": "6.10.0",
86 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
87 | "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
88 | "dev": true,
89 | "requires": {
90 | "fast-deep-equal": "^2.0.1",
91 | "fast-json-stable-stringify": "^2.0.0",
92 | "json-schema-traverse": "^0.4.1",
93 | "uri-js": "^4.2.2"
94 | }
95 | },
96 | "ansi-escapes": {
97 | "version": "3.2.0",
98 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
99 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
100 | "dev": true
101 | },
102 | "ansi-regex": {
103 | "version": "2.1.1",
104 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
105 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
106 | },
107 | "ansi-styles": {
108 | "version": "2.2.1",
109 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
110 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
111 | },
112 | "argparse": {
113 | "version": "1.0.10",
114 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
115 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
116 | "dev": true,
117 | "requires": {
118 | "sprintf-js": "~1.0.2"
119 | }
120 | },
121 | "astral-regex": {
122 | "version": "1.0.0",
123 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
124 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
125 | "dev": true
126 | },
127 | "atom-babel6-transpiler": {
128 | "version": "1.2.0",
129 | "resolved": "https://registry.npmjs.org/atom-babel6-transpiler/-/atom-babel6-transpiler-1.2.0.tgz",
130 | "integrity": "sha512-lZucrjVyRtPAPPJxvICCEBsAC1qn48wUHaIlieriWCXTXLqtLC2PvkQU7vNvU2w1eZ7tw9m0lojZ8PbpVyWTvg==",
131 | "requires": {
132 | "babel-core": "6.x"
133 | }
134 | },
135 | "babel-code-frame": {
136 | "version": "6.26.0",
137 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
138 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
139 | "requires": {
140 | "chalk": "^1.1.3",
141 | "esutils": "^2.0.2",
142 | "js-tokens": "^3.0.2"
143 | }
144 | },
145 | "babel-core": {
146 | "version": "6.26.3",
147 | "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
148 | "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
149 | "requires": {
150 | "babel-code-frame": "^6.26.0",
151 | "babel-generator": "^6.26.0",
152 | "babel-helpers": "^6.24.1",
153 | "babel-messages": "^6.23.0",
154 | "babel-register": "^6.26.0",
155 | "babel-runtime": "^6.26.0",
156 | "babel-template": "^6.26.0",
157 | "babel-traverse": "^6.26.0",
158 | "babel-types": "^6.26.0",
159 | "babylon": "^6.18.0",
160 | "convert-source-map": "^1.5.1",
161 | "debug": "^2.6.9",
162 | "json5": "^0.5.1",
163 | "lodash": "^4.17.4",
164 | "minimatch": "^3.0.4",
165 | "path-is-absolute": "^1.0.1",
166 | "private": "^0.1.8",
167 | "slash": "^1.0.0",
168 | "source-map": "^0.5.7"
169 | }
170 | },
171 | "babel-generator": {
172 | "version": "6.26.1",
173 | "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
174 | "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
175 | "requires": {
176 | "babel-messages": "^6.23.0",
177 | "babel-runtime": "^6.26.0",
178 | "babel-types": "^6.26.0",
179 | "detect-indent": "^4.0.0",
180 | "jsesc": "^1.3.0",
181 | "lodash": "^4.17.4",
182 | "source-map": "^0.5.7",
183 | "trim-right": "^1.0.1"
184 | }
185 | },
186 | "babel-helpers": {
187 | "version": "6.24.1",
188 | "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
189 | "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
190 | "requires": {
191 | "babel-runtime": "^6.22.0",
192 | "babel-template": "^6.24.1"
193 | }
194 | },
195 | "babel-messages": {
196 | "version": "6.23.0",
197 | "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
198 | "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
199 | "requires": {
200 | "babel-runtime": "^6.22.0"
201 | }
202 | },
203 | "babel-plugin-transform-es2015-modules-commonjs": {
204 | "version": "6.26.2",
205 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
206 | "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
207 | "requires": {
208 | "babel-plugin-transform-strict-mode": "^6.24.1",
209 | "babel-runtime": "^6.26.0",
210 | "babel-template": "^6.26.0",
211 | "babel-types": "^6.26.0"
212 | }
213 | },
214 | "babel-plugin-transform-strict-mode": {
215 | "version": "6.24.1",
216 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
217 | "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
218 | "requires": {
219 | "babel-runtime": "^6.22.0",
220 | "babel-types": "^6.24.1"
221 | }
222 | },
223 | "babel-register": {
224 | "version": "6.26.0",
225 | "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
226 | "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
227 | "requires": {
228 | "babel-core": "^6.26.0",
229 | "babel-runtime": "^6.26.0",
230 | "core-js": "^2.5.0",
231 | "home-or-tmp": "^2.0.0",
232 | "lodash": "^4.17.4",
233 | "mkdirp": "^0.5.1",
234 | "source-map-support": "^0.4.15"
235 | }
236 | },
237 | "babel-runtime": {
238 | "version": "6.26.0",
239 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
240 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
241 | "requires": {
242 | "core-js": "^2.4.0",
243 | "regenerator-runtime": "^0.11.0"
244 | }
245 | },
246 | "babel-template": {
247 | "version": "6.26.0",
248 | "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
249 | "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
250 | "requires": {
251 | "babel-runtime": "^6.26.0",
252 | "babel-traverse": "^6.26.0",
253 | "babel-types": "^6.26.0",
254 | "babylon": "^6.18.0",
255 | "lodash": "^4.17.4"
256 | }
257 | },
258 | "babel-traverse": {
259 | "version": "6.26.0",
260 | "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
261 | "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
262 | "requires": {
263 | "babel-code-frame": "^6.26.0",
264 | "babel-messages": "^6.23.0",
265 | "babel-runtime": "^6.26.0",
266 | "babel-types": "^6.26.0",
267 | "babylon": "^6.18.0",
268 | "debug": "^2.6.8",
269 | "globals": "^9.18.0",
270 | "invariant": "^2.2.2",
271 | "lodash": "^4.17.4"
272 | }
273 | },
274 | "babel-types": {
275 | "version": "6.26.0",
276 | "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
277 | "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
278 | "requires": {
279 | "babel-runtime": "^6.26.0",
280 | "esutils": "^2.0.2",
281 | "lodash": "^4.17.4",
282 | "to-fast-properties": "^1.0.3"
283 | }
284 | },
285 | "babylon": {
286 | "version": "6.18.0",
287 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
288 | "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
289 | },
290 | "balanced-match": {
291 | "version": "1.0.0",
292 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
293 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
294 | },
295 | "brace-expansion": {
296 | "version": "1.1.11",
297 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
298 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
299 | "requires": {
300 | "balanced-match": "^1.0.0",
301 | "concat-map": "0.0.1"
302 | }
303 | },
304 | "callsites": {
305 | "version": "3.1.0",
306 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
307 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
308 | "dev": true
309 | },
310 | "chalk": {
311 | "version": "1.1.3",
312 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
313 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
314 | "requires": {
315 | "ansi-styles": "^2.2.1",
316 | "escape-string-regexp": "^1.0.2",
317 | "has-ansi": "^2.0.0",
318 | "strip-ansi": "^3.0.0",
319 | "supports-color": "^2.0.0"
320 | }
321 | },
322 | "chardet": {
323 | "version": "0.7.0",
324 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
325 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
326 | "dev": true
327 | },
328 | "cli-cursor": {
329 | "version": "2.1.0",
330 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
331 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
332 | "dev": true,
333 | "requires": {
334 | "restore-cursor": "^2.0.0"
335 | }
336 | },
337 | "cli-width": {
338 | "version": "2.2.0",
339 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
340 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
341 | "dev": true
342 | },
343 | "color-convert": {
344 | "version": "1.9.3",
345 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
346 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
347 | "dev": true,
348 | "requires": {
349 | "color-name": "1.1.3"
350 | }
351 | },
352 | "color-name": {
353 | "version": "1.1.3",
354 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
355 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
356 | "dev": true
357 | },
358 | "concat-map": {
359 | "version": "0.0.1",
360 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
361 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
362 | },
363 | "convert-source-map": {
364 | "version": "1.6.0",
365 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
366 | "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
367 | "requires": {
368 | "safe-buffer": "~5.1.1"
369 | }
370 | },
371 | "core-js": {
372 | "version": "2.5.6",
373 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz",
374 | "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ=="
375 | },
376 | "cross-spawn": {
377 | "version": "6.0.5",
378 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
379 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
380 | "dev": true,
381 | "requires": {
382 | "nice-try": "^1.0.4",
383 | "path-key": "^2.0.1",
384 | "semver": "^5.5.0",
385 | "shebang-command": "^1.2.0",
386 | "which": "^1.2.9"
387 | }
388 | },
389 | "debug": {
390 | "version": "2.6.9",
391 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
392 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
393 | "requires": {
394 | "ms": "2.0.0"
395 | }
396 | },
397 | "deep-is": {
398 | "version": "0.1.3",
399 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
400 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
401 | "dev": true
402 | },
403 | "detect-indent": {
404 | "version": "4.0.0",
405 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
406 | "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
407 | "requires": {
408 | "repeating": "^2.0.0"
409 | }
410 | },
411 | "doctrine": {
412 | "version": "3.0.0",
413 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
414 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
415 | "dev": true,
416 | "requires": {
417 | "esutils": "^2.0.2"
418 | }
419 | },
420 | "emoji-regex": {
421 | "version": "7.0.3",
422 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
423 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
424 | "dev": true
425 | },
426 | "escape-string-regexp": {
427 | "version": "1.0.5",
428 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
429 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
430 | },
431 | "eslint": {
432 | "version": "5.16.0",
433 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
434 | "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
435 | "dev": true,
436 | "requires": {
437 | "@babel/code-frame": "^7.0.0",
438 | "ajv": "^6.9.1",
439 | "chalk": "^2.1.0",
440 | "cross-spawn": "^6.0.5",
441 | "debug": "^4.0.1",
442 | "doctrine": "^3.0.0",
443 | "eslint-scope": "^4.0.3",
444 | "eslint-utils": "^1.3.1",
445 | "eslint-visitor-keys": "^1.0.0",
446 | "espree": "^5.0.1",
447 | "esquery": "^1.0.1",
448 | "esutils": "^2.0.2",
449 | "file-entry-cache": "^5.0.1",
450 | "functional-red-black-tree": "^1.0.1",
451 | "glob": "^7.1.2",
452 | "globals": "^11.7.0",
453 | "ignore": "^4.0.6",
454 | "import-fresh": "^3.0.0",
455 | "imurmurhash": "^0.1.4",
456 | "inquirer": "^6.2.2",
457 | "js-yaml": "^3.13.0",
458 | "json-stable-stringify-without-jsonify": "^1.0.1",
459 | "levn": "^0.3.0",
460 | "lodash": "^4.17.11",
461 | "minimatch": "^3.0.4",
462 | "mkdirp": "^0.5.1",
463 | "natural-compare": "^1.4.0",
464 | "optionator": "^0.8.2",
465 | "path-is-inside": "^1.0.2",
466 | "progress": "^2.0.0",
467 | "regexpp": "^2.0.1",
468 | "semver": "^5.5.1",
469 | "strip-ansi": "^4.0.0",
470 | "strip-json-comments": "^2.0.1",
471 | "table": "^5.2.3",
472 | "text-table": "^0.2.0"
473 | },
474 | "dependencies": {
475 | "ansi-regex": {
476 | "version": "3.0.0",
477 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
478 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
479 | "dev": true
480 | },
481 | "ansi-styles": {
482 | "version": "3.2.1",
483 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
484 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
485 | "dev": true,
486 | "requires": {
487 | "color-convert": "^1.9.0"
488 | }
489 | },
490 | "chalk": {
491 | "version": "2.4.2",
492 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
493 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
494 | "dev": true,
495 | "requires": {
496 | "ansi-styles": "^3.2.1",
497 | "escape-string-regexp": "^1.0.5",
498 | "supports-color": "^5.3.0"
499 | }
500 | },
501 | "debug": {
502 | "version": "4.1.1",
503 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
504 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
505 | "dev": true,
506 | "requires": {
507 | "ms": "^2.1.1"
508 | }
509 | },
510 | "globals": {
511 | "version": "11.12.0",
512 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
513 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
514 | "dev": true
515 | },
516 | "ms": {
517 | "version": "2.1.1",
518 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
519 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
520 | "dev": true
521 | },
522 | "strip-ansi": {
523 | "version": "4.0.0",
524 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
525 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
526 | "dev": true,
527 | "requires": {
528 | "ansi-regex": "^3.0.0"
529 | }
530 | },
531 | "supports-color": {
532 | "version": "5.5.0",
533 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
534 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
535 | "dev": true,
536 | "requires": {
537 | "has-flag": "^3.0.0"
538 | }
539 | }
540 | }
541 | },
542 | "eslint-scope": {
543 | "version": "4.0.3",
544 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
545 | "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
546 | "dev": true,
547 | "requires": {
548 | "esrecurse": "^4.1.0",
549 | "estraverse": "^4.1.1"
550 | }
551 | },
552 | "eslint-utils": {
553 | "version": "1.3.1",
554 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
555 | "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
556 | "dev": true
557 | },
558 | "eslint-visitor-keys": {
559 | "version": "1.0.0",
560 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
561 | "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
562 | "dev": true
563 | },
564 | "espree": {
565 | "version": "5.0.1",
566 | "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
567 | "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
568 | "dev": true,
569 | "requires": {
570 | "acorn": "^6.0.7",
571 | "acorn-jsx": "^5.0.0",
572 | "eslint-visitor-keys": "^1.0.0"
573 | }
574 | },
575 | "esprima": {
576 | "version": "4.0.1",
577 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
578 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
579 | "dev": true
580 | },
581 | "esquery": {
582 | "version": "1.0.1",
583 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
584 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
585 | "dev": true,
586 | "requires": {
587 | "estraverse": "^4.0.0"
588 | }
589 | },
590 | "esrecurse": {
591 | "version": "4.2.1",
592 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
593 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
594 | "dev": true,
595 | "requires": {
596 | "estraverse": "^4.1.0"
597 | }
598 | },
599 | "estraverse": {
600 | "version": "4.2.0",
601 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
602 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
603 | "dev": true
604 | },
605 | "esutils": {
606 | "version": "2.0.2",
607 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
608 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
609 | },
610 | "external-editor": {
611 | "version": "3.0.3",
612 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
613 | "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
614 | "dev": true,
615 | "requires": {
616 | "chardet": "^0.7.0",
617 | "iconv-lite": "^0.4.24",
618 | "tmp": "^0.0.33"
619 | }
620 | },
621 | "fast-deep-equal": {
622 | "version": "2.0.1",
623 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
624 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
625 | "dev": true
626 | },
627 | "fast-json-stable-stringify": {
628 | "version": "2.0.0",
629 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
630 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
631 | "dev": true
632 | },
633 | "fast-levenshtein": {
634 | "version": "2.0.6",
635 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
636 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
637 | "dev": true
638 | },
639 | "figures": {
640 | "version": "2.0.0",
641 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
642 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
643 | "dev": true,
644 | "requires": {
645 | "escape-string-regexp": "^1.0.5"
646 | }
647 | },
648 | "file-entry-cache": {
649 | "version": "5.0.1",
650 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
651 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
652 | "dev": true,
653 | "requires": {
654 | "flat-cache": "^2.0.1"
655 | }
656 | },
657 | "flat-cache": {
658 | "version": "2.0.1",
659 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
660 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
661 | "dev": true,
662 | "requires": {
663 | "flatted": "^2.0.0",
664 | "rimraf": "2.6.3",
665 | "write": "1.0.3"
666 | }
667 | },
668 | "flatted": {
669 | "version": "2.0.0",
670 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
671 | "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==",
672 | "dev": true
673 | },
674 | "fs.realpath": {
675 | "version": "1.0.0",
676 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
677 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
678 | "dev": true
679 | },
680 | "functional-red-black-tree": {
681 | "version": "1.0.1",
682 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
683 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
684 | "dev": true
685 | },
686 | "glob": {
687 | "version": "7.1.4",
688 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
689 | "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
690 | "dev": true,
691 | "requires": {
692 | "fs.realpath": "^1.0.0",
693 | "inflight": "^1.0.4",
694 | "inherits": "2",
695 | "minimatch": "^3.0.4",
696 | "once": "^1.3.0",
697 | "path-is-absolute": "^1.0.0"
698 | }
699 | },
700 | "globals": {
701 | "version": "9.18.0",
702 | "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
703 | "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
704 | },
705 | "has-ansi": {
706 | "version": "2.0.0",
707 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
708 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
709 | "requires": {
710 | "ansi-regex": "^2.0.0"
711 | }
712 | },
713 | "has-flag": {
714 | "version": "3.0.0",
715 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
716 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
717 | "dev": true
718 | },
719 | "home-or-tmp": {
720 | "version": "2.0.0",
721 | "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
722 | "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
723 | "requires": {
724 | "os-homedir": "^1.0.0",
725 | "os-tmpdir": "^1.0.1"
726 | }
727 | },
728 | "iconv-lite": {
729 | "version": "0.4.24",
730 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
731 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
732 | "dev": true,
733 | "requires": {
734 | "safer-buffer": ">= 2.1.2 < 3"
735 | }
736 | },
737 | "ignore": {
738 | "version": "4.0.6",
739 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
740 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
741 | "dev": true
742 | },
743 | "import-fresh": {
744 | "version": "3.0.0",
745 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz",
746 | "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==",
747 | "dev": true,
748 | "requires": {
749 | "parent-module": "^1.0.0",
750 | "resolve-from": "^4.0.0"
751 | }
752 | },
753 | "imurmurhash": {
754 | "version": "0.1.4",
755 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
756 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
757 | "dev": true
758 | },
759 | "inflight": {
760 | "version": "1.0.6",
761 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
762 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
763 | "dev": true,
764 | "requires": {
765 | "once": "^1.3.0",
766 | "wrappy": "1"
767 | }
768 | },
769 | "inherits": {
770 | "version": "2.0.3",
771 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
772 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
773 | "dev": true
774 | },
775 | "inquirer": {
776 | "version": "6.3.1",
777 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
778 | "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
779 | "dev": true,
780 | "requires": {
781 | "ansi-escapes": "^3.2.0",
782 | "chalk": "^2.4.2",
783 | "cli-cursor": "^2.1.0",
784 | "cli-width": "^2.0.0",
785 | "external-editor": "^3.0.3",
786 | "figures": "^2.0.0",
787 | "lodash": "^4.17.11",
788 | "mute-stream": "0.0.7",
789 | "run-async": "^2.2.0",
790 | "rxjs": "^6.4.0",
791 | "string-width": "^2.1.0",
792 | "strip-ansi": "^5.1.0",
793 | "through": "^2.3.6"
794 | },
795 | "dependencies": {
796 | "ansi-regex": {
797 | "version": "4.1.0",
798 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
799 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
800 | "dev": true
801 | },
802 | "ansi-styles": {
803 | "version": "3.2.1",
804 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
805 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
806 | "dev": true,
807 | "requires": {
808 | "color-convert": "^1.9.0"
809 | }
810 | },
811 | "chalk": {
812 | "version": "2.4.2",
813 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
814 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
815 | "dev": true,
816 | "requires": {
817 | "ansi-styles": "^3.2.1",
818 | "escape-string-regexp": "^1.0.5",
819 | "supports-color": "^5.3.0"
820 | }
821 | },
822 | "strip-ansi": {
823 | "version": "5.2.0",
824 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
825 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
826 | "dev": true,
827 | "requires": {
828 | "ansi-regex": "^4.1.0"
829 | }
830 | },
831 | "supports-color": {
832 | "version": "5.5.0",
833 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
834 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
835 | "dev": true,
836 | "requires": {
837 | "has-flag": "^3.0.0"
838 | }
839 | }
840 | }
841 | },
842 | "invariant": {
843 | "version": "2.2.4",
844 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
845 | "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
846 | "requires": {
847 | "loose-envify": "^1.0.0"
848 | }
849 | },
850 | "is-finite": {
851 | "version": "1.0.2",
852 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
853 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
854 | "requires": {
855 | "number-is-nan": "^1.0.0"
856 | }
857 | },
858 | "is-fullwidth-code-point": {
859 | "version": "2.0.0",
860 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
861 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
862 | "dev": true
863 | },
864 | "is-promise": {
865 | "version": "2.1.0",
866 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
867 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
868 | "dev": true
869 | },
870 | "isexe": {
871 | "version": "2.0.0",
872 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
873 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
874 | "dev": true
875 | },
876 | "js-tokens": {
877 | "version": "3.0.2",
878 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
879 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
880 | },
881 | "js-yaml": {
882 | "version": "3.13.1",
883 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
884 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
885 | "dev": true,
886 | "requires": {
887 | "argparse": "^1.0.7",
888 | "esprima": "^4.0.0"
889 | }
890 | },
891 | "jsesc": {
892 | "version": "1.3.0",
893 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
894 | "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
895 | },
896 | "json-schema-traverse": {
897 | "version": "0.4.1",
898 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
899 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
900 | "dev": true
901 | },
902 | "json-stable-stringify-without-jsonify": {
903 | "version": "1.0.1",
904 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
905 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
906 | "dev": true
907 | },
908 | "json5": {
909 | "version": "0.5.1",
910 | "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
911 | "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
912 | },
913 | "levn": {
914 | "version": "0.3.0",
915 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
916 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
917 | "dev": true,
918 | "requires": {
919 | "prelude-ls": "~1.1.2",
920 | "type-check": "~0.3.2"
921 | }
922 | },
923 | "lodash": {
924 | "version": "4.17.11",
925 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
926 | "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
927 | },
928 | "loose-envify": {
929 | "version": "1.3.1",
930 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
931 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
932 | "requires": {
933 | "js-tokens": "^3.0.0"
934 | }
935 | },
936 | "meaw": {
937 | "version": "5.0.0",
938 | "resolved": "https://registry.npmjs.org/meaw/-/meaw-5.0.0.tgz",
939 | "integrity": "sha512-yaK9Pnj6JrLcQGEqDUS0WGUEiaFg9Q215isi8mzcDVOjeGr5oS863hu+/ZS49g+azKPo5Wbpk3tgkP2+YOyZZw=="
940 | },
941 | "mimic-fn": {
942 | "version": "1.2.0",
943 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
944 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
945 | "dev": true
946 | },
947 | "minimatch": {
948 | "version": "3.0.4",
949 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
950 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
951 | "requires": {
952 | "brace-expansion": "^1.1.7"
953 | }
954 | },
955 | "minimist": {
956 | "version": "0.0.8",
957 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
958 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
959 | },
960 | "mkdirp": {
961 | "version": "0.5.1",
962 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
963 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
964 | "requires": {
965 | "minimist": "0.0.8"
966 | }
967 | },
968 | "ms": {
969 | "version": "2.0.0",
970 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
971 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
972 | },
973 | "mute-stream": {
974 | "version": "0.0.7",
975 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
976 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
977 | "dev": true
978 | },
979 | "natural-compare": {
980 | "version": "1.4.0",
981 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
982 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
983 | "dev": true
984 | },
985 | "nice-try": {
986 | "version": "1.0.5",
987 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
988 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
989 | "dev": true
990 | },
991 | "number-is-nan": {
992 | "version": "1.0.1",
993 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
994 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
995 | },
996 | "once": {
997 | "version": "1.4.0",
998 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
999 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1000 | "dev": true,
1001 | "requires": {
1002 | "wrappy": "1"
1003 | }
1004 | },
1005 | "onetime": {
1006 | "version": "2.0.1",
1007 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
1008 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
1009 | "dev": true,
1010 | "requires": {
1011 | "mimic-fn": "^1.0.0"
1012 | }
1013 | },
1014 | "optionator": {
1015 | "version": "0.8.2",
1016 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
1017 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
1018 | "dev": true,
1019 | "requires": {
1020 | "deep-is": "~0.1.3",
1021 | "fast-levenshtein": "~2.0.4",
1022 | "levn": "~0.3.0",
1023 | "prelude-ls": "~1.1.2",
1024 | "type-check": "~0.3.2",
1025 | "wordwrap": "~1.0.0"
1026 | }
1027 | },
1028 | "os-homedir": {
1029 | "version": "1.0.2",
1030 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
1031 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
1032 | },
1033 | "os-tmpdir": {
1034 | "version": "1.0.2",
1035 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
1036 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
1037 | },
1038 | "parent-module": {
1039 | "version": "1.0.1",
1040 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
1041 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
1042 | "dev": true,
1043 | "requires": {
1044 | "callsites": "^3.0.0"
1045 | }
1046 | },
1047 | "path-is-absolute": {
1048 | "version": "1.0.1",
1049 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1050 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
1051 | },
1052 | "path-is-inside": {
1053 | "version": "1.0.2",
1054 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
1055 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
1056 | "dev": true
1057 | },
1058 | "path-key": {
1059 | "version": "2.0.1",
1060 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
1061 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
1062 | "dev": true
1063 | },
1064 | "prelude-ls": {
1065 | "version": "1.1.2",
1066 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
1067 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
1068 | "dev": true
1069 | },
1070 | "private": {
1071 | "version": "0.1.8",
1072 | "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
1073 | "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
1074 | },
1075 | "progress": {
1076 | "version": "2.0.3",
1077 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
1078 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
1079 | "dev": true
1080 | },
1081 | "punycode": {
1082 | "version": "2.1.1",
1083 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
1084 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
1085 | "dev": true
1086 | },
1087 | "regenerator-runtime": {
1088 | "version": "0.11.1",
1089 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
1090 | "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
1091 | },
1092 | "regexpp": {
1093 | "version": "2.0.1",
1094 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
1095 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
1096 | "dev": true
1097 | },
1098 | "repeating": {
1099 | "version": "2.0.1",
1100 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
1101 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
1102 | "requires": {
1103 | "is-finite": "^1.0.0"
1104 | }
1105 | },
1106 | "resolve-from": {
1107 | "version": "4.0.0",
1108 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
1109 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
1110 | "dev": true
1111 | },
1112 | "restore-cursor": {
1113 | "version": "2.0.0",
1114 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
1115 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
1116 | "dev": true,
1117 | "requires": {
1118 | "onetime": "^2.0.0",
1119 | "signal-exit": "^3.0.2"
1120 | }
1121 | },
1122 | "rimraf": {
1123 | "version": "2.6.3",
1124 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
1125 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
1126 | "dev": true,
1127 | "requires": {
1128 | "glob": "^7.1.3"
1129 | }
1130 | },
1131 | "run-async": {
1132 | "version": "2.3.0",
1133 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
1134 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
1135 | "dev": true,
1136 | "requires": {
1137 | "is-promise": "^2.1.0"
1138 | }
1139 | },
1140 | "rxjs": {
1141 | "version": "6.5.1",
1142 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz",
1143 | "integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==",
1144 | "dev": true,
1145 | "requires": {
1146 | "tslib": "^1.9.0"
1147 | }
1148 | },
1149 | "safe-buffer": {
1150 | "version": "5.1.2",
1151 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1152 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
1153 | },
1154 | "safer-buffer": {
1155 | "version": "2.1.2",
1156 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1157 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1158 | "dev": true
1159 | },
1160 | "semver": {
1161 | "version": "5.7.0",
1162 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
1163 | "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
1164 | "dev": true
1165 | },
1166 | "shebang-command": {
1167 | "version": "1.2.0",
1168 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
1169 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
1170 | "dev": true,
1171 | "requires": {
1172 | "shebang-regex": "^1.0.0"
1173 | }
1174 | },
1175 | "shebang-regex": {
1176 | "version": "1.0.0",
1177 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
1178 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
1179 | "dev": true
1180 | },
1181 | "signal-exit": {
1182 | "version": "3.0.2",
1183 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
1184 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
1185 | "dev": true
1186 | },
1187 | "slash": {
1188 | "version": "1.0.0",
1189 | "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
1190 | "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU="
1191 | },
1192 | "slice-ansi": {
1193 | "version": "2.1.0",
1194 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
1195 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
1196 | "dev": true,
1197 | "requires": {
1198 | "ansi-styles": "^3.2.0",
1199 | "astral-regex": "^1.0.0",
1200 | "is-fullwidth-code-point": "^2.0.0"
1201 | },
1202 | "dependencies": {
1203 | "ansi-styles": {
1204 | "version": "3.2.1",
1205 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
1206 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
1207 | "dev": true,
1208 | "requires": {
1209 | "color-convert": "^1.9.0"
1210 | }
1211 | }
1212 | }
1213 | },
1214 | "source-map": {
1215 | "version": "0.5.7",
1216 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
1217 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
1218 | },
1219 | "source-map-support": {
1220 | "version": "0.4.18",
1221 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
1222 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
1223 | "requires": {
1224 | "source-map": "^0.5.6"
1225 | }
1226 | },
1227 | "sprintf-js": {
1228 | "version": "1.0.3",
1229 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1230 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
1231 | "dev": true
1232 | },
1233 | "string-width": {
1234 | "version": "2.1.1",
1235 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
1236 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
1237 | "dev": true,
1238 | "requires": {
1239 | "is-fullwidth-code-point": "^2.0.0",
1240 | "strip-ansi": "^4.0.0"
1241 | },
1242 | "dependencies": {
1243 | "ansi-regex": {
1244 | "version": "3.0.0",
1245 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
1246 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
1247 | "dev": true
1248 | },
1249 | "strip-ansi": {
1250 | "version": "4.0.0",
1251 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
1252 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
1253 | "dev": true,
1254 | "requires": {
1255 | "ansi-regex": "^3.0.0"
1256 | }
1257 | }
1258 | }
1259 | },
1260 | "strip-ansi": {
1261 | "version": "3.0.1",
1262 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
1263 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
1264 | "requires": {
1265 | "ansi-regex": "^2.0.0"
1266 | }
1267 | },
1268 | "strip-json-comments": {
1269 | "version": "2.0.1",
1270 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
1271 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
1272 | "dev": true
1273 | },
1274 | "supports-color": {
1275 | "version": "2.0.0",
1276 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1277 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
1278 | },
1279 | "table": {
1280 | "version": "5.2.3",
1281 | "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz",
1282 | "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==",
1283 | "dev": true,
1284 | "requires": {
1285 | "ajv": "^6.9.1",
1286 | "lodash": "^4.17.11",
1287 | "slice-ansi": "^2.1.0",
1288 | "string-width": "^3.0.0"
1289 | },
1290 | "dependencies": {
1291 | "ansi-regex": {
1292 | "version": "4.1.0",
1293 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
1294 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
1295 | "dev": true
1296 | },
1297 | "string-width": {
1298 | "version": "3.1.0",
1299 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
1300 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
1301 | "dev": true,
1302 | "requires": {
1303 | "emoji-regex": "^7.0.1",
1304 | "is-fullwidth-code-point": "^2.0.0",
1305 | "strip-ansi": "^5.1.0"
1306 | }
1307 | },
1308 | "strip-ansi": {
1309 | "version": "5.2.0",
1310 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
1311 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
1312 | "dev": true,
1313 | "requires": {
1314 | "ansi-regex": "^4.1.0"
1315 | }
1316 | }
1317 | }
1318 | },
1319 | "text-table": {
1320 | "version": "0.2.0",
1321 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
1322 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
1323 | "dev": true
1324 | },
1325 | "through": {
1326 | "version": "2.3.8",
1327 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1328 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
1329 | "dev": true
1330 | },
1331 | "tmp": {
1332 | "version": "0.0.33",
1333 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
1334 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
1335 | "dev": true,
1336 | "requires": {
1337 | "os-tmpdir": "~1.0.2"
1338 | }
1339 | },
1340 | "to-fast-properties": {
1341 | "version": "1.0.3",
1342 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
1343 | "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
1344 | },
1345 | "trim-right": {
1346 | "version": "1.0.1",
1347 | "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
1348 | "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
1349 | },
1350 | "tslib": {
1351 | "version": "1.9.3",
1352 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
1353 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
1354 | "dev": true
1355 | },
1356 | "type-check": {
1357 | "version": "0.3.2",
1358 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
1359 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
1360 | "dev": true,
1361 | "requires": {
1362 | "prelude-ls": "~1.1.2"
1363 | }
1364 | },
1365 | "uri-js": {
1366 | "version": "4.2.2",
1367 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
1368 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
1369 | "dev": true,
1370 | "requires": {
1371 | "punycode": "^2.1.0"
1372 | }
1373 | },
1374 | "which": {
1375 | "version": "1.3.1",
1376 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1377 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1378 | "dev": true,
1379 | "requires": {
1380 | "isexe": "^2.0.0"
1381 | }
1382 | },
1383 | "wordwrap": {
1384 | "version": "1.0.0",
1385 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1386 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
1387 | "dev": true
1388 | },
1389 | "wrappy": {
1390 | "version": "1.0.2",
1391 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1392 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1393 | "dev": true
1394 | },
1395 | "write": {
1396 | "version": "1.0.3",
1397 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
1398 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
1399 | "dev": true,
1400 | "requires": {
1401 | "mkdirp": "^0.5.1"
1402 | }
1403 | }
1404 | }
1405 | }
1406 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "markdown-table-editor",
3 | "main": "./lib/markdown-table-editor.js",
4 | "version": "1.1.3",
5 | "description": "Markdown table editor/formatter",
6 | "scripts": {
7 | "lint": "eslint lib spec",
8 | "fix": "eslint lib spec --fix"
9 | },
10 | "keywords": [
11 | "markdown",
12 | "table"
13 | ],
14 | "activationCommands": {},
15 | "repository": "https://github.com/susisu/atom-markdown-table-editor",
16 | "license": "MIT",
17 | "engines": {
18 | "atom": ">=1.22.0 <2.0.0"
19 | },
20 | "devDependencies": {
21 | "eslint": "^5.16.0"
22 | },
23 | "dependencies": {
24 | "@susisu/mte-kernel": "^2.1.1",
25 | "atom-babel6-transpiler": "^1.2.0",
26 | "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2"
27 | },
28 | "atomTranspilers": [
29 | {
30 | "glob": "{lib,spec}/*.js",
31 | "transpiler": "atom-babel6-transpiler",
32 | "options": {
33 | "babel": {
34 | "plugins": [
35 | "transform-es2015-modules-commonjs"
36 | ],
37 | "sourceMaps": "inline",
38 | "babelrc": false
39 | }
40 | }
41 | }
42 | ],
43 | "configSchema": {
44 | "formatOnSave": {
45 | "order": 1,
46 | "title": "Format on Save",
47 | "type": "boolean",
48 | "default": false,
49 | "description": "Formats all tables on save."
50 | },
51 | "scopes": {
52 | "order": 2,
53 | "type": "array",
54 | "items": {
55 | "type": "string"
56 | },
57 | "default": [
58 | "table.gfm",
59 | "table.storage.md"
60 | ],
61 | "description": "List of scopes in which the table editor is enabled."
62 | },
63 | "leftMarginChars": {
64 | "order": 3,
65 | "title": "Left Margin Characters",
66 | "type": "string",
67 | "default": "",
68 | "description": "String of additional left margin characters."
69 | },
70 | "formatType": {
71 | "order": 4,
72 | "type": "string",
73 | "default": "normal",
74 | "enum": [
75 | {
76 | "value": "normal",
77 | "description": "Normal - Cells in a column have the equal width"
78 | },
79 | {
80 | "value": "weak",
81 | "description": "Weak - Cells can have different widths"
82 | }
83 | ]
84 | },
85 | "defaultAlignment": {
86 | "order": 5,
87 | "type": "string",
88 | "default": "left",
89 | "enum": [
90 | {
91 | "value": "left",
92 | "description": "Left"
93 | },
94 | {
95 | "value": "right",
96 | "description": "Right"
97 | },
98 | {
99 | "value": "center",
100 | "description": "Center"
101 | }
102 | ]
103 | },
104 | "headerAlignment": {
105 | "order": 6,
106 | "type": "string",
107 | "default": "follow",
108 | "enum": [
109 | {
110 | "value": "follow",
111 | "description": "Follow column alignment"
112 | },
113 | {
114 | "value": "left",
115 | "description": "Left"
116 | },
117 | {
118 | "value": "right",
119 | "description": "Right"
120 | },
121 | {
122 | "value": "center",
123 | "description": "Center"
124 | }
125 | ]
126 | },
127 | "minDelimiterWidth": {
128 | "order": 7,
129 | "title": "Minimum Width of Delimiters",
130 | "type": "integer",
131 | "default": 3,
132 | "minimum": 1
133 | },
134 | "ambiguousAsWide": {
135 | "order": 8,
136 | "title": "Treat East Asian Ambiguous Characters as Wide",
137 | "type": "boolean",
138 | "default": false
139 | },
140 | "wideChars": {
141 | "order": 9,
142 | "title": "Wide Characters",
143 | "type": "string",
144 | "default": "",
145 | "description": "String of characters that should be treated as wide."
146 | },
147 | "narrowChars": {
148 | "order": 10,
149 | "title": "Narrow Characters",
150 | "type": "string",
151 | "default": "",
152 | "description": "String of characters that should be treated as narrow."
153 | },
154 | "normalize": {
155 | "order": 11,
156 | "title": "Unicode Normalization",
157 | "type": "boolean",
158 | "default": true,
159 | "description": "Computes cell widths based on normalized contents (NFC)."
160 | },
161 | "smartCursor": {
162 | "order": 12,
163 | "type": "boolean",
164 | "default": true,
165 | "description": "Remembers the column where the cursor will return back on \"Next Row\" command."
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/spec/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "es6": true,
4 | "node": true,
5 | "browser": true,
6 | "jasmine": true
7 | },
8 | "globals": {
9 | "atom": true,
10 | "waitsForPromise": true
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/spec/markdown-table-editor-spec.js:
--------------------------------------------------------------------------------
1 | import { Point } from "atom";
2 | import { FormatType, DefaultAlignment, HeaderAlignment } from "@susisu/mte-kernel";
3 |
4 | const NAMESPACE = "markdown-table-editor";
5 |
6 | function prepareEditor(name, scope, text) {
7 | return atom.workspace.open(name)
8 | .then(editor => {
9 | const grammar = atom.grammars.grammarForScopeName(scope);
10 | expect(grammar).not.toBe(undefined);
11 | editor.setGrammar(grammar);
12 | editor.setText(text);
13 | return editor;
14 | });
15 | }
16 |
17 | describe("markdown-table-editor", () => {
18 | beforeEach(() => {
19 | waitsForPromise(() => atom.packages.activatePackage("language-gfm"));
20 | waitsForPromise(() => atom.packages.activatePackage("markdown-table-editor"));
21 | });
22 |
23 | describe("activation", () => {
24 | it("should be activated if the current scope is specified in the config", () => {
25 | atom.config.set(`${NAMESPACE}.scopes`, ["source.gfm", "text.md"]);
26 | const text =
27 | "\n"
28 | + "| A | B |\n"
29 | + " | --- | ----- |\n"
30 | + " | C | D | \n";
31 | waitsForPromise(() =>
32 | prepareEditor("test.md", "source.gfm", text).then(editor => {
33 | const elem = editor.getElement();
34 | editor.setCursorBufferPosition(new Point(0, 0));
35 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
36 | editor.setCursorBufferPosition(new Point(1, 0));
37 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(true);
38 | editor.setCursorBufferPosition(new Point(2, 1));
39 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(true);
40 | editor.setCursorBufferPosition(new Point(3, 2));
41 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(true);
42 | editor.setCursorBufferPosition(new Point(4, 0));
43 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
44 | })
45 | );
46 | });
47 |
48 | it("should not be activated if the current scope is not specified in the config", () => {
49 | atom.config.set(`${NAMESPACE}.scopes`, ["text.md"]);
50 | const text =
51 | "\n"
52 | + "| A | B |\n"
53 | + " | --- | ----- |\n"
54 | + " | C | D | \n";
55 | waitsForPromise(() =>
56 | prepareEditor("test.md", "source.gfm", text).then(editor => {
57 | const elem = editor.getElement();
58 | editor.setCursorBufferPosition(new Point(0, 0));
59 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
60 | editor.setCursorBufferPosition(new Point(1, 0));
61 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
62 | editor.setCursorBufferPosition(new Point(2, 1));
63 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
64 | editor.setCursorBufferPosition(new Point(3, 2));
65 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
66 | editor.setCursorBufferPosition(new Point(4, 0));
67 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
68 | })
69 | );
70 | });
71 |
72 | it("should not be activated if there are multiple cursors", () => {
73 | atom.config.set(`${NAMESPACE}.scopes`, ["source.gfm", "text.md"]);
74 | const text =
75 | "\n"
76 | + "| A | B |\n"
77 | + " | --- | ----- |\n"
78 | + " | C | D | \n";
79 | waitsForPromise(() =>
80 | prepareEditor("test.md", "source.gfm", text).then(editor => {
81 | const elem = editor.getElement();
82 | const cursor = editor.getLastCursor();
83 | cursor.setBufferPosition(new Point(1, 0));
84 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(true);
85 | editor.addCursorAtBufferPosition(new Point(2, 1));
86 | expect(elem.classList.contains("markdown-table-editor-active")).toBe(false);
87 | })
88 | );
89 | });
90 | });
91 |
92 | describe("commands", () => {
93 | beforeEach(() => {
94 | atom.config.set(`${NAMESPACE}.formatOnSave`, false);
95 | atom.config.set(`${NAMESPACE}.scopes`, ["source.gfm", "text.md"]);
96 | atom.config.set(`${NAMESPACE}.leftMarginChars`, "");
97 | atom.config.set(`${NAMESPACE}.formatType`, FormatType.NORMAL);
98 | atom.config.set(`${NAMESPACE}.defaultAlignment`, DefaultAlignment.LEFT);
99 | atom.config.set(`${NAMESPACE}.headerAlignment`, HeaderAlignment.FOLLOW);
100 | atom.config.set(`${NAMESPACE}.minDelimiterWidth`, 3);
101 | atom.config.set(`${NAMESPACE}.ambiguousAsWide`, false);
102 | atom.config.set(`${NAMESPACE}.wideChars`, "");
103 | atom.config.set(`${NAMESPACE}.narrowChars`, "");
104 | atom.config.set(`${NAMESPACE}.normalize`, true);
105 | atom.config.set(`${NAMESPACE}.smartCursor`, false);
106 | });
107 |
108 | describe("toggle-format-on-save", () => {
109 | it("should toggle \"Format On Save\" config", () => {
110 | waitsForPromise(() =>
111 | prepareEditor("test.md", "source.gfm", "").then(editor => {
112 | editor.setCursorBufferPosition(new Point(0, 0));
113 | expect(atom.config.get(`${NAMESPACE}.formatOnSave`)).toBe(false);
114 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:toggle-format-on-save`);
115 | expect(atom.config.get(`${NAMESPACE}.formatOnSave`)).toBe(true);
116 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:toggle-format-on-save`);
117 | expect(atom.config.get(`${NAMESPACE}.formatOnSave`)).toBe(false);
118 | })
119 | );
120 | });
121 | });
122 |
123 | describe("switch-format-type", () => {
124 | it("should switch \"Format Type\" config", () => {
125 | waitsForPromise(() =>
126 | prepareEditor("test.md", "source.gfm", "").then(editor => {
127 | editor.setCursorBufferPosition(new Point(0, 0));
128 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.NORMAL);
129 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:switch-format-type`);
130 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.WEAK);
131 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:switch-format-type`);
132 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.NORMAL);
133 | })
134 | );
135 | });
136 | });
137 |
138 | describe("set-format-type-normal", () => {
139 | it("should set \"Format Type\" to \"Normal\"", () => {
140 | waitsForPromise(() =>
141 | prepareEditor("test.md", "source.gfm", "").then(editor => {
142 | editor.setCursorBufferPosition(new Point(0, 0));
143 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.NORMAL);
144 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:set-format-type-normal`);
145 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.NORMAL);
146 | atom.config.set(`${NAMESPACE}.formatType`, FormatType.WEAK);
147 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:set-format-type-normal`);
148 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.NORMAL);
149 | })
150 | );
151 | });
152 | });
153 |
154 | describe("set-format-type-weak", () => {
155 | it("should set \"Format Type\" to \"Weak\"", () => {
156 | waitsForPromise(() =>
157 | prepareEditor("test.md", "source.gfm", "").then(editor => {
158 | editor.setCursorBufferPosition(new Point(0, 0));
159 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.NORMAL);
160 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:set-format-type-weak`);
161 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.WEAK);
162 | atom.config.set(`${NAMESPACE}.formatType`, FormatType.WEAK);
163 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:set-format-type-weak`);
164 | expect(atom.config.get(`${NAMESPACE}.formatType`)).toBe(FormatType.WEAK);
165 | })
166 | );
167 | });
168 | });
169 |
170 | describe("format", () => {
171 | it("should format the table", () => {
172 | const text =
173 | "| A | B |\n"
174 | + " | --- | ----- |\n"
175 | + " | C | D | \n";
176 | waitsForPromise(() =>
177 | prepareEditor("test.md", "source.gfm", text).then(editor => {
178 | editor.setCursorBufferPosition(new Point(0, 2));
179 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:format`);
180 | const formatted =
181 | "| A | B |\n"
182 | + "| --- | --- |\n"
183 | + "| C | D |\n";
184 | expect(editor.getText()).toBe(formatted);
185 | const pos = editor.getCursorBufferPosition();
186 | expect(pos.row).toBe(0);
187 | expect(pos.column).toBe(2);
188 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
189 | })
190 | );
191 | });
192 | });
193 |
194 | describe("format-all", () => {
195 | it("should format all the tables", () => {
196 | const text =
197 | "| A | B |\n"
198 | + " | --- | ----- |\n"
199 | + " | C | D | \n"
200 | + "\n"
201 | + "| E | F |\n"
202 | + " | --- | ----- |\n"
203 | + " | G | H | \n";
204 | waitsForPromise(() =>
205 | prepareEditor("test.md", "source.gfm", text).then(editor => {
206 | editor.setCursorBufferPosition(new Point(0, 2));
207 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:format-all`);
208 | const formatted =
209 | "| A | B |\n"
210 | + "| --- | --- |\n"
211 | + "| C | D |\n"
212 | + "\n"
213 | + "| E | F |\n"
214 | + "| --- | --- |\n"
215 | + "| G | H |\n";
216 | expect(editor.getText()).toBe(formatted);
217 | const pos = editor.getCursorBufferPosition();
218 | expect(pos.row).toBe(0);
219 | expect(pos.column).toBe(2);
220 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
221 | })
222 | );
223 | });
224 | });
225 |
226 | describe("escape", () => {
227 | it("should escape from the table", () => {
228 | const text =
229 | "| A | B |\n"
230 | + " | --- | ----- |\n"
231 | + " | C | D | \n";
232 | waitsForPromise(() =>
233 | prepareEditor("test.md", "source.gfm", text).then(editor => {
234 | editor.setCursorBufferPosition(new Point(0, 2));
235 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:escape`);
236 | const formatted =
237 | "| A | B |\n"
238 | + "| --- | --- |\n"
239 | + "| C | D |\n";
240 | expect(editor.getText()).toBe(formatted);
241 | const pos = editor.getCursorBufferPosition();
242 | expect(pos.row).toBe(3);
243 | expect(pos.column).toBe(0);
244 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
245 | })
246 | );
247 | });
248 | });
249 |
250 | describe("align-left", () => {
251 | it("should align-left the column", () => {
252 | const text =
253 | "| A | B |\n"
254 | + " | --- | ----- |\n"
255 | + " | C | D | \n";
256 | waitsForPromise(() =>
257 | prepareEditor("test.md", "source.gfm", text).then(editor => {
258 | editor.setCursorBufferPosition(new Point(0, 2));
259 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:align-left`);
260 | const formatted =
261 | "| A | B |\n"
262 | + "|:--- | --- |\n"
263 | + "| C | D |\n";
264 | expect(editor.getText()).toBe(formatted);
265 | const pos = editor.getCursorBufferPosition();
266 | expect(pos.row).toBe(0);
267 | expect(pos.column).toBe(2);
268 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
269 | })
270 | );
271 | });
272 | });
273 |
274 | describe("align-right", () => {
275 | it("should align-right the column", () => {
276 | const text =
277 | "| A | B |\n"
278 | + " | --- | ----- |\n"
279 | + " | C | D | \n";
280 | waitsForPromise(() =>
281 | prepareEditor("test.md", "source.gfm", text).then(editor => {
282 | editor.setCursorBufferPosition(new Point(0, 2));
283 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:align-right`);
284 | const formatted =
285 | "| A | B |\n"
286 | + "| ---:| --- |\n"
287 | + "| C | D |\n";
288 | expect(editor.getText()).toBe(formatted);
289 | const pos = editor.getCursorBufferPosition();
290 | expect(pos.row).toBe(0);
291 | expect(pos.column).toBe(4);
292 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
293 | })
294 | );
295 | });
296 | });
297 |
298 | describe("align-center", () => {
299 | it("should align-center the column", () => {
300 | const text =
301 | "| A | B |\n"
302 | + " | --- | ----- |\n"
303 | + " | C | D | \n";
304 | waitsForPromise(() =>
305 | prepareEditor("test.md", "source.gfm", text).then(editor => {
306 | editor.setCursorBufferPosition(new Point(0, 2));
307 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:align-center`);
308 | const formatted =
309 | "| A | B |\n"
310 | + "|:---:| --- |\n"
311 | + "| C | D |\n";
312 | expect(editor.getText()).toBe(formatted);
313 | const pos = editor.getCursorBufferPosition();
314 | expect(pos.row).toBe(0);
315 | expect(pos.column).toBe(3);
316 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
317 | })
318 | );
319 | });
320 | });
321 |
322 | describe("align-none", () => {
323 | it("should unset alignment of the column", () => {
324 | const text =
325 | "| A | B |\n"
326 | + " |:--- | ----- |\n"
327 | + " | C | D | \n";
328 | waitsForPromise(() =>
329 | prepareEditor("test.md", "source.gfm", text).then(editor => {
330 | editor.setCursorBufferPosition(new Point(0, 2));
331 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:align-none`);
332 | const formatted =
333 | "| A | B |\n"
334 | + "| --- | --- |\n"
335 | + "| C | D |\n";
336 | expect(editor.getText()).toBe(formatted);
337 | const pos = editor.getCursorBufferPosition();
338 | expect(pos.row).toBe(0);
339 | expect(pos.column).toBe(2);
340 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
341 | })
342 | );
343 | });
344 | });
345 |
346 | describe("align-default", () => {
347 | it("should unset alignment of the column", () => {
348 | const text =
349 | "| A | B |\n"
350 | + " |:--- | ----- |\n"
351 | + " | C | D | \n";
352 | waitsForPromise(() =>
353 | prepareEditor("test.md", "source.gfm", text).then(editor => {
354 | editor.setCursorBufferPosition(new Point(0, 2));
355 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:align-default`);
356 | const formatted =
357 | "| A | B |\n"
358 | + "| --- | --- |\n"
359 | + "| C | D |\n";
360 | expect(editor.getText()).toBe(formatted);
361 | const pos = editor.getCursorBufferPosition();
362 | expect(pos.row).toBe(0);
363 | expect(pos.column).toBe(2);
364 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
365 | })
366 | );
367 | });
368 | });
369 |
370 | describe("select-cell", () => {
371 | it("should select the focused cell content", () => {
372 | const text =
373 | "| A | B |\n"
374 | + " | --- | ----- |\n"
375 | + " | C | D | \n";
376 | waitsForPromise(() =>
377 | prepareEditor("test.md", "source.gfm", text).then(editor => {
378 | editor.setCursorBufferPosition(new Point(0, 2));
379 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:select-cell`);
380 | const formatted =
381 | "| A | B |\n"
382 | + "| --- | --- |\n"
383 | + "| C | D |\n";
384 | expect(editor.getText()).toBe(formatted);
385 | const range = editor.getSelectedBufferRange();
386 | expect(range.start.row).toBe(0);
387 | expect(range.start.column).toBe(2);
388 | expect(range.end.row).toBe(0);
389 | expect(range.end.column).toBe(3);
390 | })
391 | );
392 | });
393 | });
394 |
395 | describe("move-left", () => {
396 | it("should move the focus left", () => {
397 | const text =
398 | "| A | B |\n"
399 | + " | --- | ----- |\n"
400 | + " | C | D | \n";
401 | waitsForPromise(() =>
402 | prepareEditor("test.md", "source.gfm", text).then(editor => {
403 | editor.setCursorBufferPosition(new Point(0, 6));
404 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-left`);
405 | const formatted =
406 | "| A | B |\n"
407 | + "| --- | --- |\n"
408 | + "| C | D |\n";
409 | expect(editor.getText()).toBe(formatted);
410 | const range = editor.getSelectedBufferRange();
411 | expect(range.start.row).toBe(0);
412 | expect(range.start.column).toBe(2);
413 | expect(range.end.row).toBe(0);
414 | expect(range.end.column).toBe(3);
415 | })
416 | );
417 | });
418 | });
419 |
420 | describe("move-right", () => {
421 | it("should move the focus right", () => {
422 | const text =
423 | "| A | B |\n"
424 | + " | --- | ----- |\n"
425 | + " | C | D | \n";
426 | waitsForPromise(() =>
427 | prepareEditor("test.md", "source.gfm", text).then(editor => {
428 | editor.setCursorBufferPosition(new Point(0, 2));
429 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-right`);
430 | const formatted =
431 | "| A | B |\n"
432 | + "| --- | --- |\n"
433 | + "| C | D |\n";
434 | expect(editor.getText()).toBe(formatted);
435 | const range = editor.getSelectedBufferRange();
436 | expect(range.start.row).toBe(0);
437 | expect(range.start.column).toBe(8);
438 | expect(range.end.row).toBe(0);
439 | expect(range.end.column).toBe(9);
440 | })
441 | );
442 | });
443 | });
444 |
445 | describe("move-up", () => {
446 | it("should move the focus up", () => {
447 | const text =
448 | "| A | B |\n"
449 | + " | --- | ----- |\n"
450 | + " | C | D | \n";
451 | waitsForPromise(() =>
452 | prepareEditor("test.md", "source.gfm", text).then(editor => {
453 | editor.setCursorBufferPosition(new Point(2, 4));
454 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-up`);
455 | const formatted =
456 | "| A | B |\n"
457 | + "| --- | --- |\n"
458 | + "| C | D |\n";
459 | expect(editor.getText()).toBe(formatted);
460 | const range = editor.getSelectedBufferRange();
461 | expect(range.start.row).toBe(0);
462 | expect(range.start.column).toBe(2);
463 | expect(range.end.row).toBe(0);
464 | expect(range.end.column).toBe(3);
465 | })
466 | );
467 | });
468 | });
469 |
470 | describe("move-down", () => {
471 | it("should move the focus down", () => {
472 | const text =
473 | "| A | B |\n"
474 | + " | --- | ----- |\n"
475 | + " | C | D | \n";
476 | waitsForPromise(() =>
477 | prepareEditor("test.md", "source.gfm", text).then(editor => {
478 | editor.setCursorBufferPosition(new Point(0, 2));
479 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-down`);
480 | const formatted =
481 | "| A | B |\n"
482 | + "| --- | --- |\n"
483 | + "| C | D |\n";
484 | expect(editor.getText()).toBe(formatted);
485 | const range = editor.getSelectedBufferRange();
486 | expect(range.start.row).toBe(2);
487 | expect(range.start.column).toBe(2);
488 | expect(range.end.row).toBe(2);
489 | expect(range.end.column).toBe(3);
490 | })
491 | );
492 | });
493 | });
494 |
495 | describe("next-cell", () => {
496 | it("should move the focus to the next cell", () => {
497 | const text =
498 | "| A | B |\n"
499 | + " | --- | ----- |\n"
500 | + " | C | D | \n";
501 | waitsForPromise(() =>
502 | prepareEditor("test.md", "source.gfm", text).then(editor => {
503 | editor.setCursorBufferPosition(new Point(0, 6));
504 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:next-cell`);
505 | const formatted =
506 | "| A | B | \n"
507 | + "| --- | --- |\n"
508 | + "| C | D |\n";
509 | expect(editor.getText()).toBe(formatted);
510 | const pos = editor.getCursorBufferPosition();
511 | expect(pos.row).toBe(0);
512 | expect(pos.column).toBe(14);
513 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
514 | })
515 | );
516 | });
517 | });
518 |
519 | describe("previous-cell", () => {
520 | it("should move the focus to the previous cell", () => {
521 | const text =
522 | "| A | B |\n"
523 | + " | --- | ----- |\n"
524 | + " | C | D | \n";
525 | waitsForPromise(() =>
526 | prepareEditor("test.md", "source.gfm", text).then(editor => {
527 | editor.setCursorBufferPosition(new Point(0, 6));
528 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:previous-cell`);
529 | const formatted =
530 | "| A | B |\n"
531 | + "| --- | --- |\n"
532 | + "| C | D |\n";
533 | expect(editor.getText()).toBe(formatted);
534 | const range = editor.getSelectedBufferRange();
535 | expect(range.start.row).toBe(0);
536 | expect(range.start.column).toBe(2);
537 | expect(range.end.row).toBe(0);
538 | expect(range.end.column).toBe(3);
539 | })
540 | );
541 | });
542 | });
543 |
544 | describe("next-row", () => {
545 | it("should move the focus to the next row", () => {
546 | const text =
547 | "| A | B |\n"
548 | + " | --- | ----- |\n"
549 | + " | C | D | \n";
550 | waitsForPromise(() =>
551 | prepareEditor("test.md", "source.gfm", text).then(editor => {
552 | editor.setCursorBufferPosition(new Point(2, 4));
553 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:next-row`);
554 | const formatted =
555 | "| A | B |\n"
556 | + "| --- | --- |\n"
557 | + "| C | D |\n"
558 | + "| | |\n";
559 | expect(editor.getText()).toBe(formatted);
560 | const pos = editor.getCursorBufferPosition();
561 | expect(pos.row).toBe(3);
562 | expect(pos.column).toBe(2);
563 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
564 | })
565 | );
566 | });
567 | });
568 |
569 | describe("insert-row", () => {
570 | it("should insert an empty row", () => {
571 | const text =
572 | "| A | B |\n"
573 | + " | --- | ----- |\n"
574 | + " | C | D | \n";
575 | waitsForPromise(() =>
576 | prepareEditor("test.md", "source.gfm", text).then(editor => {
577 | editor.setCursorBufferPosition(new Point(2, 4));
578 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:insert-row`);
579 | const formatted =
580 | "| A | B |\n"
581 | + "| --- | --- |\n"
582 | + "| | |\n"
583 | + "| C | D |\n";
584 | expect(editor.getText()).toBe(formatted);
585 | const pos = editor.getCursorBufferPosition();
586 | expect(pos.row).toBe(2);
587 | expect(pos.column).toBe(2);
588 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
589 | })
590 | );
591 | });
592 | });
593 |
594 | describe("delete-row", () => {
595 | it("should delete a row", () => {
596 | const text =
597 | "| A | B |\n"
598 | + " | --- | ----- |\n"
599 | + " | C | D | \n"
600 | + "| E | F |\n";
601 | waitsForPromise(() =>
602 | prepareEditor("test.md", "source.gfm", text).then(editor => {
603 | editor.setCursorBufferPosition(new Point(2, 4));
604 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:delete-row`);
605 | const formatted =
606 | "| A | B |\n"
607 | + "| --- | --- |\n"
608 | + "| E | F |\n";
609 | expect(editor.getText()).toBe(formatted);
610 | const range = editor.getSelectedBufferRange();
611 | expect(range.start.row).toBe(2);
612 | expect(range.start.column).toBe(2);
613 | expect(range.end.row).toBe(2);
614 | expect(range.end.column).toBe(3);
615 | })
616 | );
617 | });
618 | });
619 |
620 | describe("move-row-up", () => {
621 | it("should move the focused row up", () => {
622 | const text =
623 | "| A | B |\n"
624 | + " | --- | ----- |\n"
625 | + " | C | D | \n"
626 | + "| E | F |\n";
627 | waitsForPromise(() =>
628 | prepareEditor("test.md", "source.gfm", text).then(editor => {
629 | editor.setCursorBufferPosition(new Point(3, 2));
630 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-row-up`);
631 | const formatted =
632 | "| A | B |\n"
633 | + "| --- | --- |\n"
634 | + "| E | F |\n"
635 | + "| C | D |\n";
636 | expect(editor.getText()).toBe(formatted);
637 | const pos = editor.getCursorBufferPosition();
638 | expect(pos.row).toBe(2);
639 | expect(pos.column).toBe(2);
640 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
641 | })
642 | );
643 | });
644 | });
645 |
646 | describe("move-row-down", () => {
647 | it("should move the focused row down", () => {
648 | const text =
649 | "| A | B |\n"
650 | + " | --- | ----- |\n"
651 | + " | C | D | \n"
652 | + "| E | F |\n";
653 | waitsForPromise(() =>
654 | prepareEditor("test.md", "source.gfm", text).then(editor => {
655 | editor.setCursorBufferPosition(new Point(2, 4));
656 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-row-down`);
657 | const formatted =
658 | "| A | B |\n"
659 | + "| --- | --- |\n"
660 | + "| E | F |\n"
661 | + "| C | D |\n";
662 | expect(editor.getText()).toBe(formatted);
663 | const pos = editor.getCursorBufferPosition();
664 | expect(pos.row).toBe(3);
665 | expect(pos.column).toBe(2);
666 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
667 | })
668 | );
669 | });
670 | });
671 |
672 | describe("insert-column", () => {
673 | it("should insert an empty column", () => {
674 | const text =
675 | "| A | B |\n"
676 | + " | --- | ----- |\n"
677 | + " | C | D | \n";
678 | waitsForPromise(() =>
679 | prepareEditor("test.md", "source.gfm", text).then(editor => {
680 | editor.setCursorBufferPosition(new Point(0, 2));
681 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:insert-column`);
682 | const formatted =
683 | "| | A | B |\n"
684 | + "| --- | --- | --- |\n"
685 | + "| | C | D |\n";
686 | expect(editor.getText()).toBe(formatted);
687 | const pos = editor.getCursorBufferPosition();
688 | expect(pos.row).toBe(0);
689 | expect(pos.column).toBe(2);
690 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
691 | })
692 | );
693 | });
694 | });
695 |
696 | describe("delete-column", () => {
697 | it("should delete a column", () => {
698 | const text =
699 | "| A | B |\n"
700 | + " | --- | ----- |\n"
701 | + " | C | D | \n";
702 | waitsForPromise(() =>
703 | prepareEditor("test.md", "source.gfm", text).then(editor => {
704 | editor.setCursorBufferPosition(new Point(0, 2));
705 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:delete-column`);
706 | const formatted =
707 | "| B |\n"
708 | + "| --- |\n"
709 | + "| D |\n";
710 | expect(editor.getText()).toBe(formatted);
711 | const range = editor.getSelectedBufferRange();
712 | expect(range.start.row).toBe(0);
713 | expect(range.start.column).toBe(2);
714 | expect(range.end.row).toBe(0);
715 | expect(range.end.column).toBe(3);
716 | })
717 | );
718 | });
719 | });
720 |
721 | describe("move-column-left", () => {
722 | it("should move the focused column left", () => {
723 | const text =
724 | "| A | B |\n"
725 | + " | --- | ----- |\n"
726 | + " | C | D | \n";
727 | waitsForPromise(() =>
728 | prepareEditor("test.md", "source.gfm", text).then(editor => {
729 | editor.setCursorBufferPosition(new Point(0, 6));
730 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-column-left`);
731 | const formatted =
732 | "| B | A |\n"
733 | + "| --- | --- |\n"
734 | + "| D | C |\n";
735 | expect(editor.getText()).toBe(formatted);
736 | const pos = editor.getCursorBufferPosition();
737 | expect(pos.row).toBe(0);
738 | expect(pos.column).toBe(2);
739 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
740 | })
741 | );
742 | });
743 | });
744 |
745 | describe("move-column-right", () => {
746 | it("should move the focused column right", () => {
747 | const text =
748 | "| A | B |\n"
749 | + " | --- | ----- |\n"
750 | + " | C | D | \n";
751 | waitsForPromise(() =>
752 | prepareEditor("test.md", "source.gfm", text).then(editor => {
753 | editor.setCursorBufferPosition(new Point(0, 2));
754 | atom.commands.dispatch(editor.getElement(), `${NAMESPACE}:move-column-right`);
755 | const formatted =
756 | "| B | A |\n"
757 | + "| --- | --- |\n"
758 | + "| D | C |\n";
759 | expect(editor.getText()).toBe(formatted);
760 | const pos = editor.getCursorBufferPosition();
761 | expect(pos.row).toBe(0);
762 | expect(pos.column).toBe(8);
763 | expect(editor.getSelectedBufferRange().isEmpty()).toBe(true);
764 | })
765 | );
766 | });
767 | });
768 | });
769 | });
770 |
--------------------------------------------------------------------------------
/spec/text-editor-interface-spec.js:
--------------------------------------------------------------------------------
1 | import { Point, Range } from "@susisu/mte-kernel";
2 |
3 | import TextEditorInterface from "../lib/text-editor-interface.js";
4 |
5 | function prepareEditor(name, scope, text) {
6 | return atom.workspace.open(name)
7 | .then(editor => {
8 | const grammar = atom.grammars.grammarForScopeName(scope);
9 | expect(grammar).not.toBe(undefined);
10 | editor.setGrammar(grammar);
11 | editor.setText(text);
12 | return editor;
13 | });
14 | }
15 |
16 | describe("TextEditorInterface", () => {
17 | beforeEach(() => {
18 | waitsForPromise(() => atom.packages.activatePackage("language-gfm"));
19 | waitsForPromise(() => atom.packages.activatePackage("language-text"));
20 | waitsForPromise(() => atom.packages.activatePackage("markdown-table-editor"));
21 | });
22 |
23 | describe("getCursorPosition()", () => {
24 | it("should get the current cursor position as a point object", () => {
25 | const lines = [
26 | "",
27 | "| A | B |",
28 | " | --- | ----- |",
29 | " | C | D | ",
30 | ""
31 | ];
32 | waitsForPromise(() =>
33 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
34 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
35 | editor.setCursorBufferPosition([0, 0]);
36 | {
37 | const pos = intf.getCursorPosition();
38 | expect(pos).toBeInstanceOf(Point);
39 | expect(pos.row).toBe(0);
40 | expect(pos.column).toBe(0);
41 | }
42 | editor.setCursorBufferPosition([1, 2]);
43 | {
44 | const pos = intf.getCursorPosition();
45 | expect(pos).toBeInstanceOf(Point);
46 | expect(pos.row).toBe(1);
47 | expect(pos.column).toBe(2);
48 | }
49 | editor.setCursorBufferPosition([4, 0]);
50 | {
51 | const pos = intf.getCursorPosition();
52 | expect(pos).toBeInstanceOf(Point);
53 | expect(pos.row).toBe(4);
54 | expect(pos.column).toBe(0);
55 | }
56 | })
57 | );
58 | });
59 | });
60 |
61 | describe("setCursorPosition(pos)", () => {
62 | it("should set the cursor position by a point object", () => {
63 | const lines = [
64 | "",
65 | "| A | B |",
66 | " | --- | ----- |",
67 | " | C | D | ",
68 | ""
69 | ];
70 | waitsForPromise(() =>
71 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
72 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
73 | intf.setCursorPosition(new Point(0, 0));
74 | {
75 | const pos = editor.getCursorBufferPosition();
76 | expect(pos.row).toBe(0);
77 | expect(pos.column).toBe(0);
78 | }
79 | intf.setCursorPosition(new Point(1, 2));
80 | {
81 | const pos = editor.getCursorBufferPosition();
82 | expect(pos.row).toBe(1);
83 | expect(pos.column).toBe(2);
84 | }
85 | intf.setCursorPosition(new Point(4, 0));
86 | {
87 | const pos = editor.getCursorBufferPosition();
88 | expect(pos.row).toBe(4);
89 | expect(pos.column).toBe(0);
90 | }
91 | })
92 | );
93 | });
94 | });
95 |
96 | describe("setSelectionRange(range)", () => {
97 | it("should set a selection by a range object", () => {
98 | const lines = [
99 | "",
100 | "| A | B |",
101 | " | --- | ----- |",
102 | " | C | D | ",
103 | ""
104 | ];
105 | waitsForPromise(() =>
106 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
107 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
108 | intf.setSelectionRange(new Range(new Point(0, 0), new Point(1, 2)));
109 | {
110 | const range = editor.getSelectedBufferRange();
111 | expect(range.start.row).toBe(0);
112 | expect(range.start.column).toBe(0);
113 | expect(range.end.row).toBe(1);
114 | expect(range.end.column).toBe(2);
115 | }
116 | intf.setSelectionRange(new Range(new Point(1, 2), new Point(1, 3)));
117 | {
118 | const range = editor.getSelectedBufferRange();
119 | expect(range.start.row).toBe(1);
120 | expect(range.start.column).toBe(2);
121 | expect(range.end.row).toBe(1);
122 | expect(range.end.column).toBe(3);
123 | }
124 | intf.setSelectionRange(new Range(new Point(1, 2), new Point(4, 0)));
125 | {
126 | const range = editor.getSelectedBufferRange();
127 | expect(range.start.row).toBe(1);
128 | expect(range.start.column).toBe(2);
129 | expect(range.end.row).toBe(4);
130 | expect(range.end.column).toBe(0);
131 | }
132 | })
133 | );
134 | });
135 | });
136 |
137 | describe("getLastRow()", () => {
138 | it("should get the last row index of the text editor", () => {
139 | const lines = [
140 | "",
141 | "| A | B |",
142 | " | --- | ----- |",
143 | " | C | D | ",
144 | ""
145 | ];
146 | waitsForPromise(() =>
147 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
148 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
149 | expect(intf.getLastRow()).toBe(4);
150 | })
151 | );
152 | });
153 | });
154 |
155 | describe("acceptsTableEdit(row)", () => {
156 | it("should return true if the specified row is in a table", () => {
157 | {
158 | const lines = [
159 | "",
160 | "| A | B |",
161 | "| --- | ----- |",
162 | "| C | D | ",
163 | "",
164 | "```",
165 | "| E | F |",
166 | "| --- | ----- |",
167 | "| G | H | ",
168 | "```",
169 | ""
170 | ];
171 | waitsForPromise(() =>
172 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
173 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
174 | expect(intf.acceptsTableEdit(0)).toBe(false);
175 | expect(intf.acceptsTableEdit(1)).toBe(true);
176 | expect(intf.acceptsTableEdit(2)).toBe(true);
177 | expect(intf.acceptsTableEdit(3)).toBe(true);
178 | expect(intf.acceptsTableEdit(4)).toBe(false);
179 | expect(intf.acceptsTableEdit(5)).toBe(false);
180 | expect(intf.acceptsTableEdit(6)).toBe(false);
181 | expect(intf.acceptsTableEdit(7)).toBe(false);
182 | expect(intf.acceptsTableEdit(8)).toBe(false);
183 | expect(intf.acceptsTableEdit(9)).toBe(false);
184 | expect(intf.acceptsTableEdit(10)).toBe(false);
185 | })
186 | );
187 | }
188 | {
189 | const lines = [
190 | "",
191 | "| A | B |",
192 | " | --- | ----- |",
193 | " | C | D | ",
194 | "",
195 | "```",
196 | "| E | F |",
197 | " | --- | ----- |",
198 | " | G | H | ",
199 | "```",
200 | ""
201 | ];
202 | waitsForPromise(() =>
203 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
204 | const intf = new TextEditorInterface(editor, ["source.gfm"]);
205 | expect(intf.acceptsTableEdit(0)).toBe(true);
206 | expect(intf.acceptsTableEdit(1)).toBe(true);
207 | expect(intf.acceptsTableEdit(2)).toBe(true);
208 | expect(intf.acceptsTableEdit(3)).toBe(true);
209 | expect(intf.acceptsTableEdit(4)).toBe(true);
210 | expect(intf.acceptsTableEdit(5)).toBe(true);
211 | expect(intf.acceptsTableEdit(6)).toBe(true);
212 | expect(intf.acceptsTableEdit(7)).toBe(true);
213 | expect(intf.acceptsTableEdit(8)).toBe(true);
214 | expect(intf.acceptsTableEdit(9)).toBe(true);
215 | expect(intf.acceptsTableEdit(10)).toBe(true);
216 | })
217 | );
218 | }
219 | {
220 | const lines = [
221 | "",
222 | "| A | B |",
223 | "| --- | ----- |",
224 | "| C | D | ",
225 | ""
226 | ];
227 | waitsForPromise(() =>
228 | prepareEditor("test.txt", "text.plain", lines.join("\n")).then(editor => {
229 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
230 | expect(intf.acceptsTableEdit(0)).toBe(false);
231 | expect(intf.acceptsTableEdit(1)).toBe(false);
232 | expect(intf.acceptsTableEdit(2)).toBe(false);
233 | expect(intf.acceptsTableEdit(3)).toBe(false);
234 | expect(intf.acceptsTableEdit(4)).toBe(false);
235 | })
236 | );
237 | }
238 | });
239 | });
240 |
241 | describe("getLine(row)", () => {
242 | it("should get a line without line ending at the specified row", () => {
243 | const lines = [
244 | "",
245 | "| A | B |",
246 | " | --- | ----- |",
247 | " | C | D | ",
248 | ""
249 | ];
250 | waitsForPromise(() =>
251 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
252 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
253 | expect(intf.getLine(0)).toBe("");
254 | expect(intf.getLine(1)).toBe("| A | B |");
255 | expect(intf.getLine(2)).toBe(" | --- | ----- |");
256 | expect(intf.getLine(3)).toBe(" | C | D | ");
257 | expect(intf.getLine(4)).toBe("");
258 | })
259 | );
260 | });
261 | });
262 |
263 | describe("insertLine(row, line)", () => {
264 | it("should insert a new line at the specified row", () => {
265 | const lines = [
266 | "",
267 | "| A | B |",
268 | " | --- | ----- |",
269 | " | C | D | ",
270 | ""
271 | ];
272 | waitsForPromise(() =>
273 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
274 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
275 | intf.insertLine(0, "foo");
276 | {
277 | const text = editor.getText();
278 | expect(text).toBe(
279 | "foo\n"
280 | + "\n"
281 | + "| A | B |\n"
282 | + " | --- | ----- |\n"
283 | + " | C | D | \n"
284 | );
285 | }
286 | intf.insertLine(4, "| E | F |");
287 | {
288 | const text = editor.getText();
289 | expect(text).toBe(
290 | "foo\n"
291 | + "\n"
292 | + "| A | B |\n"
293 | + " | --- | ----- |\n"
294 | + "| E | F |\n"
295 | + " | C | D | \n"
296 | );
297 | }
298 | intf.insertLine(7, "bar");
299 | {
300 | const text = editor.getText();
301 | expect(text).toBe(
302 | "foo\n"
303 | + "\n"
304 | + "| A | B |\n"
305 | + " | --- | ----- |\n"
306 | + "| E | F |\n"
307 | + " | C | D | \n"
308 | + "\n"
309 | + "bar"
310 | );
311 | }
312 | })
313 | );
314 | });
315 | });
316 |
317 | describe("deleteLine(row)", () => {
318 | it("should delete a line at the specified row", () => {
319 | const lines = [
320 | "foo",
321 | "",
322 | "| A | B |",
323 | " | --- | ----- |",
324 | " | C | D | ",
325 | "| E | F |",
326 | "| G | H |",
327 | ""
328 | ];
329 | waitsForPromise(() =>
330 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
331 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
332 | intf.deleteLine(0);
333 | {
334 | const text = editor.getText();
335 | expect(text).toBe(
336 | "\n"
337 | + "| A | B |\n"
338 | + " | --- | ----- |\n"
339 | + " | C | D | \n"
340 | + "| E | F |\n"
341 | + "| G | H |\n"
342 | );
343 | }
344 | intf.deleteLine(3);
345 | {
346 | const text = editor.getText();
347 | expect(text).toBe(
348 | "\n"
349 | + "| A | B |\n"
350 | + " | --- | ----- |\n"
351 | + "| E | F |\n"
352 | + "| G | H |\n"
353 | );
354 | }
355 | intf.deleteLine(5);
356 | {
357 | const text = editor.getText();
358 | expect(text).toBe(
359 | "\n"
360 | + "| A | B |\n"
361 | + " | --- | ----- |\n"
362 | + "| E | F |\n"
363 | + "| G | H |"
364 | );
365 | }
366 | })
367 | );
368 | });
369 | });
370 |
371 | describe("replaceLines(startRow, endRow, lines)", () => {
372 | it("should replace lines in the specified row range", () => {
373 | const lines = [
374 | "",
375 | "| A | B |",
376 | " | --- | ----- |",
377 | " | C | D | ",
378 | ""
379 | ];
380 | waitsForPromise(() =>
381 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
382 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
383 | {
384 | const newLines = [
385 | "| A | B |",
386 | "| --- | --- |",
387 | "| C | D |",
388 | "| E | F |"
389 | ];
390 | intf.replaceLines(1, 4, newLines);
391 | const text = editor.getText();
392 | expect(text).toBe(
393 | "\n"
394 | + "| A | B |\n"
395 | + "| --- | --- |\n"
396 | + "| C | D |\n"
397 | + "| E | F |\n"
398 | );
399 | }
400 | {
401 | const newLines = [
402 | "| G | H |",
403 | "| --- | --- |",
404 | "| I | J |"
405 | ];
406 | intf.replaceLines(1, 6, newLines);
407 | const text = editor.getText();
408 | expect(text).toBe(
409 | "\n"
410 | + "| G | H |\n"
411 | + "| --- | --- |\n"
412 | + "| I | J |"
413 | );
414 | }
415 | })
416 | );
417 | });
418 | });
419 |
420 | describe("transact(func)", () => {
421 | it("should batch operations as a single step", () => {
422 | const lines = [
423 | "",
424 | "| A | B |",
425 | " | --- | ----- |",
426 | " | C | D | ",
427 | ""
428 | ];
429 | waitsForPromise(() =>
430 | prepareEditor("test.md", "source.gfm", lines.join("\n")).then(editor => {
431 | const intf = new TextEditorInterface(editor, ["table.gfm"]);
432 | intf.transact(() => {
433 | intf.deleteLine(3);
434 | intf.insertLine(3, "| E | F |");
435 | });
436 | {
437 | const text = editor.getText();
438 | expect(text).toBe(
439 | "\n"
440 | + "| A | B |\n"
441 | + " | --- | ----- |\n"
442 | + "| E | F |\n"
443 | );
444 | }
445 | editor.undo();
446 | {
447 | const text = editor.getText();
448 | expect(text).toBe(
449 | "\n"
450 | + "| A | B |\n"
451 | + " | --- | ----- |\n"
452 | + " | C | D | \n"
453 | );
454 | }
455 | })
456 | );
457 | });
458 | });
459 | });
460 |
--------------------------------------------------------------------------------