@@ -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+
363581static 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
0 commit comments