Skip to content

Commit 0ef41c4

Browse files
committed
支持拼写检查
1 parent 749fd89 commit 0ef41c4

File tree

18 files changed

+590
-146
lines changed

18 files changed

+590
-146
lines changed

CodeFormat/src/LuaFormat.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ bool LuaFormat::Check(std::string_view workspace, std::shared_ptr<CodeSpellCheck
147147
_parser->BuildAstWithComment();
148148

149149
std::string_view inputFile = _inputFile;
150-
if(!workspace.empty())
150+
if (!workspace.empty())
151151
{
152152
inputFile = StringUtil::GetFileRelativePath(workspace, inputFile);
153153
}
@@ -186,8 +186,10 @@ bool LuaFormat::Check(std::string_view workspace, std::shared_ptr<CodeSpellCheck
186186
NameStyleChecker styleChecker(ctx);
187187
styleChecker.Analysis();
188188
}
189-
190-
spellChecker->Analysis(ctx);
189+
if (spellChecker)
190+
{
191+
spellChecker->Analysis(ctx);
192+
}
191193

192194
auto diagnosis = ctx.GetDiagnosisInfos();
193195
if (!diagnosis.empty())
@@ -210,7 +212,8 @@ bool LuaFormat::Check(std::string_view workspace, std::shared_ptr<CodeSpellCheck
210212
return true;
211213
}
212214

213-
void LuaFormat::DiagnosisInspection(std::string_view message, TextRange range, std::shared_ptr<LuaFile> file, std::string_view path)
215+
void LuaFormat::DiagnosisInspection(std::string_view message, TextRange range, std::shared_ptr<LuaFile> file,
216+
std::string_view path)
214217
{
215218
std::string_view source = file->GetSource();
216219
auto startLine = file->GetLine(range.StartOffset);

CodeFormatLib/src/CodeFormatLib.cpp

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ std::string GetDiagnosisString(DiagnosisType type)
4242
case DiagnosisType::EndWithNewLine: return "EndWithNewLine";
4343
case DiagnosisType::NameStyle: return "NameStyle";
4444
case DiagnosisType::StatementLineSpace: return "StatementLineSpace";
45+
case DiagnosisType::Spell: return "Spell";
4546
}
4647
return "";
4748
}
@@ -360,12 +361,233 @@ int set_default_config(lua_State* L)
360361
return 0;
361362
}
362363

