Add way to remove items from document dictionary

This commit is contained in:
Juergen Spitzmueller 2021-03-07 18:23:07 +01:00
parent 07122f066b
commit c8feef2e23
11 changed files with 85 additions and 20 deletions

View File

@ -119,6 +119,9 @@
* spelling-add-local adds words for a given language to the document's local spelling
dictionary.
* spelling-remove-local removes words for a given language from the document's local
spelling dictionary.
* inset-split is a new convenience function that splits an inset into two at the given
cursor position. This is only implemented for text insets currently.

View File

@ -92,7 +92,7 @@ SpellChecker::Result AppleSpellChecker::check(WordLangTuple const & word,
if (it->lang()->code() != word.lang()->code())
continue;
if (it->word() == word.word())
return LEARNED_WORD;
return DOCUMENT_LEARNED_WORD;
}
SpellCheckResult result =

View File

@ -445,7 +445,7 @@ SpellChecker::Result AspellChecker::check(WordLangTuple const & word,
if (it->lang()->code() != word.lang()->code())
continue;
if (it->word() == word.word())
return LEARNED_WORD;
return DOCUMENT_LEARNED_WORD;
}
SpellChecker::Result rc = d->check(m, word);
return (rc == WORD_OK && d->learned(word)) ? LEARNED_WORD : rc;

View File

@ -139,7 +139,7 @@ SpellChecker::Result EnchantChecker::check(WordLangTuple const & word,
if (it->lang()->code() != word.lang()->code())
continue;
if (it->word() == word.word())
return LEARNED_WORD;
return DOCUMENT_LEARNED_WORD;
}
return UNKNOWN_WORD;

View File

@ -499,6 +499,7 @@ enum FuncCode
LFUN_FONT_NO_SPELLCHECK, // jspitzm 20210305
LFUN_SPELLING_ADD_LOCAL, // jspitzm 20210306
// 390
LFUN_SPELLING_REMOVE_LOCAL, // jspitzm 20210307
LFUN_LASTACTION // end of the table
};

View File

