Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

FS#420 FS#316 Rework tab trigger logic

  • Loading branch information...
commit 1eeb6d3407e6b77a7250241f18faf791df6be910 1 parent c55ee61
@vershov authored
View
60 src/EditorCtrl.cpp
@@ -1358,49 +1358,12 @@ void EditorCtrl::Tab() {
return;
}
+ unsigned int pos = GetPos();
if (m_macro.IsRecording()) m_macro.Add(wxT("Tab"));
// If the tab is preceded by a word it can trigger a snippet
- const unsigned int pos = GetPos();
- unsigned int wordstart = pos;
-
- // First check if we can get a trigger before first non-alnum char
- cxLOCKDOC_READ(m_doc)
- while (wordstart) {
- const unsigned int prevchar = doc.GetPrevCharPos(wordstart);
- const wxChar c = doc.GetChar(prevchar);
- if (!Isalnum(c)) break;
- wordstart = prevchar;
- }
- cxENDLOCK
- if (wordstart < pos && DoTabTrigger(wordstart, pos)) return;
-
- // If that did not give a trigger, try to first whitespace
- cxLOCKDOC_READ(m_doc)
- while (wordstart) {
- const unsigned int prevchar = doc.GetPrevCharPos(wordstart);
- const wxChar c = doc.GetChar(prevchar);
- if (wxIsspace(c)) break;
- wordstart = prevchar;
- }
- cxENDLOCK
- if (wordstart < pos) {
- if (DoTabTrigger(wordstart, pos)) return;
-
- // If we still don't have a trigger, check if we are in quotes or parans
- // (needed for the rare case when trigger is non-alnum)
- unsigned int qstart = pos;
- cxLOCKDOC_READ(m_doc)
- while (qstart > wordstart) {
- const unsigned int prevchar = doc.GetPrevCharPos(qstart);
- const wxChar c = doc.GetChar(prevchar);
- if (c == wxT('"') || c == wxT('\'') || c == wxT('(') || c == wxT('{') || c == wxT('[')) break;
- qstart = prevchar;
- }
- cxENDLOCK
- if (qstart < pos && qstart != wordstart && DoTabTrigger(qstart, pos)) return;
- }
-
+ if (DoTabTrigger(pos)) return;
+
// If we get to here we have to insert a real tab
if (!m_parentFrame.IsSoftTabs()) { // Hard Tab
InsertChar(wxChar('\t'));
@@ -1429,22 +1392,19 @@ void EditorCtrl::Tab() {
Insert(indent);
}
-bool EditorCtrl::DoTabTrigger(unsigned int wordstart, unsigned int wordend) {
- wxASSERT(wordstart < wordend && wordend <= m_lines.GetLength());
+bool EditorCtrl::DoTabTrigger(unsigned int pos) {
+ wxASSERT(pos <= m_lines.GetLength());
- wxString trigger;
+ wxString strPart; // part of the current line to check trigger actions
cxLOCKDOC_READ(m_doc)
- trigger = doc.GetTextPart(wordstart, wordend);
+ strPart = doc.GetTextPart(doc.GetLineStart(pos), pos);
cxENDLOCK
- const deque<const wxString*> scope = m_syntaxstyler.GetScope(wordend);
- const vector<const tmAction*> actions = m_syntaxHandler.GetActions(trigger, scope);
+ const deque<const wxString*> scope = m_syntaxstyler.GetScope(pos);
+ const vector<const tmAction*> actions = m_syntaxHandler.GetActions(strPart, scope);
if (actions.empty()) return false; // no action found for trigger
- //wxLogDebug(wxT("%s (%u)"), trigger, snippets.size());
- //wxLogDebug(wxT("%s"), actions[0]->content);
-
// Present user with a list of actions
int actionIndex = 0;
if (actions.size() > 1) {
@@ -1460,7 +1420,7 @@ bool EditorCtrl::DoTabTrigger(unsigned int wordstart, unsigned int wordend) {
// Remove the trigger
Freeze();
- RawDelete(wordstart, wordend);
+ RawDelete(pos - actions[actionIndex]->trigger.Len(), pos);
// Do the Action
DoAction(*actions[actionIndex], NULL, true);
View
2  src/EditorCtrl.h
@@ -530,7 +530,7 @@ class EditorCtrl : public KeyHookable<wxControl>,
int ShowPopupList(wxMenu& menu);
void Tab();
- bool DoTabTrigger(unsigned int wordstart, unsigned int wordend);
+ bool DoTabTrigger(unsigned int pos);
void DeleteSelections();
void InsertOverSelections(const wxString& text);
View
27 src/tm_syntaxhandler.cpp
@@ -29,6 +29,8 @@
#include "IAppPaths.h"
#include "IEditorDoAction.h"
+bool Isalnum(wxChar c); // defined in EditorCtrl.cpp
+
// tinyxml includes unused vars so it can't compile with Level 4
#ifdef __WXMSW__
#pragma warning(push, 1)
@@ -298,7 +300,7 @@ void TmSyntaxHandler::ClearBundleActions() {
m_actions.clear();
// Release allocated triggers
- for (map<const wxString, sNode<tmAction>*>::iterator t = m_actionTriggers.begin(); t != m_actionTriggers.end(); ++t) {
+ for (Triggers::iterator t = m_actionTriggers.begin(); t != m_actionTriggers.end(); ++t) {
delete t->second;
}
m_actionTriggers.clear();
@@ -742,15 +744,24 @@ void TmSyntaxHandler::GetDragActions(const deque<const wxString*>& scopes, vecto
m_dragNode.GetMatches(scopes, result, matchfun);
}
-const vector<const tmAction*> TmSyntaxHandler::GetActions(const wxString& trigger, const deque<const wxString*>& scopes) const {
- map<const wxString, sNode<tmAction>*>::const_iterator p = m_actionTriggers.find(trigger);
+const vector<const tmAction*> TmSyntaxHandler::GetActions(
+ const wxString& strPart, const deque<const wxString*>& scopes) const {
- if (p != m_actionTriggers.end()) {
- p->second->Print();
- const vector<const tmAction*>* s = (const vector<const tmAction*>*)p->second->GetMatch(scopes);
- if (s) return *s;
- }
+ Triggers::const_iterator p = m_actionTriggers.lower_bound(strPart);
+ wxString key = p->first;
+ while ((p != m_actionTriggers.end()) &&
+ ((key[key.Len() - 1] == strPart[strPart.Len() - 1]))) {
+ if (!strPart.EndsWith(key)) {
+ } else if ((key.Len() < strPart.Len()) && (Isalnum(key[0])) &&
+ (Isalnum(strPart[strPart.Len() - key.Len() - 1]))) {
+ } else {
+ const vector<const tmAction*>* s = (const vector<const tmAction*>*)p->second->GetMatch(scopes);
+ if (s) return *s;
+ }
+ ++p;
+ key = p->first;
+ }
return vector<const tmAction*>();
}
View
20 src/tm_syntaxhandler.h
@@ -191,6 +191,24 @@ template <class T> class sNode {
void Tokenize(const wxString& scope, wxArrayString& words) const;
};
+// Compare class for triggers
+class TriggerCompare {
+public:
+ bool operator()(const wxString& a, const wxString &b) {
+ size_t a_len = a.Len(), b_len = b.Len();
+ for (size_t i = 1; i <= a_len; i++) {
+ if (b_len < i) return true;
+ if (a[a_len - i] > b[b_len - i]) {
+ return false;
+ } else if (a[a_len - i] < b[b_len - i]) {
+ return true;
+ }
+ }
+ return false;
+ };
+};
+typedef std::map<const wxString, sNode<tmAction>*, class TriggerCompare> Triggers;
+
class TmSyntaxHandler:
public ITmThemeHandler,
public ITmLoadBundles,
@@ -368,7 +386,7 @@ class TmSyntaxHandler:
sNode<tmAction> m_actionNode;
sNode<tmDragCommand> m_dragNode;
std::map<const wxString, tmAction*> m_actions;
- std::map<const wxString, sNode<tmAction>*> m_actionTriggers;
+ Triggers m_actionTriggers;
std::map<unsigned int, wxString> m_menuActions;
wxMenu* m_bundleMenu;
unsigned int m_nextMenuID;
Please sign in to comment.
Something went wrong with that request. Please try again.