364+
int spell_load_dictionary_from_path(lua_State* L)
365+
{
366+
int top = lua_gettop(L);
367+
368+
if (top != 1)
369+
{
370+
return 0;
371+
}
372+
373+
if (lua_isstring(L, 1))
374+
{
375+
try
376+
{
377+
auto path = lua_tostring(L, 1);
378+
LuaCodeFormat::GetInstance().LoadSpellDictionary(path);
379+
380+
lua_pushboolean(L, true);
381+
return 1;
382+
}
383+
catch (std::exception& e)
384+
{
385+
std::string err = e.what();
386+
lua_settop(L, top);
387+
lua_pushboolean(L, false);
388+
lua_pushlstring(L, err.c_str(), err.size());
389+
return 2;
390+
}
391+
}
392+
393+
return 0;
394+
}
395+
396+
397+
int spell_load_dictionary_from_buffer(lua_State* L)
398+
{
399+
int top = lua_gettop(L);
400+
401+
if (top != 1)
402+
{
403+
return 0;
404+
}
405+
406+
if (lua_isstring(L, 1))
407+
{
408+
try
409+
{
410+
auto dictionary = lua_tostring(L, 1);
411+
LuaCodeFormat::GetInstance().LoadSpellDictionaryFromBuffer(dictionary);
412+
413+
lua_pushboolean(L, true);
414+
return 1;
415+
}
416+
catch (std::exception& e)
417+
{
418+
std::string err = e.what();
419+
lua_settop(L, top);
420+
lua_pushboolean(L, false);
421+
lua_pushlstring(L, err.c_str(), err.size());
422+
return 2;
423+
}
424+
}
425+
426+
return 0;
427+
}
428+
429+
int spell_analysis(lua_State* L)
430+
{
431+
int top = lua_gettop(L);
432+
433+
if (top < 2)
434+
{
435+
return 0;
436+
}
437+
438+
if (lua_isstring(L, 1) && lua_isstring(L, 2))
439+
{
440+
try
441+
{
442+
std::string filename = lua_tostring(L, 1);
443+
std::string text = lua_tostring(L, 2);
444+
auto diagnosticInfos = LuaCodeFormat::GetInstance().SpellCheck(filename, std::move(text));
445+
446+
lua_pushboolean(L, true);
447+
int count = 1;
448+
lua_newtable(L);
449+
for (auto& diagnosticInfo : diagnosticInfos)
450+
{
451+
// 诊断信息表
452+
lua_newtable(L);
453+
454+
//message
455+
{
456+
lua_pushstring(L, "message");
457+
lua_pushlstring(L, diagnosticInfo.Message.c_str(), diagnosticInfo.Message.size());
458+
lua_rawset(L, -3);
459+
460+
lua_pushstring(L, "type");
461+
lua_pushstring(L, GetDiagnosisString(diagnosticInfo.type).c_str());
462+
lua_rawset(L, -3);
463+
464+
lua_pushstring(L, "data");
465+
lua_pushstring(L, diagnosticInfo.Data.c_str());
466+
lua_rawset(L, -3);
467+
}
468+
469+
// range
470+
{
471+
lua_pushstring(L, "range");
472+
//range table
473+
lua_newtable(L);
474+
475+
lua_pushstring(L, "start");
476+
// start table
477+
lua_newtable(L);
478+
lua_pushstring(L, "line");
479+
lua_pushinteger(L, diagnosticInfo.Range.Start.Line);
480+
lua_rawset(L, -3);
481+
482+
lua_pushstring(L, "character");
483+
lua_pushinteger(L, diagnosticInfo.Range.Start.Character);
484+
lua_rawset(L, -3);
485+
486+
lua_rawset(L, -3); // set start = {}
487+
488+
lua_pushstring(L, "end");
489+
// end table
490+
lua_newtable(L);
491+
lua_pushstring(L, "line");
492+
lua_pushinteger(L, diagnosticInfo.Range.End.Line);
493+
lua_rawset(L, -3);
494+
495+
lua_pushstring(L, "character");
496+
lua_pushinteger(L, diagnosticInfo.Range.End.Character);
497+
lua_rawset(L, -3);
498+
499+
lua_rawset(L, -3); // set end = {}
500+
501+
lua_rawset(L, -3); // set range = {}
502+
}
503+
504+
// 不确认lua会不会把他改成宏,所以不要在这里用++count
505+
lua_rawseti(L, -2, count);
506+
count++;
507+
}
508+
509+
return 2;
510+
}
511+
catch (std::exception& e)
512+
{
513+
std::string err = e.what();
514+
lua_settop(L, top);
515+
lua_pushboolean(L, false);
516+
lua_pushlstring(L, err.c_str(), err.size());
517+
return 2;
518+
}
519+
}
520+
return 0;
521+
}
522+
523+
int spell_suggest(lua_State* L)
524+
{
525+
int top = lua_gettop(L);
526+
527+
if (top != 1)
528+
{
529+
return 0;
530+
}
531+
532+
if (lua_isstring(L, 1))
533+
{
534+
try
535+
{
536+
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+
550+
auto suggests = LuaCodeFormat::GetInstance().SpellCorrect(word);
551+
int count = 1;
552+
lua_newtable(L);
553+
for (auto& suggest : suggests)
554+
{
555+
if (!suggest.Term.empty())
556+
{
557+
if (upperFirst)
558+
{
559+
suggest.Term[0] = ::toupper(suggest.Term[0]);
560+
}
561+
lua_pushstring(L, suggest.Term.c_str());
562+
lua_rawseti(L, -2, count);
563+
count++;
564+
}
565+
}
566+
567+
return 2;
568+
}
569+
catch (std::exception& e)
570+
{
571+
std::string err = e.what();
572+
lua_settop(L, top);
573+
lua_pushboolean(L, false);
574+
lua_pushlstring(L, err.c_str(), err.size());
575+
return 2;
576+
}
577+
}
578+
return 0;
579+
}
580+
363581
static const luaL_Reg lib[] = {
364582
{"format", format},
365583
{"range_format", range_format},
366584
{"update_config", update_config},
367585
{"diagnose_file", diagnose_file},
368586
{"set_default_config", set_default_config},
587+
{"spell_load_dictionary_from_path", spell_load_dictionary_from_path},
588+
{"spell_load_dictionary_from_buffer", spell_load_dictionary_from_buffer},
589+
{"spell_analysis", spell_analysis},
590+
{"spell_suggest", spell_suggest},
369591
{nullptr, nullptr}
370592
};
371593

CodeFormatLib/src/LuaCodeFormat.cpp

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ LuaCodeFormat& LuaCodeFormat::GetInstance()
1313
}
1414

1515
LuaCodeFormat::LuaCodeFormat()
16-
: _defaultOptions(std::make_shared<LuaCodeStyleOptions>())
16+
: _defaultOptions(std::make_shared<LuaCodeStyleOptions>()),
17+
_codeSpellChecker(std::make_shared<CodeSpellChecker>())
1718
{
1819
}
1920

@@ -62,6 +63,16 @@ void LuaCodeFormat::SetDefaultCodeStyle(ConfigMap& configMap)
6263
}
6364
}
6465

