Skip to content

Commit cd81c90

Browse files
authored
Fix keyboard edits, capitalization
Closes GH-45. Closes GH-46.
1 parent 9c002d2 commit cd81c90

File tree

2 files changed

+79
-13
lines changed

2 files changed

+79
-13
lines changed

lib/suggest.js

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,12 @@ function suggest(value) {
152152

153153
push.apply(edits, values)
154154

155-
// Ensure the lower-cased, capitalised, and uppercase values are included.
155+
// Ensure the capitalised and uppercase values are included.
156156
values = [value]
157157
replacement = value.toLowerCase()
158158

159-
if (value === replacement) {
159+
if (value === replacement || currentCase === null) {
160160
values.push(value.charAt(0).toUpperCase() + replacement.slice(1))
161-
} else {
162-
values.push(replacement)
163161
}
164162

165163
replacement = value.toUpperCase()
@@ -257,6 +255,7 @@ function generate(context, memory, words, edits) {
257255
var flags = context.flags
258256
var result = []
259257
var upper
258+
var nextUpper
260259
var length
261260
var index
262261
var word
@@ -270,6 +269,7 @@ function generate(context, memory, words, edits) {
270269
var nextCharacter
271270
var inject
272271
var offset
272+
var currentCase
273273

274274
// Check the pre-generated edits.
275275
length = edits && edits.length
@@ -289,8 +289,10 @@ function generate(context, memory, words, edits) {
289289
before = ''
290290
character = ''
291291
nextAfter = word
292+
currentCase = casing(word)
292293
nextNextAfter = word.slice(1)
293294
nextCharacter = word.charAt(0)
295+
nextUpper = nextCharacter.toLowerCase() !== nextCharacter
294296
position = -1
295297
count = word.length + 1
296298

@@ -302,7 +304,23 @@ function generate(context, memory, words, edits) {
302304
nextNextAfter = nextAfter.slice(1)
303305
character = nextCharacter
304306
nextCharacter = word.charAt(position + 1)
305-
upper = character.toLowerCase() !== character
307+
upper = nextUpper
308+
if (nextCharacter) {
309+
nextUpper = nextCharacter.toLowerCase() !== nextCharacter
310+
}
311+
312+
if (nextAfter && upper !== nextUpper) {
313+
// Remove.
314+
check(before + switchCase(nextAfter))
315+
316+
// Switch.
317+
check(
318+
before +
319+
switchCase(nextCharacter) +
320+
switchCase(character) +
321+
nextNextAfter
322+
)
323+
}
306324

307325
// Remove.
308326
check(before + nextAfter)
@@ -318,14 +336,19 @@ function generate(context, memory, words, edits) {
318336
while (++offset < characterLength) {
319337
inject = characters[offset]
320338

321-
// Add and replace.
322-
check(before + inject + after)
323-
check(before + inject + nextAfter)
324-
325339
// Try upper-case if the original character was upper-cased.
326340
if (upper && inject !== inject.toUpperCase()) {
341+
if (currentCase !== 's') {
342+
check(before + inject + after)
343+
check(before + inject + nextAfter)
344+
}
345+
327346
inject = inject.toUpperCase()
328347

348+
check(before + inject + after)
349+
check(before + inject + nextAfter)
350+
} else {
351+
// Add and replace.
329352
check(before + inject + after)
330353
check(before + inject + nextAfter)
331354
}
@@ -359,4 +382,13 @@ function generate(context, memory, words, edits) {
359382
memory.weighted[value]++
360383
}
361384
}
385+
386+
function switchCase(fragment) {
387+
var first = fragment.charAt(0)
388+
if (first.toLowerCase() === first) {
389+
return first.toUpperCase() + fragment.slice(1)
390+
}
391+
392+
return first.toLowerCase() + fragment.slice(1)
393+
}
362394
}

test/index.js

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,18 @@ test('NSpell()', function (t) {
263263

264264
st.deepEqual(
265265
us.suggest('Ghandi'),
266-
['Brandi', 'Ghana', 'Grandee', 'Shanxi', 'hand', 'hands', 'handy'],
266+
[
267+
'Brandi',
268+
'Ghana',
269+
'Grandee',
270+
'Hand',
271+
'Hands',
272+
'Handy',
273+
'Hanoi',
274+
'Hindi',
275+
'Randi',
276+
'Shanxi'
277+
],
267278
'should suggest alternatives'
268279
)
269280

@@ -479,26 +490,49 @@ test('NSpell()', function (t) {
479490
us.suggest('dont'),
480491
[
481492
'cont',
482-
'font',
483493
'dent',
484494
'dint',
485495
'done',
486496
'dong',
487-
'wont',
497+
'font',
488498
'dolt',
489499
'don',
490500
"don't",
491501
'dona',
492502
'dons',
493503
'dost',
494504
'dot',
505+
'wont',
495506
'Donn',
496507
'Mont',
497-
'ONT'
508+
'Ont'
498509
],
499510
'should suggest alternatives including correct conjunction'
500511
)
501512

513+
st.deepEqual(
514+
us.suggest('Iffect'),
515+
['Affect', 'Effect', 'Infect'],
516+
'should suggest sentence-case with replaced first character'
517+
)
518+
519+
st.deepEqual(
520+
us.suggest('Acnada'),
521+
['Canada'],
522+
'should suggest sentence-case with swapped first character'
523+
)
524+
525+
st.deepEqual(
526+
us.suggest('abDUL'),
527+
['Abdul'],
528+
'should suggest sentence-case for funky case when sentence-case in dictionary'
529+
)
530+
531+
st.deepEqual(
532+
us.suggest('COLORFU'),
533+
['COLORFUL'],
534+
'should suggest alternatives for upper-case with added letter'
535+
502536
st.deepEqual(
503537
us.suggest('TODO'),
504538
[`DODO`, `TOD`, `TODD`, `TOGO`, `TOJO`, `TOO`, `TOTO`],

0 commit comments

Comments
 (0)