diff options
author | fluxgen <fluxgen> | 2004-04-18 14:16:09 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2004-04-18 14:16:09 (GMT) |
commit | facca1f6f998630af008fffe59ed1af116596609 (patch) | |
tree | 7a352d824c40e9b67dac1c6a93875837afce52f5 | |
parent | c81cec51a97eae53622c94c9bfe8e23f9a7716c1 (diff) | |
download | fluxbox_pavel-facca1f6f998630af008fffe59ed1af116596609.zip fluxbox_pavel-facca1f6f998630af008fffe59ed1af116596609.tar.bz2 |
tab complete on all apps in PATH, patch from Mathias Gumz
-rw-r--r-- | util/fbrun/FbRun.cc | 72 | ||||
-rw-r--r-- | util/fbrun/FbRun.hh | 11 |
2 files changed, 79 insertions, 4 deletions
diff --git a/util/fbrun/FbRun.cc b/util/fbrun/FbRun.cc index e32e101..360adf5 100644 --- a/util/fbrun/FbRun.cc +++ b/util/fbrun/FbRun.cc | |||
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: FbRun.cc,v 1.25 2004/02/28 10:43:20 fluxgen Exp $ | 22 | // $Id: FbRun.cc,v 1.26 2004/04/18 14:16:09 fluxgen Exp $ |
23 | 23 | ||
24 | #include "FbRun.hh" | 24 | #include "FbRun.hh" |
25 | 25 | ||
@@ -42,11 +42,15 @@ | |||
42 | #include <X11/Xutil.h> | 42 | #include <X11/Xutil.h> |
43 | #include <X11/cursorfont.h> | 43 | #include <X11/cursorfont.h> |
44 | 44 | ||
45 | #include <sys/types.h> | ||
46 | #include <sys/stat.h> | ||
47 | #include <dirent.h> | ||
45 | #include <unistd.h> | 48 | #include <unistd.h> |
46 | 49 | ||
47 | #include <iostream> | 50 | #include <iostream> |
48 | #include <iterator> | 51 | #include <iterator> |
49 | #include <fstream> | 52 | #include <fstream> |
53 | #include <algorithm> | ||
50 | #include <cassert> | 54 | #include <cassert> |
51 | 55 | ||
52 | using namespace std; | 56 | using namespace std; |
@@ -59,6 +63,7 @@ FbRun::FbRun(int x, int y, size_t width): | |||
59 | m_gc(*this), | 63 | m_gc(*this), |
60 | m_end(false), | 64 | m_end(false), |
61 | m_current_history_item(0), | 65 | m_current_history_item(0), |
66 | m_current_apps_item(0), | ||
62 | m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)) { | 67 | m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)) { |
63 | 68 | ||
64 | setGC(m_gc.gc()); | 69 | setGC(m_gc.gc()); |
@@ -96,6 +101,44 @@ FbRun::FbRun(int x, int y, size_t width): | |||
96 | wmhints.icon_pixmap = m_pixmap.drawable(); | 101 | wmhints.icon_pixmap = m_pixmap.drawable(); |
97 | XSetWMHints(m_display, window(), &wmhints); | 102 | XSetWMHints(m_display, window(), &wmhints); |
98 | } | 103 | } |
104 | |||
105 | |||
106 | string path= getenv("PATH"); | ||
107 | |||
108 | unsigned int l; | ||
109 | unsigned int r; | ||
110 | |||
111 | for(l= 0, r= 0; r < path.size(); r++) { | ||
112 | if (path[r]==':' && r - l > 0) { | ||
113 | struct dirent** namelist; | ||
114 | struct stat buf; | ||
115 | int n; | ||
116 | |||
117 | string dir= path.substr(l, r - l); | ||
118 | n= scandir(dir.c_str(), &namelist, 0, alphasort); | ||
119 | if (n >= 0) { | ||
120 | while(n--) { | ||
121 | if (!stat((dir + "/" + namelist[n]->d_name).c_str(), &buf) | ||
122 | && S_ISREG(buf.st_mode) && | ||
123 | (buf.st_mode & S_IXUSR | ||
124 | || buf.st_mode & S_IXGRP | ||
125 | || buf.st_mode & S_IXOTH)) { | ||
126 | m_apps.push_back(namelist[n]->d_name); | ||
127 | } | ||
128 | free(namelist[n]); | ||
129 | } | ||
130 | free(namelist); | ||
131 | } | ||
132 | l= r + 1; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | sort(m_apps.begin(), m_apps.end()); | ||
137 | unique(m_apps.begin(), m_apps.end()); | ||
138 | reverse(m_apps.begin(), m_apps.end()); | ||
139 | |||
140 | if (!m_apps.empty()) | ||
141 | m_current_apps_item= 1; | ||
99 | } | 142 | } |
100 | 143 | ||
101 | 144 | ||
@@ -225,6 +268,10 @@ void FbRun::keyPressEvent(XKeyEvent &ke) { | |||
225 | case XK_n: | 268 | case XK_n: |
226 | nextHistoryItem(); | 269 | nextHistoryItem(); |
227 | break; | 270 | break; |
271 | case XK_Tab: | ||
272 | tabCompleteHistory(); | ||
273 | setCursorPosition(cp); | ||
274 | break; | ||
228 | } | 275 | } |
229 | } else if (ke.state == (Mod1Mask | ShiftMask)) { | 276 | } else if (ke.state == (Mod1Mask | ShiftMask)) { |
230 | switch (ks) { | 277 | switch (ks) { |
@@ -253,7 +300,7 @@ void FbRun::keyPressEvent(XKeyEvent &ke) { | |||
253 | nextHistoryItem(); | 300 | nextHistoryItem(); |
254 | break; | 301 | break; |
255 | case XK_Tab: | 302 | case XK_Tab: |
256 | tabCompleteHistory(); | 303 | tabCompleteApps(); |
257 | setCursorPosition(cp); | 304 | setCursorPosition(cp); |
258 | break; | 305 | break; |
259 | } | 306 | } |
@@ -334,6 +381,27 @@ void FbRun::tabCompleteHistory() { | |||
334 | } | 381 | } |
335 | } | 382 | } |
336 | 383 | ||
384 | void FbRun::tabCompleteApps() { | ||
385 | if ( m_current_apps_item == 0 || m_apps.empty() ) { | ||
386 | XBell(m_display, 0); | ||
387 | } else { | ||
388 | unsigned int nr= 0; | ||
389 | int apps_item = m_current_apps_item - 1; | ||
390 | string prefix = text().substr(0, cursorPosition()); | ||
391 | while (apps_item != m_current_apps_item && nr++ < m_apps.size()) { | ||
392 | if (apps_item <= -1 ) | ||
393 | apps_item= m_apps.size() - 1; | ||
394 | if (m_apps[apps_item].find(prefix) == 0) { | ||
395 | m_current_apps_item = apps_item; | ||
396 | setText(m_apps[m_current_apps_item]); | ||
397 | break; | ||
398 | } | ||
399 | apps_item--; | ||
400 | } | ||
401 | if (apps_item == m_current_apps_item) XBell(m_display, 0); | ||
402 | } | ||
403 | } | ||
404 | |||
337 | void FbRun::insertCharacter(char keychar) { | 405 | void FbRun::insertCharacter(char keychar) { |
338 | char val[2] = {keychar, 0}; | 406 | char val[2] = {keychar, 0}; |
339 | insertText(val); | 407 | insertText(val); |
diff --git a/util/fbrun/FbRun.hh b/util/fbrun/FbRun.hh index 7856bdd..f287a5b 100644 --- a/util/fbrun/FbRun.hh +++ b/util/fbrun/FbRun.hh | |||
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: FbRun.hh,v 1.14 2003/08/27 14:04:12 fluxgen Exp $ | 22 | // $Id: FbRun.hh,v 1.15 2004/04/18 14:16:09 fluxgen Exp $ |
23 | 23 | ||
24 | #ifndef FBRUN_HH | 24 | #ifndef FBRUN_HH |
25 | #define FBRUN_HH | 25 | #define FBRUN_HH |
@@ -82,6 +82,7 @@ private: | |||
82 | void firstHistoryItem(); | 82 | void firstHistoryItem(); |
83 | void lastHistoryItem(); | 83 | void lastHistoryItem(); |
84 | void tabCompleteHistory(); | 84 | void tabCompleteHistory(); |
85 | void tabCompleteApps(); | ||
85 | 86 | ||
86 | FbTk::Font m_font; ///< font used to draw command text | 87 | FbTk::Font m_font; ///< font used to draw command text |
87 | Display *m_display; ///< display connection | 88 | Display *m_display; ///< display connection |
@@ -89,8 +90,14 @@ private: | |||
89 | FbTk::GContext m_gc; ///< graphic context | 90 | FbTk::GContext m_gc; ///< graphic context |
90 | bool m_end; ///< marks when this object is done | 91 | bool m_end; ///< marks when this object is done |
91 | std::vector<std::string> m_history; ///< history list of commands | 92 | std::vector<std::string> m_history; ///< history list of commands |
92 | size_t m_current_history_item; ///< holds current position in command history | ||
93 | std::string m_history_file; ///< holds filename for command history file | 93 | std::string m_history_file; ///< holds filename for command history file |
94 | size_t m_current_history_item; ///< holds current position in command history | ||
95 | |||
96 | typedef std::vector<std::string> AppsContainer; | ||
97 | typedef AppsContainer::iterator AppsContainerIt; | ||
98 | AppsContainer m_apps; ///< holds all apps in $PATH | ||
99 | size_t m_current_apps_item; ///< holds current position in apps-history | ||
100 | |||
94 | Cursor m_cursor; | 101 | Cursor m_cursor; |
95 | 102 | ||
96 | FbTk::FbPixmap m_pixmap; | 103 | FbTk::FbPixmap m_pixmap; |