66+
void LuaCodeFormat::LoadSpellDictionary(const std::string& path)
67+
{
68+
_codeSpellChecker->LoadDictionary(path);
69+
}
70+
71+
void LuaCodeFormat::LoadSpellDictionaryFromBuffer(const std::string& buffer)
72+
{
73+
_codeSpellChecker->LoadDictionaryFromBuffer(buffer);
74+
}
75+
6576
std::string LuaCodeFormat::Reformat(const std::string& uri, std::string&& text, ConfigMap& configMap)
6677
{
6778
auto parser = LuaParser::LoadFromBuffer(std::move(text));
@@ -122,6 +133,24 @@ std::pair<bool, std::vector<LuaDiagnosisInfo>> LuaCodeFormat::Diagnose(const std
122133
return std::make_pair(true, ctx.GetDiagnosisInfos());
123134
}
124135

136+
std::vector<LuaDiagnosisInfo> LuaCodeFormat::SpellCheck(const std::string& uri, std::string&& text)
137+
{
138+
auto parser = LuaParser::LoadFromBuffer(std::move(text));
139+
140+
auto options = GetOptions(uri);
141+
142+
DiagnosisContext ctx(parser, *options);
143+
144+
_codeSpellChecker->Analysis(ctx);
145+
146+
return ctx.GetDiagnosisInfos();
147+
}
148+
149+
std::vector<SuggestItem> LuaCodeFormat::SpellCorrect(const std::string& word)
150+
{
151+
return _codeSpellChecker->GetSuggests(word);
152+
}
153+
125154
std::shared_ptr<LuaCodeStyleOptions> LuaCodeFormat::GetOptions(const std::string& uri)
126155
{
127156
std::size_t matchLength = 0;
@@ -152,20 +181,20 @@ LuaCodeStyleOptions LuaCodeFormat::CalculateOptions(const std::string& uri, Conf
152181
if (configMap.count("insertSpaces"))
153182
{
154183
tempOptions.indent_style = configMap.at("insertSpaces") == "true"
155-
? IndentStyle::Space
156-
: IndentStyle::Tab;
184+
? IndentStyle::Space
185+
: IndentStyle::Tab;
157186
}
158187
if (configMap.count("tabSize"))
159188
{
160-
if (tempOptions.indent_style == IndentStyle::Tab) {
189+
if (tempOptions.indent_style == IndentStyle::Tab)
190+
{
161191
tempOptions.tab_width = std::stoi(configMap.at("tabSize"));
162192
}
163-
else if(tempOptions.indent_style == IndentStyle::Space)
193+
else if (tempOptions.indent_style == IndentStyle::Space)
164194
{
165195
tempOptions.indent_size = std::stoi(configMap.at("tabSize"));
166196
}
167197
}
168198
return tempOptions;
169199
}
170-
171200
}

CodeFormatLib/src/LuaCodeFormat.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "CodeService/Diagnosis/LuaDiagnosisInfo.h"
99
#include "CodeService/LuaEditorConfig.h"
1010
#include "CodeService/LuaFormatRange.h"
11+
#include "CodeService/Spell/CodeSpellChecker.h"
1112

1213
class LuaCodeFormat
1314
{
@@ -21,17 +22,27 @@ class LuaCodeFormat
2122
void RemoveCodeStyle(const std::string& workspaceUri);
2223
void SetDefaultCodeStyle(ConfigMap& configMap);
2324

25+
void LoadSpellDictionary(const std::string& path);
26+
27+
void LoadSpellDictionaryFromBuffer(const std::string& buffer);
28+
2429
std::string Reformat(const std::string& uri, std::string&& text,ConfigMap& configMap);
2530

2631
std::string RangeFormat(const std::string& uri, LuaFormatRange& range, std::string&& text, ConfigMap& configMap);
2732

2833
std::pair<bool, std::vector<LuaDiagnosisInfo>> Diagnose(const std::string& uri, std::string&& text);
2934

35+
std::vector<LuaDiagnosisInfo> SpellCheck(const std::string& uri, std::string&& text);
36+
37+
std::vector<SuggestItem> SpellCorrect(const std::string& word);
38+
3039
std::shared_ptr<LuaCodeStyleOptions> GetOptions(const std::string& uri);
3140

3241
LuaCodeStyleOptions CalculateOptions(const std::string& uri, ConfigMap& configMap);
3342
private:
3443
std::vector<std::pair<std::string, std::shared_ptr<LuaEditorConfig>>> _editorConfigVector;
3544

3645
std::shared_ptr<LuaCodeStyleOptions> _defaultOptions;
46+
47+
std::shared_ptr<CodeSpellChecker> _codeSpellChecker;
3748
};

0 commit comments

Comments
 (0)