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 160 161 162 163 164 165 166
|
#include "wordcompletion.h"
#include <wx/xrc/xmlres.h>
#include "WordCompletionThread.h"
#include <wx/stc/stc.h>
#include "clKeyboardManager.h"
#include <wx/app.h>
#include "WordCompletionSettingsDlg.h"
#include "event_notifier.h"
#include "cl_command_event.h"
#include "wxCodeCompletionBoxManager.h"
#include "WordCompletionDictionary.h"
#include "lexer_configuration.h"
#include "ColoursAndFontsManager.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; }
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::OnWordComplete, this, XRCID("text_word_complete"));
wxTheApp->Bind(wxEVT_MENU, &WordCompletionPlugin::OnWordComplete, this, XRCID("word_complete_no_single_insert"));
wxTheApp->Bind(wxEVT_MENU, &WordCompletionPlugin::OnSettings, this, XRCID("text_word_complete_settings"));
m_dictionary = new WordCompletionDictionary();
clKeyboardManager::Get()->AddGlobalAccelerator(
"text_word_complete", "Ctrl-ENTER", "Plugins::Word Completion::Show word completion");
}
WordCompletionPlugin::~WordCompletionPlugin() {}
clToolBar* WordCompletionPlugin::CreateToolBar(wxWindow* parent)
{
wxUnusedVar(parent);
clToolBar* tb(NULL);
return tb;
}
void WordCompletionPlugin::CreatePluginMenu(wxMenu* pluginsMenu)
{
wxMenu* menu = new wxMenu;
menu->Append(XRCID("text_word_complete"), _("Show Word Completion"));
menu->AppendSeparator();
menu->Append(XRCID("text_word_complete_settings"), _("Settings"));
pluginsMenu->Append(wxID_ANY, GetShortName(), menu);
}
void WordCompletionPlugin::UnPlug()
{
wxDELETE(m_dictionary);
wxTheApp->Unbind(wxEVT_MENU, &WordCompletionPlugin::OnWordComplete, this, XRCID("text_word_complete"));
wxTheApp->Unbind(wxEVT_MENU, &WordCompletionPlugin::OnWordComplete, this, XRCID("word_complete_no_single_insert"));
wxTheApp->Unbind(wxEVT_MENU, &WordCompletionPlugin::OnSettings, this, XRCID("text_word_complete_settings"));
}
void WordCompletionPlugin::OnWordComplete(wxCommandEvent& event)
{
event.Skip();
IEditor* activeEditor = m_mgr->GetActiveEditor();
CHECK_PTR_RET(activeEditor);
WordCompletionSettings settings;
settings.Load();
// Enabled?
if(!settings.IsEnabled()) return;
// Build the suggetsion list
wxString suggestString;
wxCodeCompletionBoxEntry::Vec_t entries;
wxCodeCompletionBox::BmpVec_t bitmaps;
bitmaps.push_back(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 = stc->GetTextRange(start, curPos);
wxString lcFilter = filter.Lower();
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;
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(lcFilter.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(lcFilter) && filter != word) {
filterdSet.insert(word);
}
} else {
if(lcWord.Contains(lcFilter) && filter != word) {
filterdSet.insert(word);
}
}
}
}
for(wxStringSet_t::iterator iter = filterdSet.begin(); iter != filterdSet.end(); ++iter) {
entries.push_back(wxCodeCompletionBoxEntry::New(*iter, 0));
}
wxCodeCompletionBoxManager::Get().ShowCompletionBox(activeEditor->GetCtrl(), entries, bitmaps,
event.GetId() == XRCID("text_word_complete") ? wxCodeCompletionBox::kInsertSingleMatch :
wxCodeCompletionBox::kNone,
wxNOT_FOUND);
}
void WordCompletionPlugin::OnSettings(wxCommandEvent& event)
{
WordCompletionSettingsDlg dlg(EventNotifier::Get()->TopFrame());
dlg.ShowModal();
}
|