electron-spellchecker
electron-spellchecker copied to clipboard
macOS does NOT do automatic language detection
In opposite to what is assumed here it does not look like macOS is doing automatic language detection.
My guess is that because we use node-spellchecker#setDictionary
, the automatic language detection is deactivated given what is done in MacSpellchecker::UpdateGlobalSpellchecker
@alexstrat I can reproduce. Any workaround for this?
@alexstrat same on Linux as well.
Hmm. This used to work for me, but not anymore.
I just wanted to loop back around to this. It appears that somewhere in the past 6 months, the language auto detect has stopped working. @paulcbetts any ideas how to fix this? I'm more than happy to help.
This is a little suspect: https://github.com/atom/node-spellchecker/blob/master/src/spellchecker_mac.mm#L149-L154
Here's my attempt for language detection:
import * as _ from "lodash"
import { webFrame } from "electron"
interface Spellchecker {
isMisspelled: (word: string) => boolean
getCorrectionsForMisspelling: (word: string) => Array<string>
checkSpelling: (corpus: string) => Array<{ start: number; end: number }>
checkSpellingAsync: (
corpus: string
) => Promise<Array<{ start: number; end: number }>>
add: (word: string) => void
remove: (word: string) => void
getAvailableDictionaries: () => Array<string>
setDictionary: (lang: string) => void
}
interface Cld {
detect: (text: string, fn: (err: Error, result: any) => void) => void
}
class SpellCheck {
// cld is a native C program by google for determining the language
// of a body of text. Note: it can handle HTML with the right options.
private cld?: Cld
// Native bindings to Mac and Windows spellcheckers.
private spellchecker?: Spellchecker
// Language that we're spell-checking
private currentLanguage: string | undefined
// Dynamically import the native modules in case they fail.
async initialize() {
this.spellchecker = await import("spellchecker")
this.cld = await import("cld")
document.addEventListener("selectionchange", this.handleSelectionChange)
}
// Detect language as the selection changes.
private currentInputElement: HTMLElement | undefined
private handleSelectionChange = () => {
const inputElement = this.getInputElement()
if (inputElement && inputElement !== this.currentInputElement) {
// If the selection changed inputs, compute new language immediately.
this.currentInputElement = inputElement
this.handleDetectLanguageChange(inputElement)
} else if (inputElement) {
this.handleDetectLanguageChangeThrottled(inputElement)
}
}
private handleDetectLanguageChange = (element: HTMLElement) => {
const text = element.textContent
if (text) {
const lang = this.detectLanguage(text)
if (lang) {
this.setLanguage(lang)
}
}
}
private handleDetectLanguageChangeThrottled = _.throttle(
this.handleDetectLanguageChange,
500
)
private detectLanguage(text: string) {
let lang: string | undefined
if (this.cld) {
this.cld.detect(text, (err, result) => {
if (result && result.reliable) {
if (result.languages) {
const language = result.languages[0]
if (language && language.code) {
lang = language.code
}
}
}
})
}
return lang
}
private setLanguage(lang: string) {
if (this.currentLanguage !== lang) {
this.currentLanguage = lang
webFrame.setSpellCheckProvider(lang, true, {
spellCheck: word => {
if (this.spellchecker) {
// Note: you can iterate through multiple languages here.
this.spellchecker.setDictionary(lang)
if (!this.spellchecker.isMisspelled(word)) {
return true
}
}
return false
},
})
}
}
private getInputElement() {
const element = document.activeElement
if (element instanceof HTMLElement) {
if (element.tagName === "input" || element.contentEditable === "true") {
return element
}
}
}
}
const spellcheck = new SpellCheck()
try {
spellcheck.initialize()
} catch (error) {
console.error(error)
}
Just to expand (confound?) the issue; this is also not working on Windows 10 (64-bit) (discovered in GitKraken, which uses electron for spell checking).
I confirm language detection still doesn't work. It'd be great if this can be fixed.
@ccorcos Is there an easy way to use your patch?
Update: it seems like Electron now supports spellchecker natively: https://github.com/electron/electron/pull/20692