@ -70,8 +70,7 @@ struct HunspellChecker::Private
Hunspell * speller(Language const * lang);
Hunspell * lookup(Language const * lang);
/// ignored words
bool isIgnored(WordLangTuple const & wl,
std::vector<WordLangTuple> const & docdict) const;
bool isIgnored(WordLangTuple const & wl) const;
/// personal word list interface
void remove(WordLangTuple const & wl);
void insert(WordLangTuple const & wl);
@ -282,8 +281,7 @@ int HunspellChecker::Private::numDictionaries() const
}
bool HunspellChecker::Private::isIgnored(WordLangTuple const & wl,
vector<WordLangTuple> const & docdict) const
bool HunspellChecker::Private::isIgnored(WordLangTuple const & wl) const
{
IgnoreList::const_iterator it = ignored_.begin();
for (; it != ignored_.end(); ++it) {
@ -292,13 +290,6 @@ bool HunspellChecker::Private::isIgnored(WordLangTuple const & wl,
if (it->word() == wl.word())
return true;
}
it = docdict.begin();
for (; it != docdict.end(); ++it) {
if (it->lang()->code() != wl.lang()->code())
continue;
if (it->word() == wl.word())
return true;
}
return false;
}
@ -356,9 +347,17 @@ HunspellChecker::~HunspellChecker()
SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl,
vector<WordLangTuple> const & docdict)
{
if (d->isIgnored(wl, docdict))
if (d->isIgnored(wl))
return WORD_OK;
IgnoreList::const_iterator it = docdict.begin();
for (; it != docdict.end(); ++it) {
if (it->lang()->code() != wl.lang()->code())
continue;
if (it->word() == wl.word())
return DOCUMENT_LEARNED_WORD;
}
Hunspell * h = d->speller(wl.lang());
if (!h)
return NO_DICTIONARY;

View File

@ -3806,6 +3806,19 @@ void LyXAction::init()
*/
{ LFUN_SPELLING_ADD_LOCAL, "spelling-add-local", Noop, Edit },
/*!
* \var lyx::FuncCode lyx::LFUN_SPELLING_REMOVE_LOCAL
* \li Action: Remove the word under the cursor from the document's local
* spell checker dictionary.
* The default for the language is retrieved from the cursor position.
* \li Syntax: spelling-remove-local [<STRING>] [<LANG>]
* \li Params: <WORD>: word to remove
<LANG>: language name (see file languages)
* \li Origin: spitz, 7 Mar 2021
* \endvar
*/
{ LFUN_SPELLING_REMOVE_LOCAL, "spelling-remove-local", Noop, Edit },
/*!
* \var lyx::FuncCode lyx::LFUN_SPELLING_CONTINUOUSLY
* \li Action: Toggle continuous spell checking.

View File

@ -4961,11 +4961,11 @@ void Paragraph::Private::markMisspelledWords(
WordLangTuple const candidate(word.substr(wstart, wlen), lang);
SpellChecker::Result actresult = result;
if (inset_owner_->buffer().params().spellignored(candidate))
actresult = SpellChecker::WORD_OK;
actresult = SpellChecker::DOCUMENT_LEARNED_WORD;
numskipped += countSkips(it, et, snext);
/// mark the range of misspelling
setMisspelled(wstart, snext, actresult);
if (actresult == SpellChecker::WORD_OK)
if (actresult == SpellChecker::DOCUMENT_LEARNED_WORD)
LYXERR(Debug::GUI, "local dictionary word: \"" <<
candidate.word() << "\" [" <<
wstart << ".." << (snext-1) << "]");

View File

@ -44,6 +44,8 @@ public:
IGNORED_WORD,
/// number of personal dictionary "word"
LEARNED_WORD,
/// number of document dictionary "word"
DOCUMENT_LEARNED_WORD,
/// missing dictionary for language
NO_DICTIONARY
};
@ -57,7 +59,8 @@ public:
return res != WORD_OK
&& res != IGNORED_WORD
&& res != NO_DICTIONARY
&& res != LEARNED_WORD; }
&& res != LEARNED_WORD
&& res != DOCUMENT_LEARNED_WORD; }
/// check the given word of the given lang code and return the result
virtual enum Result check(WordLangTuple const &,

View File

@ -2745,8 +2745,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
}
}
WordLangTuple wl(word, language);
bool const has_item = bv->buffer().params().spellignored(wl);
if (!has_item) {
if (!bv->buffer().params().spellignored(wl)) {
cur.recordUndoBufferParams();
bv->buffer().params().spellignore().push_back(wl);
cur.recordUndo();
@ -2761,6 +2760,45 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
break;
}
case LFUN_SPELLING_REMOVE_LOCAL: {
Language const * language = getLanguage(cur, cmd.getArg(1));
docstring word = from_utf8(cmd.getArg(0));
if (word.empty()) {
word = cur.selectionAsString(false);
if (word.size() > 100)
break;
if (word.empty()) {
// Get word or selection
selectWordWhenUnderCursor(cur, WHOLE_WORD);
word = cur.selectionAsString(false);
}
}
WordLangTuple wl(word, language);
bool has_item = false;
vector<WordLangTuple>::const_iterator it = bv->buffer().params().spellignore().begin();
for (; it != bv->buffer().params().spellignore().end(); ++it) {
if (it->lang()->code() != wl.lang()->code())
continue;
if (it->word() == wl.word()) {
has_item = true;
break;
}
}
if (has_item) {
cur.recordUndoBufferParams();
bv->buffer().params().spellignore().erase(it);
cur.recordUndo();
// trigger re-check
WordLangTuple wl;
docstring_list suggestions;
Paragraph const & par = cur.paragraph();
pos_type from = cur.pos();
pos_type to = from;
par.spellCheck(from, to, wl, suggestions, true, true);
}
break;
}
case LFUN_SPELLING_IGNORE: {
Language const * language = getLanguage(cur, cmd.getArg(1));
@ -3492,6 +3530,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
case LFUN_SPELLING_ADD:
case LFUN_SPELLING_ADD_LOCAL:
case LFUN_SPELLING_REMOVE_LOCAL:
case LFUN_SPELLING_IGNORE:
case LFUN_SPELLING_REMOVE:
enable = theSpellChecker() != nullptr;

View File

@ -878,6 +878,13 @@ void MenuDefinition::expandSpellingSuggestions(BufferView const * bv)
FuncRequest(LFUN_SPELLING_REMOVE, arg)));
}
break;
case SpellChecker::DOCUMENT_LEARNED_WORD: {
LYXERR(Debug::GUI, "Document-Learned Word.");
docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
add(MenuItem(MenuItem::Command, qt_("Remove from document dictionary|r"),
FuncRequest(LFUN_SPELLING_REMOVE_LOCAL, arg)));
}
break;
case SpellChecker::NO_DICTIONARY:
LYXERR(Debug::GUI, "No dictionary for language " + from_ascii(wl.lang()->lang()));
// FALLTHROUGH