1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#include "ColoursAndFontsManager.h"
#include "WordCompletionDictionary.h"
#include "WordCompletionSettingsDlg.h"
#include "WordCompletionThread.h"
#include "clKeyboardManager.h"
#include "cl_command_event.h"
#include "event_notifier.h"
#include "lexer_configuration.h"
#include "wordcompletion.h"
#include "wxCodeCompletionBoxManager.h"
#include <wx/app.h>
#include <wx/stc/stc.h>
#include <wx/xrc/xmlres.h>
static WordCompletionPlugin* thePlugin = NULL;
// Define the plugin entry point
CL_PLUGIN_API IPlugin* CreatePlugin(IManager* manager)
{
if(thePlugin == 0) { thePlugin = new WordCompletionPlugin(manager); }
return thePlugin;
}
CL_PLUGIN_API PluginInfo* GetPluginInfo()
{
static PluginInfo info;
info.SetAuthor(wxT("Eran Ifrah"));
info.SetName(wxT("Word Completion"));
info.SetDescription(_("Suggest completion based on words typed in the editors"));
info.SetVersion(wxT("v1.0"));
return &info;
}
CL_PLUGIN_API int GetPluginInterfaceVersion() { return PLUGIN_INTERFACE_VERSION; }
// Helper
WordCompleter::WordCompleter(WordCompletionPlugin* plugin)
: ServiceProvider("Words", eServiceType::kCodeCompletion)
, m_plugin(plugin)
{
SetPriority(20);
Bind(wxEVT_CC_WORD_COMPLETE, &WordCompleter::OnWordComplete, this);
}
WordCompleter::~WordCompleter()
{
Unbind(wxEVT_CC_WORD_COMPLETE, &WordCompleter::OnWordComplete, this);
}
void WordCompleter::OnWordComplete(clCodeCompletionEvent& event) { m_plugin->OnWordComplete(event); }
WordCompletionPlugin::WordCompletionPlugin(IManager* manager)
: IPlugin(manager)
{
m_longName = _("Suggest completion based on words typed in the editor");
m_shortName = wxT("Word Completion");
wxTheApp->Bind(wxEVT_MENU, &WordCompletionPlugin::OnSettings, this, XRCID("text_word_complete_settings"));
m_dictionary = new WordCompletionDictionary();
m_completer = new WordCompleter(this);
}
WordCompletionPlugin::~WordCompletionPlugin() {}
void WordCompletionPlugin::CreateToolBar(clToolBar* toolbar) { wxUnusedVar(toolbar); }
void WordCompletionPlugin::CreatePluginMenu(wxMenu* pluginsMenu)
{
wxMenu* menu = new wxMenu;
menu->Append(XRCID("text_word_complete_settings"), _("Settings"));
pluginsMenu->Append(wxID_ANY, GetShortName(), menu);
}
void WordCompletionPlugin::UnPlug()
{
wxDELETE(m_dictionary);
wxDELETE(m_completer);
wxTheApp->Unbind(wxEVT_MENU, &WordCompletionPlugin::OnSettings, this, XRCID("text_word_complete_settings"));
}
void WordCompletionPlugin::OnWordComplete(clCodeCompletionEvent& event)
{
event.Skip(); // Always skip this
IEditor* activeEditor = dynamic_cast<IEditor*>(event.GetEditor());
CHECK_PTR_RET(activeEditor);
WordCompletionSettings settings;
settings.Load();
// Enabled?
if(!settings.IsEnabled()) { return; }
// Build the suggetsion list
static wxBitmap sBmp = wxNullBitmap;
if(!sBmp.IsOk()) { sBmp = m_mgr->GetStdIcons()->LoadBitmap("word"); }
// Filter (what the user has typed so far)
// wxStyledTextCtrl* stc = activeEditor->GetCtrl();
// int curPos = stc->GetCurrentPos();
// int start = stc->WordStartPosition(stc->GetCurrentPos(), true);
// if(curPos < start) return;
wxString filter = event.GetWord().Lower(); // stc->GetTextRange(start, curPos);
wxStringSet_t words = m_dictionary->GetWords();
// Parse the current bufer (if modified), to include non saved words
if(activeEditor->IsModified()) {
// For performance (this parsing is done in the main thread)
// only parse the visible area of the document
wxStringSet_t unsavedBufferWords;
wxStyledTextCtrl* stc = activeEditor->GetCtrl();
int startPos = stc->PositionFromLine(stc->GetFirstVisibleLine());
int endPos = stc->GetCurrentPos();
wxString buffer = stc->GetTextRange(startPos, endPos);
WordCompletionThread::ParseBuffer(buffer, unsavedBufferWords);
// Merge the results
words.insert(unsavedBufferWords.begin(), unsavedBufferWords.end());
}
// Get the editor keywords and add them
LexerConf::Ptr_t lexer = ColoursAndFontsManager::Get().GetLexerForFile(activeEditor->GetFileName().GetFullName());
if(lexer) {
wxString keywords;
for(size_t i = 0; i < wxSTC_KEYWORDSET_MAX; ++i) {
keywords << lexer->GetKeyWords(i) << " ";
}
wxArrayString langWords = ::wxStringTokenize(keywords, "\n\t \r", wxTOKEN_STRTOK);
words.insert(langWords.begin(), langWords.end());
}
wxStringSet_t filterdSet;
if(filter.IsEmpty()) {
filterdSet.swap(words);
} else {
for(wxStringSet_t::iterator iter = words.begin(); iter != words.end(); ++iter) {
wxString word = *iter;
wxString lcWord = word.Lower();
if(settings.GetComparisonMethod() == WordCompletionSettings::kComparisonStartsWith) {
if(lcWord.StartsWith(filter) && filter != word) { filterdSet.insert(word); }
} else {
if(lcWord.Contains(filter) && filter != word) { filterdSet.insert(word); }
}
}
}
wxCodeCompletionBoxEntry::Vec_t entries;
for(wxStringSet_t::iterator iter = filterdSet.begin(); iter != filterdSet.end(); ++iter) {
entries.push_back(wxCodeCompletionBoxEntry::New(*iter, sBmp));
}
event.GetEntries().insert(event.GetEntries().end(), entries.begin(), entries.end());
}
void WordCompletionPlugin::OnSettings(wxCommandEvent& event)
{
WordCompletionSettingsDlg dlg(EventNotifier::Get()->TopFrame());
dlg.ShowModal();
}
|