ALT Linux repos
S: | 3.4.2-alt1 |
5.0: | 1.2.36-alt2.1 |
4.1: | 1.2.35-alt2.1 |
4.0: | 1.2.32-alt2.1 |
3.0: | 1.2.23-alt1 |
+backports: | 1.2.30-alt1.M30.1 |
Group :: Graphical desktop/Icewm
RPM: icewm
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: icewm-alt-readline.patch
Download
Download
icewm/configure.in | 16 ++++
icewm/src/aaddressbar.cc | 173 ++++++++++++++++++++++++++++++++++++++++++++++
icewm/src/config.h.in | 3 +
icewm/src/yinput.cc | 2 +-
4 files changed, 193 insertions(+), 1 deletions(-)
diff --git a/icewm/configure.in b/icewm/configure.in
index 58f248e..6a9ea8e 100644
--- a/icewm/configure.in
+++ b/icewm/configure.in
@@ -482,6 +482,22 @@ AC_ARG_ENABLE(xfreetype,
features="${features} corefonts"
fi
+dnl =================================================== Support for readline ===
+dnl
+AC_ARG_ENABLE(readline,
+ [ --with-readline Enable readline & history support])
+ if test "$with_readline" != "no"; then
+ AC_CHECK_LIB(history, using_history,
+ CORE_LIBS="${CORE_LIBS} -lhistory -lreadline"
+ features="${features} readline"
+ [ AC_DEFINE(HAVE_READLINE, 1, [Enable readline & history support]) ],
+ [ AC_MSG_ERROR([Unable to find history library])])
+ AC_CHECK_LIB(ncurses, copywin,
+ CORE_LIBS="${CORE_LIBS} -lncurses"
+ [ ],
+ [ AC_MSG_ERROR([Unable to find ncurses library])])
+ fi
+
dnl ============================================================= GUI Events ===
dnl
AC_ARG_ENABLE(guievents,
diff --git a/icewm/src/aaddressbar.cc b/icewm/src/aaddressbar.cc
index 31c5e83..1767031 100644
--- a/icewm/src/aaddressbar.cc
+++ b/icewm/src/aaddressbar.cc
@@ -15,8 +15,144 @@
#include "sysdep.h"
#include "default.h"
+#ifdef HAVE_READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+
+char *extract_colon_unit (char *string, int *p_index)
+{
+ int i, start, len;
+ char *value = NULL;
+
+ if (string == 0)
+ return (string);
+
+ len = strlen (string);
+ if (*p_index >= len)
+ return ((char *)NULL);
+
+ i = *p_index;
+
+ if (i && string[i] == ':')
+ i++;
+
+ for (start = i; string[i] && string[i] != ':'; i++)
+ ;
+
+ *p_index = i;
+
+ if (i == start)
+ {
+ if (string[i])
+ (*p_index)++;
+ /* Return "" in the case of a trailing `:'. */
+ value = new char[1];
+ value[0] = '\0';
+ }
+ else
+ {
+ int len = i-start;
+ value = new char[len+1];
+ strncpy(value, string+start,len);
+ value[len] = '\0';
+ }
+
+ return (value);
+}
+
+char *find_completion(const char *text,int *state) {
+ char *path = getenv("PATH");
+ char *current_path;
+ char **matches = NULL;
+ char *filename = NULL;
+ char *found = NULL;
+ int path_index, text_len = strlen(text), found_len = 0, path_len = 0;
+ struct stat st;
+
+ *state = 0;
+ path_index = 0;
+ if (text[0] != '/' && text[0] != '~') {
+ while (path && path[path_index]) {
+ current_path = extract_colon_unit(path, &path_index);
+ if (current_path && *current_path) {
+ filename = new char[2+strlen(current_path)+text_len];
+ sprintf(filename,"%s/%s",current_path,text);
+ path_len = strlen(current_path)+1;
+ free(current_path);
+ matches = rl_completion_matches(filename, rl_filename_completion_function);
+ if (matches) {
+ //if (!matches[1]) {
+ char *f = *matches+path_len;
+ int len = strlen(f);
+ if (len < found_len) {
+ free(found);
+ found = strdup(f);
+ found_len = len;
+ *state = 3;
+ } else if (*state) {
+ *state = 2;
+ if (found) {
+ free(found);
+ found = NULL;
+ }
+ } else {
+ found = strdup(*matches+path_len);
+ found_len = strlen(found);
+ if (matches[1])
+ *state = 3;
+ else
+ *state = 1;
+ }
+ //} else {
+ // *state = 2;
+ // }
+ }
+ if (*state == 2)
+ return NULL;
+ }
+ }
+ } else {
+ const char *wtilde = NULL;
+ int len = -1;
+ if (text[0] == '~') {
+ wtilde = text;
+ text = tilde_expand(text);
+ len = strlen(text);
+ }
+ matches = rl_completion_matches(text, rl_filename_completion_function);
+ if (matches) {
+ stat(*matches,&st);
+ if (len > 0) {
+ *matches += len;
+ len = text_len+strlen(*matches);
+ found = new char[len+2];
+ if (S_ISDIR(st.st_mode) && !matches[1]) {
+ sprintf(found,"%s%s/",wtilde,*matches);
+ } else {
+ sprintf(found,"%s%s",wtilde,*matches);
+ }
+ } else {
+ if (S_ISDIR(st.st_mode) && !matches[1]) {
+ found = new char[strlen(*matches)+2];
+ sprintf(found,"%s/",*matches);
+ } else {
+ found = strdup(*matches);
+ }
+ }
+ if (matches[1])
+ *state = 3;
+ else
+ *state = 1;
+ }
+ }
+ return found;
+}
+#endif /* HAVE_READLINE */
AddressBar::AddressBar(YWindow *parent): YInputLine(parent) {
+#ifdef HAVE_READLINE
+ using_history();
+#endif
}
AddressBar::~AddressBar() {
@@ -27,7 +163,41 @@ bool AddressBar::handleKey(const XKeyEvent &key) {
KeySym k = XKeycodeToKeysym(xapp->display(), (KeyCode)key.keycode, 0);
int m = KEY_MODMASK(key.state);
+#ifdef HAVE_READLINE
+ if (k == XK_Tab) {
+ int state=0, p;
+ char *f;
+ char *text = strdup(getText());
+ p = prevWord(strlen(text), false);
+ text += p;
+ f = find_completion(text,&state);
+ if (state & 1) {
+ char *t = f;
+ if (p != 0) {
+ t = new char[strlen(f)+p+2];
+ *text = '\0';
+ text -= p;
+ sprintf(t,"%s%s",text,f);
+ free(text);
+ free(f);
+ }
+ setText(t);
+ free(t);
+ }
+ if (!state || state & 2)
+ ; // printf("\a\n");
+ return true; // for future compatibility
+ } else if (k == XK_Up || k == XK_Down) {
+ HIST_ENTRY *hist;
+ hist = k == XK_Down ? next_history() : previous_history();
+ if (hist == NULL)
+ return true;
+ setText(hist->line);
+ return true;
+ } else if (k == XK_KP_Enter || k == XK_Return) {
+#else
if (k == XK_KP_Enter || k == XK_Return) {
+#endif
const char *t = getText();
const char *args[7];
int i = 0;
@@ -50,6 +220,9 @@ bool AddressBar::handleKey(const XKeyEvent &key) {
if (m & ControlMask)
if (t == 0 || t[0] == 0)
args[1] = 0;
+#ifdef HAVE_READLINE
+ add_history((char *)t);
+#endif
app->runProgram(args[0], args);
selectAll();
return true;
diff --git a/icewm/src/config.h.in b/icewm/src/config.h.in
index ce58d3a..5c1f553 100644
--- a/icewm/src/config.h.in
+++ b/icewm/src/config.h.in
@@ -351,5 +351,8 @@
/* Define to 1 if the X Window System is missing or not being used. */
#undef X_DISPLAY_MISSING
+/* Define to 1 if the readline (address bar history) support used. */
+#undef HAVE_READLINE
+
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
diff --git a/icewm/src/yinput.cc b/icewm/src/yinput.cc
index 3647241..6e81368 100644
--- a/icewm/src/yinput.cc
+++ b/icewm/src/yinput.cc
@@ -84,7 +84,7 @@ void YInputLine::setText(const char *text) {
fText = newstr(text);
markPos = curPos = leftOfs = 0;
if (fText)
- curPos = strlen(fText);
+ markPos = curPos = strlen(fText);
limit();
repaint();
}