Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 1b23a63

Browse files
committed
almost done now
i made some refactoring and such this is more of a "hey, this is till being worked on" commit stuff still to do: - transformations are not done, i changed the format (easy) - tests are incomplete (being worked on, not on this commit) (easy but time consuming) - need to go over things and document them properly (hard, but i think i might have something to make it easier)
1 parent e7d8455 commit 1b23a63

20 files changed

+1110
-1589
lines changed

available-snippets-view.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,18 @@ module.exports = class AvailableSnippetsView extends SelectListView {
66
items: Object.entries(snippets.snippetsByScopes()
77
.getPropertyValue(editor.getRootScopeDescriptor().getScopeChain())),
88
filterKeyForItem: ([name, { prefix }]) => prefix + name,
9-
elementForItem: ([name, { prefix }]) => {
9+
elementForItem: ([name, { prefix, description }]) => {
1010
const li = document.createElement('li')
1111
li.classList.add('two-lines')
1212

13-
const primaryLine = document.createElement('div')
13+
const primaryLine = li.appendChild(document.createElement('div'))
1414
primaryLine.classList.add('primary-line')
1515
primaryLine.textContent = prefix
16-
li.appendChild(primaryLine)
1716

18-
const secondaryLine = document.createElement('div')
17+
const secondaryLine = li.appendChild(document.createElement('div'))
1918
secondaryLine.classList.add('secondary-line')
20-
secondaryLine.textContent = name
21-
li.appendChild(secondaryLine)
19+
// TODO: Nullish coalescing operator
20+
secondaryLine.textContent = description != null ? description : name
2221

2322
return li
2423
},

constructs/tabstop.js

-7
This file was deleted.

constructs/variable.js

-9
This file was deleted.
File renamed without changes.

expression/choice.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const { CompositeDisposable } = require('atom')
2+
3+
const Expression = require('./expression')
4+
5+
module.exports = class Choice extends Expression {
6+
constructor (identifier, choices) {
7+
super(identifier)
8+
9+
this.choices = choices
10+
// The "first" and therefore default values is last in the list so that
11+
// choice cycling starts from the second choice
12+
this.default = choices[choices.length - 1]
13+
}
14+
15+
activate (editor, cursor, stop, mirror) {
16+
super.activate(editor, cursor, stop, mirror)
17+
// Don't bother if a mirror, the marker won't get iterated over
18+
if (mirror === stop) {
19+
const disposables = new CompositeDisposable()
20+
21+
const target = 'atom-text-editor:not([mini])'
22+
const cycle = `snippets:next-choice-${stop.id}`
23+
24+
const choices = {
25+
choices: this.choices,
26+
iterator: this.choices.values(),
27+
next () {
28+
const iteration = this.iterator.next()
29+
const { value } = iteration.done
30+
? (this.iterator = this.choices.values()).next()
31+
: iteration
32+
editor.getBuffer().setTextInRange(stop.getBufferRange(), value)
33+
cursor.selection.setBufferRange(stop.getBufferRange())
34+
}
35+
}
36+
37+
// What happens when the user clicks inside the choice, resulting in it nolonger being selected
38+
disposables.add(
39+
atom.keymaps.add(module.filename, { [target]: { 'shift-tab': cycle } }),
40+
atom.commands.add(target, cycle, event => choices.next()),
41+
cursor.onDidChangePosition(({ newBufferPosition }) => {
42+
if (!stop.getBufferRange().containsPoint(newBufferPosition)) {
43+
disposables.dispose()
44+
}
45+
}))
46+
}
47+
}
48+
49+
expand (editor, cursor, tabstops, variables) {
50+
if (!(this.identifier in variables)) {
51+
this.mark({ tabstops, ...this.insert(editor, cursor, this.default) })
52+
} else {
53+
super.expand(editor, cursor, tabstops, variables)
54+
}
55+
}
56+
57+
toString () {
58+
return this.default.toString()
59+
}
60+
}

constructs/construct.js expression/expression.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
module.exports = class Construct {
1+
module.exports = class Expression {
22
constructor (identifier) {
33
this.identifier = identifier
44
}
55

6-
expand () {}
6+
expand (editor, cursor, tabstops, variables) {
7+
// Check whether we are a tabstop or a variable
8+
Number.isInteger(this.identifier)
9+
// Create a tabstop marker at our position
10+
? this.mark({ tabstops, start: cursor.getBufferPosition() })
11+
// Check whether we are a know variable or not
12+
: this.identifier in variables
13+
// Insert the variables value
14+
? this.insert(editor, cursor, variables[this.identifier])
15+
// Insert 'this.identifier' and create a tabstop marker with it selected
16+
: this.mark({ tabstops, ...this.insert(editor, cursor, this.identifier) })
17+
}
718

819
insert (editor, cursor, value) {
920
return editor.getBuffer().insert(cursor.getBufferPosition(), value)
@@ -24,8 +35,8 @@ module.exports = class Construct {
2435
}
2536
}
2637

27-
mark ({ tabstops, start, end = start, exclusive = true, construct = this }) {
28-
tabstops.markBufferRange({ start, end }, { exclusive }).setProperties({ construct })
38+
mark ({ tabstops, start, end = start, exclusive = true, expression = this }) {
39+
tabstops.markBufferRange({ start, end }, { exclusive }).setProperties({ expression })
2940
}
3041

3142
toString () {

expression/placeholder.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const Expression = require('./expression')
2+
3+
module.exports = class Placeholder extends Expression {
4+
constructor (identifier, snippet) {
5+
super(identifier)
6+
7+
this.snippet = snippet
8+
}
9+
10+
expand (editor, cursor, tabstops, variables) {
11+
if (!(this.identifier in variables)) {
12+
this.mark({ tabstops, ...this.snippet.expand({ editor, cursor, tabstops, variables }) })
13+
} else {
14+
super.expand(editor, cursor, tabstops, variables)
15+
}
16+
}
17+
18+
toString () {
19+
return this.snippet.toString()
20+
}
21+
}

constructs/snippet.js expression/snippet.js

+13-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
const { CompositeDisposable } = require('atom')
22
const path = require('path')
33

4-
const Construct = require('./construct')
4+
const Expression = require('./expression')
55

6-
module.exports = class Snippet extends Construct {
6+
module.exports = class Snippet extends Expression {
77
static VARIABLES = {
88
// The currently selected text or the empty string
99
TM_SELECTED_TEXT: (editor, cursor) => cursor.selection.getText(),
@@ -61,9 +61,10 @@ module.exports = class Snippet extends Construct {
6161
// LINE_COMMENT
6262
//
6363
// custom = custom variables
64+
// TODO: I dont remember what this cache is supposed to do
6465
PROXY: (editor, cursor, custom) => new Proxy({}, {
6566
get: (cache, property) => property in this.VARIABLES
66-
? (cache[property] = this.VARIABLES[property]())
67+
? (cache[property] = this.VARIABLES[property](editor, cursor))
6768
: property in custom
6869
? custom[property]
6970
// We should never see this value used
@@ -77,12 +78,12 @@ module.exports = class Snippet extends Construct {
7778
const unknowns = []
7879

7980
markers.forEach(marker => {
80-
const { construct } = marker.getProperties()
81+
const { expression } = marker.getProperties()
8182

82-
Number.isInteger(construct.identifier)
83-
? Array.isArray(tabstops[construct.identifier])
84-
? tabstops[construct.identifier].push(marker)
85-
: tabstops[construct.identifier] = [marker]
83+
Number.isInteger(expression.identifier)
84+
? Array.isArray(tabstops[expression.identifier])
85+
? tabstops[expression.identifier].push(marker)
86+
: tabstops[expression.identifier] = [marker]
8687
: unknowns.push([marker])
8788
})
8889
// Include all unknown variables at the end
@@ -95,21 +96,18 @@ module.exports = class Snippet extends Construct {
9596
return tabstops
9697
}
9798

98-
constructor (body, legacySyntax) {
99+
constructor (body) {
99100
// This snippet will work as the default ending tabstop
100101
super(0)
101102

102103
this.body = body
103-
104-
this.legacySyntax = legacySyntax
105104
}
106105

107106
// We work as the default ending tabstop, this is a special case
108107
activate (editor, cursor, stop, mirror) {
109108
cursor.setBufferPosition(stop.getBufferRange().end)
110109
}
111110

112-
// helper cause Snippet isn't really ever available
113111
expand ({
114112
editor = atom.workspace.getActiveTextEditor(),
115113
cursor = editor.getLastCursor(),
@@ -123,7 +121,7 @@ module.exports = class Snippet extends Construct {
123121
})
124122
}
125123

126-
// Construct a variable proxy to access given and built-in variables
124+
// Expression a variable proxy to access given and built-in variables
127125
variables = Snippet.VARIABLES.PROXY(editor, cursor, variables)
128126

129127
// Define a marker that spans the whole snippet
@@ -160,8 +158,8 @@ module.exports = class Snippet extends Construct {
160158
const iteration = this.iterator.next()
161159
if (!iteration.done) {
162160
const { value: [stop] } = iteration
163-
const { construct } = stop.getProperties()
164-
iteration.value.forEach(mirror => construct.activate(editor, cursor, stop, mirror))
161+
const { expression } = stop.getProperties()
162+
iteration.value.forEach(mirror => expression.activate(editor, cursor, stop, mirror))
165163
return true
166164
}
167165
disposables.dispose()

expression/transformation.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const Expression = require('./expression')
2+
3+
module.exports = class Transformation extends Expression {
4+
constructor (identifier, [regexp, format, flags]) {
5+
super(identifier)
6+
7+
this.regexp = new RegExp(regexp, flags.join(''))
8+
this.format = format
9+
}
10+
11+
activate (editor, cursor, stop, mirror) {
12+
super.activate(editor, cursor, stop, mirror)
13+
mirror.onDidDestroy(() => {
14+
const range = mirror.getBufferRange()
15+
const buffer = editor.getBuffer()
16+
buffer.setTextInRange(range, this.transform(buffer.getTextInRange(range)))
17+
})
18+
}
19+
20+
transform (string, regexp = this.regexp) {
21+
let fold = sequence => sequence
22+
return this.format.reduce((result, sequence) => {
23+
const [group, insertion, replacement = ''] = sequence
24+
sequence instanceof Function
25+
? fold = sequence
26+
: sequence instanceof Object
27+
? result += fold(string.replace(regexp, group) ? insertion : replacement)
28+
: result += fold(string.replace(regexp, sequence))
29+
return result
30+
}, '')
31+
}
32+
33+
insert (editor, cursor, value) {
34+
return super.insert(editor, cursor, this.transform(value))
35+
}
36+
37+
toString () {
38+
return this.transform(super.toString())
39+
}
40+
}

modifiers/babel.config.json

-6
This file was deleted.

modifiers/choice.js

-66
This file was deleted.

modifiers/modifier.js

-6
This file was deleted.

modifiers/placeholder.js

-29
This file was deleted.

0 commit comments

Comments
 (0)