From cb65dae95fb3bd01cb4e43286ba2a56c41838d2e Mon Sep 17 00:00:00 2001
From: simonb <simonb>
Date: Tue, 25 Apr 2006 02:42:05 +0000
Subject: fbrun: Move the cursor to the end when tab completing + thanks Jonas
 Koelker, sf.net rfe #1333003, patch #1475578

---
 ChangeLog           |  3 +++
 util/fbrun/FbRun.cc | 33 +++++++++++++++++++++++----------
 util/fbrun/FbRun.hh |  1 +
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bbb74c6..86ee946 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 (Format: Year/Month/Day)
 Changes for 0.9.16:
 *06/04/25:
+   * fbrun: Move the cursor to the end when tab completing
+     (Simon + thanks Jonas Koelker), sf.net rfe #1333003, patch #1475578
+     util/fbrun/FbRun.hh/cc
    * Fix up comments for doxygen (Thanks Jonas Koelker)
      Screen.cc CommandParser.cc Container.hh fluxbox.hh Workspace.hh 
      ArrowButton.hh FbTk/Texture.cc FbTk/ThemeItems.cc FbTk/Texture.hh 
diff --git a/util/fbrun/FbRun.cc b/util/fbrun/FbRun.cc
index 41c7474..7392083 100644
--- a/util/fbrun/FbRun.cc
+++ b/util/fbrun/FbRun.cc
@@ -64,6 +64,7 @@ FbRun::FbRun(int x, int y, size_t width):
     m_gc(*this),
     m_end(false),
     m_current_history_item(0),
+    m_last_completion_prefix(""),
     m_current_apps_item(0),
     m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)) {
     
@@ -222,10 +223,11 @@ void FbRun::redrawLabel() {
 }
 
 void FbRun::keyPressEvent(XKeyEvent &ke) {
-    
+    // reset last completion prefix if we don't do a tab completion thing
+    bool did_tab_complete = false;
+
     ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state);
 
-    int cp= cursorPosition();
     FbTk::TextBox::keyPressEvent(ke);
     KeySym ks;
     char keychar[1];
@@ -238,22 +240,26 @@ void FbRun::keyPressEvent(XKeyEvent &ke) {
         if ((ke.state & ControlMask) == ControlMask) {
             switch (ks) {
             case XK_p:
+                did_tab_complete = true;
                 prevHistoryItem();
                 break;
             case XK_n:
+                did_tab_complete = true;
                 nextHistoryItem();
                 break;
             case XK_Tab:
+                did_tab_complete = true;
                 tabCompleteHistory();
-                setCursorPosition(cp);
                 break;
             }
         } else if ((ke.state & (Mod1Mask|ShiftMask)) == (Mod1Mask | ShiftMask)) {
             switch (ks) {
             case XK_less:
+                did_tab_complete = true;
                 firstHistoryItem();
                 break;
             case XK_greater:
+                did_tab_complete = true;
                 lastHistoryItem();
                 break;
             }
@@ -276,12 +282,14 @@ void FbRun::keyPressEvent(XKeyEvent &ke) {
             nextHistoryItem();
             break;
         case XK_Tab:
+            did_tab_complete = true;
             tabCompleteApps();
-            setCursorPosition(cp);
             break;
         }
     }
     clear();
+    if (!did_tab_complete)
+        m_last_completion_prefix = "";
 }
 
 void FbRun::lockPosition(bool size_too) {
@@ -347,11 +355,14 @@ void FbRun::tabCompleteHistory() {
     } else {
         unsigned int nr= 0;
         unsigned int history_item = m_current_history_item - 1;
-        string prefix = text().substr(0, textStartPos() + cursorPosition());
+        if (m_last_completion_prefix.empty())
+            m_last_completion_prefix = text().substr(0, textStartPos() + cursorPosition());
+
         while (history_item != m_current_history_item && nr++ < m_history.size()) {
-            if (m_history[history_item].find(prefix) == 0) {
+            if (m_history[history_item].find(m_last_completion_prefix) == 0) {
                 m_current_history_item = history_item;
                 setText(m_history[m_current_history_item]);
+                cursorEnd();
                 break;
             }
             if (history_item == 0) // loop
@@ -365,15 +376,16 @@ void FbRun::tabCompleteHistory() {
 void FbRun::tabCompleteApps() {
   
     static bool first_run= true;
-    static string saved_prefix= "";
-    string prefix= text().substr(0, textStartPos() + cursorPosition());
+    if (m_last_completion_prefix.empty())
+        m_last_completion_prefix = text().substr(0, textStartPos() + cursorPosition());
+    string prefix = m_last_completion_prefix;
     FbTk::Directory dir;
 
     bool add_dirs= false;
     bool changed_prefix= false;
 
     // (re)build m_apps-container
-    if (first_run || saved_prefix != prefix) {
+    if (first_run || m_last_completion_prefix != prefix) {
         first_run= false;
         
         string path;
@@ -430,7 +442,7 @@ void FbRun::tabCompleteApps() {
         sort(m_apps.begin(), m_apps.end());
         unique(m_apps.begin(), m_apps.end());
 
-        saved_prefix= prefix;
+        m_last_completion_prefix = prefix;
         changed_prefix= true;
         m_current_apps_item= 0;
     }
@@ -456,6 +468,7 @@ void FbRun::tabCompleteApps() {
                     setText(m_apps[m_current_apps_item] +  "/");
                 else
                     setText(m_apps[m_current_apps_item]);
+                cursorEnd();
                 break;
             }
             apps_item++;
diff --git a/util/fbrun/FbRun.hh b/util/fbrun/FbRun.hh
index f34f691..9d2705e 100644
--- a/util/fbrun/FbRun.hh
+++ b/util/fbrun/FbRun.hh
@@ -93,6 +93,7 @@ private:
     std::vector<std::string> m_history; ///< history list of commands
     std::string m_history_file; ///< holds filename for command history file
     size_t m_current_history_item; ///< holds current position in command history
+    std::string m_last_completion_prefix; ///< last prefix we completed on
     
     typedef std::vector<std::string> AppsContainer;
     typedef AppsContainer::iterator AppsContainerIt;
-- 
cgit v0.11.2