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

Speed up spell checking #102

Merged
merged 7 commits into from
Jan 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/corrections-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class CorrectionsView extends SelectListView
@cancel()
return unless correction
@editor.transact =>
@editor.selectMarker(@marker)
@editor.setSelectedBufferRange(@marker.getRange())
@editor.insertText(correction)

cancelled: ->
Expand Down
12 changes: 7 additions & 5 deletions lib/main.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ module.exports =
description: 'List of scopes for languages which will be checked for misspellings. See [the README](https://github.com/atom/spell-check#spell-check-package-) for more information on finding the correct scope for a specific language.'

activate: ->
@disposable = atom.workspace.observeTextEditors(addViewToEditor)
@viewsByEditor = new WeakMap
@disposable = atom.workspace.observeTextEditors (editor) =>
SpellCheckView ?= require './spell-check-view'
@viewsByEditor.set(editor, new SpellCheckView(editor))

misspellingMarkersForEditor: (editor) ->
@viewsByEditor.get(editor).markerLayer.getMarkers()

deactivate: ->
@disposable.dispose()

addViewToEditor = (editor) ->
SpellCheckView ?= require './spell-check-view'
new SpellCheckView(editor)
44 changes: 0 additions & 44 deletions lib/misspelling-view.coffee

This file was deleted.

34 changes: 24 additions & 10 deletions lib/spell-check-handler.coffee
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
SpellChecker = require 'spellchecker'

wordRegex = /(?:^|[\s\[\]"'])([a-zA-Z]+([a-zA-Z']+[a-zA-Z])?)(?=[\s\.\[\]:,"']|$)/g

module.exports = ({id, text}) ->
SpellChecker.add("GitHub")
SpellChecker.add("github")

misspelledCharacterRanges = SpellChecker.checkSpelling(text)

row = 0
rangeIndex = 0
characterIndex = 0
misspellings = []
for line in text.split('\n')
while matches = wordRegex.exec(line)
word = matches[1]
continue if word in ['GitHub', 'github']
continue unless SpellChecker.isMisspelled(word)
while characterIndex < text.length and rangeIndex < misspelledCharacterRanges.length
lineBreakIndex = text.indexOf('\n', characterIndex)
if lineBreakIndex is -1
lineBreakIndex = Infinity

startColumn = matches.index + matches[0].length - word.length
endColumn = startColumn + word.length
misspellings.push([[row, startColumn], [row, endColumn]])
loop
range = misspelledCharacterRanges[rangeIndex]
if range and range.start < lineBreakIndex
misspellings.push([
[row, range.start - characterIndex],
[row, range.end - characterIndex]
])
rangeIndex++
else
break

characterIndex = lineBreakIndex + 1
row++

{id, misspellings}
52 changes: 41 additions & 11 deletions lib/spell-check-view.coffee
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
_ = require 'underscore-plus'
{CompositeDisposable} = require 'atom'
MisspellingView = require './misspelling-view'
SpellCheckTask = require './spell-check-task'

CorrectionsView = null
SpellChecker = null

module.exports =
class SpellCheckView
@content: ->
@div class: 'spell-check'

constructor: (@editor) ->
@disposables = new CompositeDisposable
@views = []
@task = new SpellCheckTask()
@initializeMarkerLayer()

@correctMisspellingCommand = atom.commands.add atom.views.getView(@editor), 'spell-check:correct-misspelling', =>
if marker = @markerLayer.findMarkers({containsPoint: @editor.getCursorBufferPosition()})[0]
CorrectionsView ?= require './corrections-view'
@correctionsView?.destroy()
@correctionsView = new CorrectionsView(@editor, @getCorrections(marker), marker)

@task.onDidSpellCheck (misspellings) =>
@destroyViews()
@addViews(misspellings) if @buffer?
@detroyMarkers()
@addMarkers(misspellings) if @buffer?

@disposables.add @editor.onDidChangePath =>
@subscribeToBuffer()
Expand All @@ -33,13 +41,25 @@ class SpellCheckView

@disposables.add @editor.onDidDestroy(@destroy.bind(this))

initializeMarkerLayer: ->
@markerLayer = @editor.getBuffer().addMarkerLayer()
@markerLayerDecoration = @editor.decorateMarkerLayer(@markerLayer, {
type: 'highlight',
class: 'spell-check-misspelling',
deprecatedRegionClass: 'misspelling'
})

destroy: ->
@unsubscribeFromBuffer()
@disposables.dispose()
@task.terminate()
@markerLayer.destroy()
@markerLayerDecoration.destroy()
@correctMisspellingCommand.dispose()
@correctionsView?.remove()

unsubscribeFromBuffer: ->
@destroyViews()
@detroyMarkers()

if @buffer?
@bufferDisposable.dispose()
Expand All @@ -57,18 +77,28 @@ class SpellCheckView
grammar = @editor.getGrammar().scopeName
_.contains(atom.config.get('spell-check.grammars'), grammar)

destroyViews: ->
while view = @views.shift()
view.destroy()
detroyMarkers: ->
@markerLayer.destroy()
@markerLayerDecoration.destroy()
@initializeMarkerLayer()

addViews: (misspellings) ->
addMarkers: (misspellings) ->
for misspelling in misspellings
view = new MisspellingView(misspelling, @editor)
@views.push(view)
@markerLayer.markRange(misspelling,
invalidate: 'touch',
replicate: 'false',
persistent: false,
maintainHistory: false,
)

updateMisspellings: ->
# Task::start can throw errors atom/atom#3326
try
@task.start(@buffer.getText())
catch error
console.warn('Error starting spell check task', error.stack ? error)

getCorrections: (marker) ->
SpellChecker ?= require 'spellchecker'
misspelling = @editor.getTextInBufferRange(marker.getRange())
corrections = SpellChecker.getCorrectionsForMisspelling(misspelling)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "Highlights misspelled words and shows possible corrections.",
"dependencies": {
"atom-space-pen-views": "^2.0.0",
"spellchecker": "^3.1.2",
"spellchecker": "3.2.0",
"underscore-plus": "^1"
},
"repository": "https://github.com/atom/spell-check",
Expand Down
15 changes: 15 additions & 0 deletions script/benchmark.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env coffee

handler = require '../lib/spell-check-handler'
fs = require 'fs'

pathToCheck = process.argv[2]
console.log("Spellchecking %s...", pathToCheck)

text = fs.readFileSync(pathToCheck, 'utf8')

t0 = Date.now()
result = handler({id: 1, text})
t1 = Date.now()

console.log("Found %d misspellings in %d milliseconds", result.misspellings.length, t1 - t0)
Loading