Correct Spellchecking

This commit is contained in:
Janosch Maier 2021-11-26 21:59:06 +01:00 committed by Ben Gotow
parent e2289ac204
commit e17e6bbb1e
3 changed files with 16 additions and 92 deletions

View file

@ -167,14 +167,6 @@ function onSpellcheckFocusedNode(editor) {
function onSpellcheckFullDocument(editor) { function onSpellcheckFullDocument(editor) {
const { value } = editor; const { value } = editor;
// re-determine the language the document is written in
if (value.focusBlock) {
const text = value.focusBlock.text;
if (text.length > 60) {
AppEnv.spellchecker.provideHintText(text.substr(text.length - 512, 512));
}
}
// spellcheck all text nodes // spellcheck all text nodes
const texts = collectSpellcheckableTextNodes(value.document); const texts = collectSpellcheckableTextNodes(value.document);
const decorations = []; const decorations = [];

View file

@ -281,7 +281,7 @@ export default {
], ],
title: localized('Spellcheck language'), title: localized('Spellcheck language'),
note: localized( note: localized(
'If you write a draft in another language, Mailspring will auto-detect it and use the correct spelling dictionary after a few sentences.' 'Windows and Linux only - on macOS, the spellcheck language is detected by the system as you type.'
), ),
}, },
}, },

View file

@ -1,5 +1,4 @@
import { remote } from 'electron'; import { remote, webFrame } from 'electron';
import LRUCache from 'lru-cache';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { localized } from './intl'; import { localized } from './intl';
@ -7,24 +6,17 @@ import { localized } from './intl';
const { app, MenuItem } = remote; const { app, MenuItem } = remote;
const customDictFilePath = path.join(AppEnv.getConfigDirPath(), 'custom-dict.json'); const customDictFilePath = path.join(AppEnv.getConfigDirPath(), 'custom-dict.json');
const { webFrame } = require('electron');
class Spellchecker { class Spellchecker {
private _customDictLoaded = false;
private _saveOnLoad = false;
private _savingCustomDict = false;
private _saveAgain = false;
private _win;
private _customDict = {}; private _session = remote.getCurrentWebContents().session;
constructor() { constructor() {
//this._session = ;
// Nobody will notice if spellcheck isn't available for a few seconds and it // Nobody will notice if spellcheck isn't available for a few seconds and it
// takes a considerable amount of time to startup (212ms in dev mode on my 2017 MBP) // takes a considerable amount of time to startup (212ms in dev mode on my 2017 MBP)
const initHandler = () => { const initHandler = () => {
this._win = AppEnv.getCurrentWindow(); this._migrateFromCustomDict();
this._loadCustomDict();
const initialLanguage = AppEnv.config.get('core.composing.spellcheckDefaultLanguage'); const initialLanguage = AppEnv.config.get('core.composing.spellcheckDefaultLanguage');
this._switchToLanguage(initialLanguage); this._switchToLanguage(initialLanguage);
@ -44,20 +36,15 @@ class Spellchecker {
} }
_switchToLanguage = lang => { _switchToLanguage = (lang: string | undefined | null) => {
if (lang === null || lang === undefined || lang === '') { if (lang === null || lang === undefined || lang === '') {
lang = app.getLocale() || 'en-US'; lang = app.getLocale() || 'en-US';
} }
// Only switch to a language that is supported by the system. this._session.setSpellCheckerLanguages([lang]);
// Otherwise stay at the current language. Default language is the OS language.
if (this._win.webContents.session.availableSpellCheckerLanguages.includes(lang)) {
this._win.webContents.session.setSpellCheckerLanguages([lang])
}
}; };
_loadCustomDict = () => { _migrateFromCustomDict = () => {
/*
fs.readFile(customDictFilePath, (err, data) => { fs.readFile(customDictFilePath, (err, data) => {
let fileData: any = data; let fileData: any = data;
if (err) { if (err) {
@ -70,78 +57,23 @@ class Spellchecker {
} }
} }
const loadedDict = JSON.parse(fileData); const loadedDict = JSON.parse(fileData);
this._customDict = Object.assign(loadedDict, this._customDict); Object.keys(loadedDict).forEach(word => this._session.addWordToSpellCheckerDictionary(word));
this._customDictLoaded = true; fs.unlink(customDictFilePath, () => { });
if (this._saveOnLoad) {
this._saveCustomDict();
this._saveOnLoad = false;
}
});
*/
};
_saveCustomDict = () => {
/*
// If we haven't loaded the dict yet, saving could overwrite all the things.
// Wait until the loaded dict is merged with our working copy before saving
if (this._customDictLoaded) {
// Don't perform two writes at the same time, as this results in an overlaid
// version of the data. (This may or may not happen in practice, but was
// an issue with the tests)
if (this._savingCustomDict) {
this._saveAgain = true;
} else {
this._savingCustomDict = true;
fs.writeFile(customDictFilePath, JSON.stringify(this._customDict), err => {
if (err) {
AppEnv.reportError(err);
}
this._savingCustomDict = false;
if (this._saveAgain) {
this._saveAgain = false;
this._saveCustomDict();
}
}); });
} }
} else {
this._saveOnLoad = true;
}
*/
};
provideHintText = text => {
/*
if (!this.handler) {
return false;
}
this.handler.provideHintText(text);
*/
};
isMisspelled = (word: string) => { isMisspelled = (word: string) => {
if ({}.hasOwnProperty.call(this._customDict, word)) {
return false;
}
return webFrame.isWordMisspelled(word) return webFrame.isWordMisspelled(word)
}; };
learnWord = word => { learnWord = (word: string) => {
/* // TODO: Ensure that this work. Somehow on my Ubuntu 20.12., this does not add words to the custom dict.
this._customDict[word] = ''; this._session.addWordToSpellCheckerDictionary(word);
this._saveCustomDict();
*/
}; };
unlearnWord = word => { unlearnWord = (word: string) => {
/* this._session.removeWordFromSpellCheckerDictionary(word);
if (word in this._customDict) {
delete this._customDict[word];
this._saveCustomDict();
}
*/
}; };
appendSpellingItemsToMenu = async ({ menu, word, onCorrect, onDidLearn }) => { appendSpellingItemsToMenu = async ({ menu, word, onCorrect, onDidLearn }) => {