Skip to content

Commit fd56252

Browse files
committed
拼写效果优化,支持大写的拼写检查
1 parent 31714b1 commit fd56252

File tree

8 files changed

+147
-46
lines changed

8 files changed

+147
-46
lines changed

CodeFormatLib/src/CodeFormatLib.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -534,30 +534,13 @@ int spell_suggest(lua_State* L)
534534
try
535535
{
536536
std::string word = lua_tostring(L, 1);
537-
538-
std::string letterWord = word;
539-
for (auto& c : letterWord)
540-
{
541-
c = ::tolower(c);
542-
}
543-
bool upperFirst = false;
544-
if (std::isupper(word.front()))
545-
{
546-
upperFirst = true;
547-
}
548-
lua_pushboolean(L, true);
549-
550537
auto suggests = LuaCodeFormat::GetInstance().SpellCorrect(word);
551538
int count = 1;
552539
lua_newtable(L);
553540
for (auto& suggest : suggests)
554541
{
555542
if (!suggest.Term.empty())
556543
{
557-
if (upperFirst)
558-
{
559-
suggest.Term[0] = ::toupper(suggest.Term[0]);
560-
}
561544
lua_pushstring(L, suggest.Term.c_str());
562545
lua_rawseti(L, -2, count);
563546
count++;

CodeFormatLib/src/LuaCodeFormat.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,30 @@ std::vector<LuaDiagnosisInfo> LuaCodeFormat::SpellCheck(const std::string& uri,
148148

149149
std::vector<SuggestItem> LuaCodeFormat::SpellCorrect(const std::string& word)
150150
{
151-
return _codeSpellChecker->GetSuggests(word);
151+
std::string letterWord = word;
152+
for (auto& c : letterWord)
153+
{
154+
c = std::tolower(c);
155+
}
156+
bool upperFirst = false;
157+
if (std::isupper(word.front()))
158+
{
159+
upperFirst = true;
160+
}
161+
162+
auto suggests = _codeSpellChecker->GetSuggests(letterWord);
163+
164+
for (auto& suggest : suggests)
165+
{
166+
if (!suggest.Term.empty())
167+
{
168+
if (upperFirst)
169+
{
170+
suggest.Term[0] = std::toupper(suggest.Term[0]);
171+
}
172+
}
173+
}
174+
return suggests;
152175
}
153176

154177
std::shared_ptr<LuaCodeStyleOptions> LuaCodeFormat::GetOptions(const std::string& uri)

CodeFormatServer/src/Service/CodeFormatService.cpp

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,27 +100,12 @@ void CodeFormatService::MakeSpellActions(std::shared_ptr<vscode::CodeActionResul
100100
return;
101101
}
102102

103-
auto letterWord = originText;
104-
for (auto& c : letterWord)
105-
{
106-
c = ::tolower(c);
107-
}
108-
bool upperFirst = false;
109-
if(std::isupper(originText.front()))
110-
{
111-
upperFirst = true;
112-
}
113-
114-
auto suggests = _spellChecker->GetSuggests(letterWord);
103+
auto suggests = _spellChecker->GetSuggests(originText);
115104
for (auto& suggest : suggests)
116105
{
117106
if (!suggest.Term.empty()) {
118107
auto& action = result->actions.emplace_back();
119-
auto term = suggest.Term;
120-
if(upperFirst)
121-
{
122-
term[0] = std::toupper(term[0]);
123-
}
108+
auto& term = suggest.Term;
124109

125110
action.title = term;
126111
action.command.title = term;

CodeService/src/FormatElement/DiagnosisContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,4 @@ std::vector<LuaDiagnosisInfo> DiagnosisContext::GetDiagnosisInfos()
5353
PushDiagnosis(LText("The code must end with a new line"), start, end, DiagnosisType::EndWithNewLine);
5454
}
5555
return _diagnosisInfos;
56-
}
56+
}

CodeService/src/Spell/CodeSpellChecker.cpp

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void CodeSpellChecker::LoadDictionary(std::string_view path)
1919

2020
void CodeSpellChecker::LoadDictionaryFromBuffer(std::string_view buffer)
2121
{
22-
_symSpell->LoadWordDictionaryFromBuffer(buffer);
22+
_symSpell->LoadWordDictionaryFromBuffer(buffer);
2323
}
2424

2525
void CodeSpellChecker::Analysis(DiagnosisContext& ctx)
@@ -36,9 +36,118 @@ void CodeSpellChecker::Analysis(DiagnosisContext& ctx)
3636
}
3737
}
3838

39-
std::vector<SuggestItem> CodeSpellChecker::GetSuggests(const std::string& word)
39+
std::vector<SuggestItem> CodeSpellChecker::GetSuggests(std::string word)
4040
{
41-
return _symSpell->LookUp(word);
41+
enum class ParseState
42+
{
43+
Unknown,
44+
FirstUpper,
45+
AllUpper,
46+
Lower,
47+
} state = ParseState::Unknown;
48+
49+
std::vector<SuggestItem> suggests;
50+
51+
for (std::size_t i = 0; i != word.size(); i++)
52+
{
53+
char& c = word[i];
54+
if (c < 0 || !std::isalpha(c))
55+
{
56+
return suggests;
57+
}
58+
59+
switch (state)
60+
{
61+
case ParseState::Unknown:
62+
{
63+
if (std::isupper(c))
64+
{
65+
state = ParseState::AllUpper;
66+
c = static_cast<char>(std::tolower(c));
67+
}
68+
else // lower
69+
{
70+
state = ParseState::Lower;
71+
}
72+
73+
break;
74+
}
75+
case ParseState::AllUpper:
76+
{
77+
if (std::islower(c))
78+
{
79+
if (i == 1)
80+
{
81+
state = ParseState::FirstUpper;
82+
}
83+
else
84+
{
85+
return suggests;
86+
}
87+
}
88+
c = static_cast<char>(std::tolower(c));
89+
break;
90+
}
91+
case ParseState::FirstUpper:
92+
{
93+
if (!std::islower(c))
94+
{
95+
return suggests;
96+
}
97+
break;
98+
}
99+
case ParseState::Lower:
100+
{
101+
if (std::isupper(c))
102+
{
103+
return suggests;
104+
}
105+
break;
106+
}
107+
}
108+
}
109+
110+
if (state == ParseState::Unknown)
111+
{
112+
return suggests;
113+
}
114+
115+
suggests = _symSpell->LookUp(word);
116+
117+
switch (state)
118+
{
119+
case ParseState::FirstUpper:
120+
{
121+
for (auto& suggest : suggests)
122+
{
123+
if (!suggest.Term.empty())
124+
{
125+
suggest.Term[0] = std::toupper(suggest.Term[0]);
126+
}
127+
}
128+
break;
129+
}
130+
case ParseState::AllUpper:
131+
{
132+
for (auto& suggest : suggests)
133+
{
134+
if (!suggest.Term.empty())
135+
{
136+
for (auto& ch : suggest.Term)
137+
{
138+
ch = std::toupper(ch);
139+
}
140+
}
141+
}
142+
break;
143+
}
144+
default:
145+
{
146+
break;
147+
}
148+
}
149+
150+
return suggests;
42151
}
43152

44153
void CodeSpellChecker::IdentifyAnalysis(DiagnosisContext& ctx, LuaToken& token)
@@ -54,7 +163,7 @@ void CodeSpellChecker::IdentifyAnalysis(DiagnosisContext& ctx, LuaToken& token)
54163
{
55164
parser = std::make_shared<IdentifyParser>(token.Text);
56165
parser->Parse();
57-
_caches.insert({ text, parser });
166+
_caches.insert({text, parser});
58167
}
59168

60169
auto& words = parser->GetWords();

CodeService/src/Spell/IdentifyParser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void IdentifyParser::Parse()
2929
start = _currentIndex;
3030
break;
3131
}
32-
case IdentifyType::LowerEnd:
32+
case IdentifyType::AsciiEnd:
3333
{
3434
WordRange range(start, _source.size() - start);
3535
PushWords(range);
@@ -72,9 +72,9 @@ IdentifyParser::IdentifyType IdentifyParser::Lex()
7272

7373
if (ch == EOZ)
7474
{
75-
if(state == ParseState::LowerCase)
75+
if(state == ParseState::LowerCase || state == ParseState::UpperCase)
7676
{
77-
return IdentifyType::LowerEnd;
77+
return IdentifyType::AsciiEnd;
7878
}
7979
return IdentifyType::End;
8080
}
@@ -145,7 +145,7 @@ IdentifyParser::IdentifyType IdentifyParser::Lex()
145145
--_currentIndex;
146146
}
147147

148-
return IdentifyType::Ignore;
148+
return IdentifyType::Ascii;
149149
}
150150
}
151151
++_currentIndex;

include/CodeService/Spell/CodeSpellChecker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class CodeSpellChecker
1818

1919
void Analysis(DiagnosisContext& ctx);
2020

21-
std::vector<SuggestItem> GetSuggests(const std::string& word);
21+
// copy once
22+
std::vector<SuggestItem> GetSuggests(std::string word);
2223
private:
2324
void IdentifyAnalysis(DiagnosisContext& ctx, LuaToken& token);
2425

include/CodeService/Spell/IdentifyParser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class IdentifyParser
1313
Ascii,
1414
Unicode,
1515
Ignore,
16-
LowerEnd,
16+
AsciiEnd,
1717
End,
1818
};
1919

0 commit comments

Comments
 (0)