├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── keymaps
└── sequential-number.cson
├── lib
├── sequential-number-view.coffee
├── sequential-number.coffee
└── template-helper.coffee
├── menus
└── sequential-number.cson
├── package.json
└── spec
└── sequential-number-spec.coffee
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | npm-debug.log
3 | node_modules
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 |
3 | notifications:
4 | email:
5 | on_success: never
6 | on_failure: change
7 |
8 | script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh'
9 |
10 | branches:
11 | only:
12 | - master
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.5.0 - Support alphabet radix
2 |
3 | * Support alphabet radix option. Idea from @flyinbutrs, thanks.
4 |
5 |
6 | ## 0.4.0 - Add `radix` option
7 |
8 | * Add radix option. Very nice idea from @flyinbutrs, thanks.
9 |
10 |
11 | ## 0.3.0 - Replacement of selected text
12 |
13 | * When inserting a sequence number, modified to replace the text that was selected.
14 |
15 |
16 | ## 0.2.0 - Add real time simulator
17 |
18 | * Added a real-time simulator in the input panel.
19 | * Fixed a bug of the calculated value.
20 | * Changed the UI of the input panel.
21 | * Modified to count the position of the cursor from the top.
22 |
23 |
24 | ## 0.1.0 - First Release
25 |
26 | * Every feature added
27 |
28 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 tsuyoshiwada
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | sequential-number
2 | =================
3 |
4 | [](https://travis-ci.org/tsuyoshiwada/sequential-number)
5 | [](https://raw.githubusercontent.com/tsuyoshiwada/sequential-number/master/LICENSE)
6 |
7 | An Atom package, to inputs sequential numbers across multiple cursors.
8 |
9 | 
10 |
11 |
12 |
13 | ## INSTALLATION
14 |
15 | Search in the `sequential-number` from Install Packages.
16 | Please restart as necessary After the installation.
17 |
18 |
19 | ## USAGE
20 |
21 |
22 | ### Keymaps (Linux, Win, OS X)
23 |
24 | ctrl + alt + 0 => Open the input panel !
25 |
26 |
27 | ### Syntax Rules
28 |
29 | ```
30 | : :
31 | ```
32 |
33 | | Key | Default | Definition |
34 | | :------------------------------------ | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------- |
35 | | **start** | `""` | It specifies the number that you start typing an integer. |
36 | | **operator** (optinal) | `+` | It specifies the generation rules of consecutive numbers in the `+` or `-`. The sign of the increment(`++`) and decrement(`--`) also available. |
37 | | **step** (optinal) | `1` | It specifies the integer to be added or subtracted. |
38 | | **digit** (optinal) | `0` | It specifies of the number of digits in the integer. |
39 | | **radix** (optinal) | `10` | It specifies an integer between 2 and 36 that represents radix. Or increment alphabetically by `"a"` or `"A"`. |
40 |
41 |
42 |
43 | #### Examples
44 |
45 | The following sample the cursor length is `5`.
46 |
47 | ```
48 | # Input
49 | => 1
50 | => 1++
51 | => 1 + 1
52 |
53 | # Output
54 | 1
55 | 2
56 | 3
57 | 4
58 | 5
59 | ```
60 |
61 | ```
62 | # Input
63 | => 10 + 2
64 |
65 | # Output
66 | 10
67 | 12
68 | 14
69 | 16
70 | 18
71 | ```
72 |
73 | ```
74 | # Input
75 | => 0027 + 3
76 |
77 | # Output
78 | 0027
79 | 0030
80 | 0033
81 | 0036
82 | 0039
83 | ```
84 |
85 | ```
86 | # Input
87 | => 010 - 1
88 | => 010--
89 |
90 | # Output
91 | 010
92 | 009
93 | 008
94 | 007
95 | 006
96 | ```
97 |
98 | ```
99 | # Input
100 | => -10 + 1 : 2
101 |
102 | # Output
103 | -10
104 | -09
105 | -08
106 | -07
107 | -06
108 | ```
109 |
110 | ```
111 | # Input
112 | => 0ff + 14 : 3 : 16
113 |
114 | # Output
115 | 0ff
116 | 10d
117 | 11b
118 | 129
119 | 137
120 | ```
121 |
122 | ```
123 | # Input
124 | => 0AB239 + 2 : 6 : 16
125 |
126 | # Output
127 | 0AB239
128 | 0AB23B
129 | 0AB23D
130 | 0AB23F
131 | 0AB241
132 | ```
133 |
134 | ```
135 | # Input
136 | => a + 2 : 1 : a
137 |
138 | # Output
139 | a
140 | c
141 | e
142 | g
143 | i
144 | ```
145 |
146 | ```
147 | # Input
148 | => c + 20 : 3 : a
149 |
150 | # Output
151 | aac
152 | aaw
153 | aaq
154 | abk
155 | ace
156 | ```
157 |
158 |
159 |
160 | ## CUSTOMIZING KEYMAP
161 |
162 | May be overriden for your favorite keystroke in your `keymap.cson`.
163 |
164 | ```coffeescript
165 | # Open input panel
166 | 'atom-text-editor':
167 | 'ctrl-alt-0': 'sequential-number:open'
168 |
169 | # Close input panel
170 | '.sequential-number atom-text-editor':
171 | 'escape': 'sequential-number:close'
172 | 'ctrl-c': 'sequential-number:close'
173 | ```
174 |
175 |
176 |
177 | ## AUTHOR
178 | [tsuyoshiwada](https://github.com/tsuyoshiwada)
179 |
180 |
181 |
182 | ---
183 |
184 |
185 |
186 | Bugs, feature requests and comments are more than welcome in the [issues](https://github.com/tsuyoshiwada/sequential-number/issues)
187 |
--------------------------------------------------------------------------------
/keymaps/sequential-number.cson:
--------------------------------------------------------------------------------
1 | 'atom-text-editor':
2 | 'ctrl-alt-0': 'sequential-number:open'
3 |
4 | '.sequential-number atom-text-editor':
5 | 'escape': 'sequential-number:close'
6 | 'ctrl-c': 'sequential-number:close'
--------------------------------------------------------------------------------
/lib/sequential-number-view.coffee:
--------------------------------------------------------------------------------
1 | {Emitter} = require "event-kit"
2 | TemplateHelper = require "./template-helper"
3 |
4 | ENABLE_ENTER_KEY_DELAY = 250
5 |
6 | modalTemplate = """
7 |
16 | """
17 |
18 | module.exports =
19 | class SequentialNumberView extends Emitter
20 | constructor: (serializedState) ->
21 | super()
22 |
23 | @modalTemplate = TemplateHelper.create modalTemplate
24 |
25 | @element = document.createElement "div"
26 | @element.classList.add "sequential-number"
27 | @element.appendChild TemplateHelper.render @modalTemplate
28 |
29 | @textEditor = @element.querySelector "atom-text-editor"
30 | @simulator = @element.querySelector "#sequential-number-simulator"
31 | @modalPanel = atom.workspace.addModalPanel item: @element, visible: false
32 |
33 | @handleBlur = @handleBlur.bind this
34 | @handleKeyup = @handleKeyup.bind this
35 |
36 | serialize: ->
37 |
38 | bindEvents: ->
39 | @isEnableEnterKey = false
40 | @isEnableEnterKeyTimer = setTimeout =>
41 | @isEnableEnterKey = true
42 | , ENABLE_ENTER_KEY_DELAY
43 |
44 | @textEditor.addEventListener "blur", @handleBlur, false
45 | @textEditor.addEventListener "keyup", @handleKeyup, false
46 |
47 | unbindEvents: ->
48 | @isEnableEnterKey = false
49 | clearTimeout @isEnableEnterKeyTimer
50 | @isEnableEnterKeyTimer = null
51 |
52 | @textEditor.removeEventListener "blur", @handleBlur, false
53 | @textEditor.removeEventListener "keyup", @handleKeyup, false
54 |
55 | handleBlur: ->
56 | @emit "blur"
57 |
58 | handleKeyup: (e) ->
59 | text = @getText()
60 | if @isEnableEnterKey && e.keyCode == 13
61 | @emit "done", text
62 | else
63 | @emit "change", text
64 |
65 | isVisible: ->
66 | @modalPanel.isVisible()
67 |
68 | show: ->
69 | @modalPanel.show()
70 | @textEditor.focus()
71 | @bindEvents()
72 |
73 | hide: ->
74 | @unbindEvents()
75 | @modalPanel.hide()
76 | @setText ""
77 | @setSimulatorText ""
78 |
79 | destroy: ->
80 | @modalPanel.destroy()
81 | @modalPanel = null
82 | @element.remove()
83 | @element = null
84 |
85 | setText: (text) ->
86 | @textEditor.getModel().setText text
87 |
88 | getText: ->
89 | @textEditor.getModel().getText().trim()
90 |
91 | setSimulatorText: (text) ->
92 | @simulator.textContent = text
93 |
94 | getSimulatorText: ->
95 | @simulator.textContent
96 |
--------------------------------------------------------------------------------
/lib/sequential-number.coffee:
--------------------------------------------------------------------------------
1 | {CompositeDisposable, Range} = require "atom"
2 | SequentialNumberView = require "./sequential-number-view"
3 |
4 | SIMULATE_CURSOR_LENGTH = 3
5 |
6 | module.exports = SequentialNumber =
7 | activate: () ->
8 | @view = new SequentialNumberView
9 | @view.on "blur", => @close()
10 | @view.on "change", (value) => @simulate value
11 | @view.on "done", (value) => @exec value
12 |
13 | @previousFocused
14 |
15 | @subscriptions = new CompositeDisposable
16 | @subscriptions.add atom.commands.add "atom-workspace", "sequential-number:open": => @open()
17 | @subscriptions.add atom.commands.add "atom-workspace", "sequential-number:close": => @close()
18 |
19 | deactivate: ->
20 | @subscriptions.dispose()
21 | @view.destroy()
22 |
23 | serialize: ->
24 |
25 | open: ->
26 | if !@view.isVisible()
27 | @view.show()
28 |
29 | close: ->
30 | @view.hide()
31 | atom.views.getView(atom.workspace).focus()
32 |
33 | simulate: (value) ->
34 | result = @parseValue value
35 | text = ""
36 |
37 | if result != null
38 | simulateList = [0..SIMULATE_CURSOR_LENGTH - 1].map (index) =>
39 | @calculateValue index, result
40 | simulateList.push "..."
41 | text = simulateList.join ", "
42 |
43 | @view.setSimulatorText text
44 |
45 | exec: (value) ->
46 | editor = @getEditor()
47 | result = @parseValue value
48 |
49 | if result != null
50 | editor.transact( =>
51 | length = editor.cursors.length
52 | for index in [0...length]
53 | cursors = editor.cursors.slice()
54 | cursors = cursors.map (cursor) -> cursor.selection.getBufferRange()
55 | cursors = cursors.sort (a, b) -> a.start.row - b.start.row || a.start.column - b.start.column
56 | range = cursors[index]
57 | editor.setTextInBufferRange new Range(range.start, range.end), @calculateValue index, result
58 | )
59 |
60 | @close()
61 |
62 | getEditor: ->
63 | atom.workspace.getActivePane().activeItem
64 |
65 | parseValue: (input) ->
66 | matches = "#{input}".match /^([+\-]?[\da-zA-Z]+(?:\.\d+)?)\s*([+\-]|(?:\+\+|\-\-))?\s*(\d+)?\s*(?:\:\s*(\d+))?\s*(?:\:\s*([\daA]+))?$/
67 | return null if matches == null
68 |
69 | radix = matches[5]
70 | radix = if radix != undefined then radix else 10
71 | radix = if /\d+/.test radix then parseInt radix, 10 else radix
72 | isAlphaRadix = /[aA]/.test radix
73 |
74 | start = matches[1]
75 | return null if isAlphaRadix and /\d+/.test(start)
76 |
77 | start = if isAlphaRadix then start else parseInt(start, radix)
78 |
79 | operator = matches[2] || "+"
80 | step = parseInt matches[3], 10
81 | step = if isNaN matches[3] then 1 else step
82 |
83 | _digit = parseInt matches[4], 10
84 | digit = if "#{start}" == matches[1] then 0 else matches[1].length
85 | digit = if /^[+\-]/.test matches[1] then Math.max(digit - 1, 0) else digit
86 | digit = if isNaN _digit then digit else _digit
87 |
88 | return {start, digit, operator, step, radix, input}
89 |
90 | calculateValue: (index, args) ->
91 | if /[aA]/.test args.radix
92 | return @calculateAlphaValue index, args
93 | else
94 | return @calculateNumberValue index, args
95 |
96 | calculateNumberValue: (index, {start, digit, operator, step, radix, input}) ->
97 | _start = parseInt start, 10
98 |
99 | switch operator
100 | when "++" then value = _start + index
101 | when "--" then value = _start - index
102 | when "+" then value = _start + (index * step)
103 | when "-" then value = _start - (index * step)
104 | else return ""
105 |
106 | if isNaN value
107 | return ""
108 |
109 | value = @zeroPadding value, digit, radix
110 | firstAlpha = input.match /([a-fA-F])/
111 |
112 | if firstAlpha
113 | value = value[if firstAlpha[1] == firstAlpha[1].toLowerCase() then "toLowerCase" else "toUpperCase"]()
114 |
115 | return value
116 |
117 | calculateAlphaValue: (index, {start, digit, operator, step, radix, input}) ->
118 | switch operator
119 | when "++" then count = (index - 1) + step
120 | when "--" then count = (index - 1) - step
121 | when "+" then count = index * step
122 | when "-" then count = index * step * -1
123 |
124 | value = @alphaSequence(start.toLowerCase(), count)
125 | value = @leftPadding(value, digit, "a")
126 |
127 | if /[A-Z]/.test(start) or /[A-Z]/.test(radix)
128 | value = value.toUpperCase()
129 |
130 | return value
131 |
132 | alphaSequence: (str, count) ->
133 | return str if count == 0
134 |
135 | alphabet = "abcdefghijklmnopqrstuvwxyz".split ""
136 | last = str.slice -1
137 | index = alphabet.indexOf last
138 | n = Math.floor((index + count) / alphabet.length)
139 | next = alphabet[(index + count) % alphabet.length]
140 |
141 | return "" if !next
142 |
143 | s = "#{str.slice(0, str.length - 1)}#{next}"
144 |
145 | if n > 0
146 | if s.length == 1 and index == alphabet.length - 1
147 | s = "a#{s}"
148 | else
149 | s = "#{@alphaSequence(s.slice(0, s.length - 1), n)}#{next}"
150 |
151 | return s
152 |
153 | leftPadding: (str, digit, padString) ->
154 | _digit = Math.max str.length, digit
155 | return (Array(_digit).join(padString) + str).slice(_digit * -1)
156 |
157 | zeroPadding: (number, digit = 0, radix = 10) ->
158 | num = number.toString radix
159 | numAbs = num.replace "-", ""
160 | positive = num.indexOf("-") < 0
161 | return (if positive then "" else "-") + @leftPadding(numAbs, digit, "0")
162 |
--------------------------------------------------------------------------------
/lib/template-helper.coffee:
--------------------------------------------------------------------------------
1 | # Reference:
2 | # https://github.com/atom/notifications/blob/master/lib/template-helper.coffee
3 |
4 | module.exports =
5 | create: (htmlString) ->
6 | template = document.createElement("template")
7 | template.innerHTML = htmlString
8 | document.body.appendChild(template)
9 | template
10 |
11 | render: (template) ->
12 | document.importNode(template.content, true)
--------------------------------------------------------------------------------
/menus/sequential-number.cson:
--------------------------------------------------------------------------------
1 | 'context-menu':
2 | 'atom-text-editor': [
3 | {
4 | 'label': 'Open Sequential Number'
5 | 'command': 'sequential-number:open'
6 | }
7 | ]
8 | 'menu': [
9 | {
10 | 'label': 'Packages'
11 | 'submenu': [
12 | 'label': 'Sequential Number'
13 | 'submenu': [
14 | {
15 | 'label': 'Open Sequential Number'
16 | 'command': 'sequential-number:open'
17 | }
18 | ]
19 | ]
20 | }
21 | ]
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sequential-number",
3 | "main": "./lib/sequential-number",
4 | "version": "0.5.0",
5 | "description": "Input sequential number in the across multiple cursors.",
6 | "keywords": [
7 | "serial number",
8 | "sequence number",
9 | "numbering",
10 | "text helper"
11 | ],
12 | "activationCommands": {
13 | "atom-workspace": "sequential-number:open"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/tsuyoshiwada/sequential-number"
18 | },
19 | "license": "MIT",
20 | "engines": {
21 | "atom": ">=1.0.0 <2.0.0"
22 | },
23 | "dependencies": {
24 | "event-kit": "^1.4.1"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/spec/sequential-number-spec.coffee:
--------------------------------------------------------------------------------
1 | {Range, Point} = require "atom"
2 | SequentialNumber = require "../lib/sequential-number"
3 |
4 |
5 | # Event trigger utility
6 | trigger = (el, event, type, data = {}) ->
7 | e = document.createEvent event
8 | e.initEvent type, true, true
9 | e = Object.assign e, data
10 | el.dispatchEvent e
11 |
12 |
13 | # setTimeout utility
14 | sleep = (msec) ->
15 | new Promise((resolve) ->
16 | setTimeout resolve, msec
17 | )
18 |
19 |
20 | # Package
21 | describe "SequentialNumber", ->
22 | [workspaceElement, pane, element, panel] = []
23 |
24 | beforeEach ->
25 | workspaceElement = atom.views.getView(atom.workspace)
26 | activationPromise = null
27 |
28 | jasmine.useRealClock()
29 | jasmine.attachToDOM(workspaceElement)
30 |
31 | waitsForPromise ->
32 | atom.workspace.open "test.txt"
33 |
34 | runs ->
35 | activationPromise = atom.packages.activatePackage "sequential-number"
36 | pane = atom.workspace.getActivePaneItem()
37 | pane.setText Array(5).join "\n"
38 | pane.setCursorBufferPosition [0, 0]
39 | atom.commands.dispatch workspaceElement, "sequential-number:open"
40 |
41 | waitsForPromise ->
42 | activationPromise
43 |
44 | runs ->
45 | element = workspaceElement.querySelector ".sequential-number"
46 | panel = atom.workspace.panelForItem(element)
47 |
48 | waitsForPromise ->
49 | sleep 250
50 |
51 | describe "when the sequential-number:open event is triggered", ->
52 | it "show the modal panel", ->
53 | expect(panel.isVisible()).toBe true
54 |
55 | it "hide the modal panel", ->
56 | atom.commands.dispatch element, "sequential-number:close"
57 | expect(panel.isVisible()).toBe false
58 |
59 | it "clears the previous editor text", ->
60 | model = panel.getItem().querySelector("atom-text-editor").getModel()
61 | model.setText "Sequential Number!!"
62 | expect(model.getText()).toBe "Sequential Number!!"
63 |
64 | atom.commands.dispatch element, "sequential-number:close"
65 | atom.commands.dispatch element, "sequential-number:open"
66 | expect(model.getText()).toBe ""
67 |
68 | describe "when the text is entered", ->
69 | [editor, simulator, model, previousText] = []
70 |
71 | beforeEach ->
72 | pane.addCursorAtScreenPosition [1, 0]
73 | pane.addCursorAtScreenPosition [2, 0]
74 | pane.addCursorAtScreenPosition [3, 0]
75 | pane.addCursorAtScreenPosition [4, 0]
76 | pane.addCursorAtScreenPosition [5, 0]
77 | _panelItem = panel.getItem()
78 | editor = _panelItem.querySelector "atom-text-editor"
79 | simulator = _panelItem.querySelector "#sequential-number-simulator"
80 | model = editor.getModel()
81 | previousText = pane.getText()
82 |
83 | expectModelUndoToOriginal = ->
84 | pane.undo()
85 | expect(pane.getText()).toBe previousText
86 |
87 | expectModalTextToEnter = (input, simulateExpected, expected, undo = false) ->
88 | model.setText(input)
89 |
90 | # Simulate the Right key
91 | trigger editor, "HTMLEvents", "keyup", keyCode: 39
92 | expect(simulator.textContent).toBe simulateExpected
93 |
94 | # Simulate the Enter key
95 | trigger editor, "HTMLEvents", "keyup", keyCode: 13
96 | expect(pane.getText()).toBe expected
97 |
98 | if undo
99 | expectModelUndoToOriginal()
100 |
101 | it "does not change if the invalid value", ->
102 | expectModalTextToEnter "", "", previousText
103 | expectModalTextToEnter "--0011", "", previousText
104 | expectModalTextToEnter "++1", "", previousText
105 | expectModalTextToEnter "+1/", "", previousText
106 | expectModalTextToEnter "1%1", "", previousText
107 | expectModalTextToEnter "1*2", "", previousText
108 | expectModalTextToEnter "-2+++", "", previousText
109 | expectModalTextToEnter "+34hoge", "", previousText
110 | expectModalTextToEnter "alphabet", "", previousText
111 |
112 | describe "addition", ->
113 | it "syntax of the '0'", ->
114 | expectModalTextToEnter "0",
115 | "0, 1, 2, ...",
116 | """
117 | 0
118 | 1
119 | 2
120 | 3
121 | 4
122 | """,
123 | true
124 |
125 | it "syntax of the '1'", ->
126 | expectModalTextToEnter "1",
127 | "1, 2, 3, ...",
128 | """
129 | 1
130 | 2
131 | 3
132 | 4
133 | 5
134 | """,
135 | true
136 |
137 | it "syntax of the '1 + 2'", ->
138 | expectModalTextToEnter "1 + 2",
139 | "1, 3, 5, ...",
140 | """
141 | 1
142 | 3
143 | 5
144 | 7
145 | 9
146 | """,
147 | true
148 |
149 | it "syntax of the '5++'", ->
150 | expectModalTextToEnter "5++",
151 | "5, 6, 7, ...",
152 | """
153 | 5
154 | 6
155 | 7
156 | 8
157 | 9
158 | """,
159 | true
160 |
161 | it "syntax of the '015 + 1'", ->
162 | expectModalTextToEnter "015 + 1",
163 | "015, 016, 017, ...",
164 | """
165 | 015
166 | 016
167 | 017
168 | 018
169 | 019
170 | """,
171 | true
172 |
173 | it "syntax of the '09 + 65'", ->
174 | expectModalTextToEnter "09 + 65",
175 | "09, 74, 139, ...",
176 | """
177 | 09
178 | 74
179 | 139
180 | 204
181 | 269
182 | """,
183 | true
184 |
185 | it "syntax of the '-20+12'", ->
186 | expectModalTextToEnter "-20+12",
187 | "-20, -8, 4, ...",
188 | """
189 | -20
190 | -8
191 | 4
192 | 16
193 | 28
194 | """,
195 | true
196 |
197 | it "syntax of the '-10 + 1 : 2'", ->
198 | expectModalTextToEnter "-10 + 1 : 2",
199 | "-10, -09, -08, ...",
200 | """
201 | -10
202 | -09
203 | -08
204 | -07
205 | -06
206 | """,
207 | true
208 |
209 | it "syntax of the '-9 + 1000'", ->
210 | expectModalTextToEnter "-9 + 1000 : 3",
211 | "-009, 991, 1991, ...",
212 | """
213 | -009
214 | 991
215 | 1991
216 | 2991
217 | 3991
218 | """,
219 | true
220 |
221 | describe "subtraction", ->
222 | it "syntax of the '10 - 3'", ->
223 | expectModalTextToEnter "10 - 3",
224 | "10, 7, 4, ...",
225 | """
226 | 10
227 | 7
228 | 4
229 | 1
230 | -2
231 | """,
232 | true
233 |
234 | it "syntax of the '15--'", ->
235 | expectModalTextToEnter "15--",
236 | "15, 14, 13, ...",
237 | """
238 | 15
239 | 14
240 | 13
241 | 12
242 | 11
243 | """,
244 | true
245 |
246 | it "syntax of the '0020 - 2'", ->
247 | expectModalTextToEnter "0020 - 2",
248 | "0020, 0018, 0016, ...",
249 | """
250 | 0020
251 | 0018
252 | 0016
253 | 0014
254 | 0012
255 | """,
256 | true
257 |
258 | it "syntax of the '-003120 - 21'", ->
259 | expectModalTextToEnter "-003120 - 21",
260 | "-003120, -003141, -003162, ...",
261 | """
262 | -003120
263 | -003141
264 | -003162
265 | -003183
266 | -003204
267 | """,
268 | true
269 |
270 | it "syntax of the '-8 - 90 : 3'", ->
271 | expectModalTextToEnter "-8 - 90 : 2",
272 | "-08, -98, -188, ...",
273 | """
274 | -08
275 | -98
276 | -188
277 | -278
278 | -368
279 | """,
280 | true
281 |
282 | describe "radix = 2", ->
283 | it "syntax of the '0 + 1 : 1 : 2'", ->
284 | expectModalTextToEnter "0 + 1 : 1 : 2",
285 | "0, 1, 10, ...",
286 | """
287 | 0
288 | 1
289 | 10
290 | 11
291 | 100
292 | """,
293 | true
294 |
295 | it "syntax of the '-11 - 2 : 2 : 2'", ->
296 | expectModalTextToEnter "-11 - 2 : 2 : 2",
297 | "-11, -101, -111, ...",
298 | """
299 | -11
300 | -101
301 | -111
302 | -1001
303 | -1011
304 | """,
305 | true
306 |
307 | describe "radix = 8", ->
308 | it "syntax of the '6 + 1 : 2 : 8'", ->
309 | expectModalTextToEnter "6 + 1 : 2 : 8",
310 | "06, 07, 10, ...",
311 | """
312 | 06
313 | 07
314 | 10
315 | 11
316 | 12
317 | """,
318 | true
319 |
320 | it "syntax of the '-5 - 5 : 2 : 8'", ->
321 | expectModalTextToEnter "-5 - 5 : 2 : 8",
322 | "-05, -12, -17, ...",
323 | """
324 | -05
325 | -12
326 | -17
327 | -24
328 | -31
329 | """,
330 | true
331 |
332 | describe "radix = 16", ->
333 | it "syntax of the 'a + 6 : 1 : 16'", ->
334 | expectModalTextToEnter "a + 6 : 1 : 16",
335 | "a, 10, 16, ...",
336 | """
337 | a
338 | 10
339 | 16
340 | 1c
341 | 22
342 | """,
343 | true
344 |
345 | it "syntax of the 'C4b + 9 : 6 : 16'", ->
346 | expectModalTextToEnter "C4b + 9 : 6 : 16",
347 | "000C4B, 000C54, 000C5D, ...",
348 | """
349 | 000C4B
350 | 000C54
351 | 000C5D
352 | 000C66
353 | 000C6F
354 | """,
355 | true
356 |
357 | it "syntax of the 'b - 12 : 2 : 16'", ->
358 | expectModalTextToEnter "b - 12 : 2 : 16",
359 | "0b, -01, -0d, ...",
360 | """
361 | 0b
362 | -01
363 | -0d
364 | -19
365 | -25
366 | """,
367 | true
368 |
369 | describe "radix = a", ->
370 | it "syntax of the 'a++ : 1 : a'", ->
371 | expectModalTextToEnter "a++ : 1 : a",
372 | "a, b, c, ...",
373 | """
374 | a
375 | b
376 | c
377 | d
378 | e
379 | """,
380 | true
381 |
382 | it "syntax of the 'a + 2 : 1 : a'", ->
383 | expectModalTextToEnter "a + 2 : 1 : a",
384 | "a, c, e, ...",
385 | """
386 | a
387 | c
388 | e
389 | g
390 | i
391 | """,
392 | true
393 |
394 | it "syntax of the 'z + 3 : 1 : a'", ->
395 | expectModalTextToEnter "z + 3 : 1 : a",
396 | "z, ac, af, ...",
397 | """
398 | z
399 | ac
400 | af
401 | ai
402 | al
403 | """,
404 | true
405 |
406 | it "syntax of the 'W + 2 : 1 : a'", ->
407 | expectModalTextToEnter "W + 2 : 1 : a",
408 | "W, Y, AA, ...",
409 | """
410 | W
411 | Y
412 | AA
413 | AC
414 | AE
415 | """,
416 | true
417 |
418 | it "syntax of the 'w + 2 : 1 : A'", ->
419 | expectModalTextToEnter "W + 2 : 1 : A",
420 | "W, Y, AA, ...",
421 | """
422 | W
423 | Y
424 | AA
425 | AC
426 | AE
427 | """,
428 | true
429 |
430 | it "syntax of the 'y + 2 : 3 : a'", ->
431 | expectModalTextToEnter "y + 2 : 3 : a",
432 | "aay, aaa, aac, ...",
433 | """
434 | aay
435 | aaa
436 | aac
437 | aae
438 | aag
439 | """,
440 | true
441 |
442 | it "syntax of the 'e - 1 : 1 : a'", ->
443 | expectModalTextToEnter "e - 1 : 1 : a",
444 | "e, d, c, ...",
445 | """
446 | e
447 | d
448 | c
449 | b
450 | a
451 | """,
452 | true
453 |
454 | it "syntax of the 'a - 2 : 1 : a'", ->
455 | expectModalTextToEnter "a - 2 : 1 : a",
456 | "a, , , ...",
457 | """
458 | a
459 |
460 |
461 |
462 |
463 | """,
464 | true
465 |
466 | describe "single line", ->
467 | it "syntax of the '1 + 1 : 2'", ->
468 | text = "test[] test[] test[]"
469 | pane.setText text
470 | pane.setCursorScreenPosition [0, 5]
471 | pane.addCursorAtScreenPosition [0, 12]
472 | pane.addCursorAtScreenPosition [0, 19]
473 | expectModalTextToEnter "1 + 1 : 2",
474 | "01, 02, 03, ...",
475 | """
476 | test[01] test[02] test[03]
477 | """,
478 | false
479 |
480 | pane.undo()
481 | expect(pane.getText()).toBe text
482 |
483 | describe "when the currently selected text", ->
484 | it "replace selected text", ->
485 | pane.insertText "Hello World!!"
486 |
487 | # Select all of the "Hello World!!"
488 | for cursor in pane.getCursors()
489 | position = cursor.getBufferPosition()
490 | startPoint = new Point position.row, 0
491 | endPoint = new Point position.row, 13
492 | cursor.selection.setBufferRange new Range startPoint, endPoint
493 |
494 | model.setText "01+1:3"
495 |
496 | # Simulate the Enter key
497 | trigger editor, "HTMLEvents", "keyup", keyCode: 13
498 |
499 | expect(pane.getText()).toBe """
500 | 001
501 | 002
502 | 003
503 | 004
504 | 005
505 | """
506 |
--------------------------------------------------------------------------------