--- Begin Message ---
Package: icewm
Version: 1.3.8-2
Severity: wishlist
Tags: patch
Hi there,
added tab-completion to the "internal taskbar command line" in icewm.
Please apply this patch and send it upstream.
Cheers,
Axel
-- System Information:
Debian Release: 8.0
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)
Kernel: Linux 3.16.0-4-amd64 (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/lksh
Init: sysvinit (via /sbin/init)
Versions of packages icewm depends on:
ii icewm-common 1.3.8-2.0axel1
ii libc6 2.19-13
ii libesd0 0.2.41-11
ii libfontconfig1 2.11.0-6.3
ii libgcc1 1:4.9.2-10
ii libgdk-pixbuf2.0-0 2.31.1-2+b1
ii libglib2.0-0 2.42.1-1
ii libice6 2:1.0.9-1+b1
ii libsm6 2:1.2.2-1+b1
ii libx11-6 2:1.6.2-3
ii libxext6 2:1.3.3-1
ii libxft2 2.3.2-1
ii libxinerama1 2:1.1.3-1+b1
ii libxrandr2 2:1.4.2-1+b1
ii ttf-dejavu-core 2.34-1
icewm recommends no packages.
Versions of packages icewm suggests:
pn icewm-gnome-support <none>
-- no debconf information
diff -Nru icewm-1.3.8/debian/changelog icewm-1.3.8/debian/changelog
--- icewm-1.3.8/debian/changelog 2014-10-20 00:24:11.000000000 +0200
+++ icewm-1.3.8/debian/changelog 2014-12-30 16:09:39.000000000 +0100
@@ -1,3 +1,10 @@
+icewm (1.3.8-2.0axel1) UNRELEASED; urgency=medium
+
+ * Non-maintainer upload.
+ * added patch for tab-completion
+
+ -- Axel Dirla <[email protected]> Tue, 30 Dec 2014 16:07:40 +0100
+
icewm (1.3.8-2) unstable; urgency=medium
* Fix format buffer overflow in CPU tooltip rendering (closes: 765965)
diff -Nru icewm-1.3.8/debian/patches/complete icewm-1.3.8/debian/patches/complete
--- icewm-1.3.8/debian/patches/complete 1970-01-01 01:00:00.000000000 +0100
+++ icewm-1.3.8/debian/patches/complete 2014-12-30 16:16:25.000000000 +0100
@@ -0,0 +1,400 @@
+Author: Axel Dirla <[email protected]>, Thorsten “mirabilos” Glaser <[email protected]>
+Description: Tab-Completion for "internal taskbar command line"
+
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -63,6 +63,7 @@ libice_OBJS = ref.o \
+ libitk_OBJS = \
+ ymenu.o ylabel.o yscrollview.o \
+ ymenuitem.o yscrollbar.o ybutton.o ylistbox.o yinput.o \
++ globit.o \
+ yicon.o \
+ wmconfig.o # FIXME
+
+--- /dev/null
++++ b/src/globit.c
+@@ -0,0 +1,297 @@
++/*-
++ * Copyright © 2014
++ * Thorsten “mirabilos” Glaser <[email protected]>
++ *
++ * Provided that these terms and disclaimer and all copyright notices
++ * are retained or reproduced in an accompanying document, permission
++ * is granted to deal in this work without restriction, including un‐
++ * limited rights to use, publicly perform, distribute, sell, modify,
++ * merge, give away, or sublicence.
++ *
++ * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
++ * the utmost extent permitted by applicable law, neither express nor
++ * implied; without malicious intent or gross negligence. In no event
++ * may a licensor, author or contributor be held liable for indirect,
++ * direct, other damage, loss, or other issues arising in any way out
++ * of dealing in the work, even if advised of the possibility of such
++ * damage or existence of a defect, except proven that it results out
++ * of said person’s immediate fault when using the work as intended.
++ */
++
++#define _GNU_SOURCE
++#include <errno.h>
++#include <glob.h>
++#include <limits.h>
++#include <paths.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include "globit.h"
++
++/*
++ * globit_best – return the “best præfix” for a pattern, or the sole match
++ *
++ * Arguments:
++ * – [in] const char *pattern
++ * – [out] char **result
++ * Return value:
++ * – (int) number of matches
++ * + if -1: an error occurred; *result is the error string (or NULL)
++ * + if 0: *result is unchanged
++ * + if 1: *result contains the sole match
++ * + else: *result contains the longest common præfix
++ * In all cases where it is set, the caller has to free(*result) later.
++ */
++
++/* helper functions */
++
++#ifndef _PATH_DEFPATH
++#define _PATH_DEFPATH "/bin:/usr/bin:/sbin:/usr/sbin"
++#endif
++
++static char *
++globit_escape(const char *istr)
++{
++ char c, *cp, *ostr;
++ size_t i;
++
++ if (!(cp = ostr = calloc((i = strlen(istr)) + 1, 2)))
++ return (NULL);
++
++ /* strictly spoken, newline should be single-quoted instead */
++ while (i--) {
++ if (strchr("\t\n \"#$&'()*:;<=>?[\\`{|}", (c = *istr++)))
++ *cp++ = '\\';
++ *cp++ = c;
++ }
++ *cp = '\0';
++
++ return (ostr);
++}
++
++static int
++globit_pfxlen(char **words, int nwords)
++{
++ int j, prefix_len;
++ char *p;
++ int i;
++
++ prefix_len = strlen(words[0]);
++ for (i = 1; i < nwords; i++)
++ for (j = 0, p = words[i]; j < prefix_len; j++)
++ if (p[j] != words[0][j]) {
++ prefix_len = j;
++ break;
++ }
++ return (prefix_len);
++}
++
++/* main function */
++
++int
++globit_best(const char *pattern_, char **result)
++{
++ char c, *cp, **results = NULL;
++ size_t z, nresults = 0;
++ int i;
++ int glob_flags = GLOB_MARK |
++#ifdef GLOB_NO_DOTDIRS
++ GLOB_NO_DOTDIRS |
++#endif
++ GLOB_NOSORT;
++ int is_absolute = 0;
++ char *pattern, *pf = NULL, *pp = NULL, *pathpfx = NULL, *pathstr = NULL;
++ size_t pathlen = 0;
++ glob_t glob_block;
++ const char *errstr = NULL;
++
++ /* initialise pattern, with ‘*’ appended unless it already has magic */
++ if (!(pattern = malloc((z = strlen(pattern_)) + 2))) {
++ *result = strdup("not enough memory");
++ return (-1);
++ }
++ memcpy(pattern, pattern_, z);
++ if (glob_pattern_p(pattern_, 1) == 0)
++ pattern[z++] = '*';
++ pattern[z] = '\0';
++ cp = pattern;
++
++ /* check if pattern is absolute */
++ if (*pattern == '/') {
++ /* yes, pathname */
++ is_absolute = 1;
++ } else if (*pattern == '~') {
++ /* yes, tilde */
++ is_absolute = 2;
++ glob_flags |= GLOB_TILDE;
++ /* any slash in the pattern? */
++ while (*cp && *cp != '/')
++ ++cp;
++ if (!*cp) {
++ /* no, so don’t append ‘*’ */
++ memcpy(pattern, pattern_, z + 1);
++ }
++ cp = pattern;
++ /* TODO: keep tilde unexpanded in return value (hard) */
++ } else {
++ /* no, get $PATH */
++ cp = getenv("PATH");
++ pp = pathstr = strdup(cp && *cp ? cp : _PATH_DEFPATH);
++ glob_repeatedly:
++ /* get one path element */
++ cp = pp;
++ while ((c = *cp) && c != ':')
++ ++cp;
++ *cp = '\0';
++ free(pathpfx);
++ pathpfx = strdup(cp == pp ? "." : pp);
++ *cp = c;
++ /* advance path præfix */
++ pp = cp;
++ if (c)
++ ++pp;
++ /* construct pattern for this round */
++ pathlen = strlen(pathpfx) + 1;
++ if (!(cp = globit_escape(pathpfx)))
++ goto oom;
++ free(pathpfx);
++ pathpfx = cp;
++ if (asprintf(&cp, "%s/%s", pathpfx, pattern) == -1) {
++ errstr = "could not compose path";
++ goto errout;
++ }
++ free(pf);
++ pf = cp;
++ }
++
++ /* collect (one round of) glob results */
++ memset(&glob_block, '\0', sizeof(glob_block));
++ switch (glob(cp, glob_flags, NULL, &glob_block)) {
++ case 0:
++ /* success */
++ if ((i = glob_block.gl_pathc) < 0) {
++ globfree(&glob_block);
++ errstr = "negative result set size";
++ goto errout;
++ }
++ break;
++ case GLOB_NOMATCH:
++ /* or close enough */
++ i = 0;
++ break;
++ case GLOB_NOSPACE:
++ errstr = "not enough space for glob";
++ if (0)
++ /* FALLTHROUGH */
++ case GLOB_ABORTED:
++ errstr = "glob was aborted due to an error";
++ if (0)
++ /* FALLTHROUGH */
++ case GLOB_NOSYS:
++ errstr = "glob library does not support requested function";
++ if (0)
++ /* FALLTHROUGH */
++ default:
++ errstr = "unknown glob error";
++ globfree(&glob_block);
++ goto errout;
++ }
++
++ /* if we have only one round, work directly on the results */
++ if (is_absolute) {
++ switch (i) {
++ case 0:
++ break;
++ case 1:
++ *result = globit_escape(glob_block.gl_pathv[0]);
++ break;
++ default:
++ z = globit_pfxlen(glob_block.gl_pathv, i);
++ if (z == 0) {
++ i = 0;
++ break;
++ }
++ if (!(cp = strdup(glob_block.gl_pathv[0])))
++ goto oom;
++ cp[z] = '\0';
++ *result = globit_escape(cp);
++ free(cp);
++ break;
++ }
++ globfree(&glob_block);
++ ok_out:
++ if (i && !*result)
++ goto oom;
++ free(pf);
++ free(pathpfx);
++ free(pathstr);
++ free(pattern);
++ return (i);
++ }
++
++ /* otherwise, post-process the results */
++ if (i) {
++ int j = 0;
++ char **r2;
++
++ if (((size_t)i > ((size_t)INT_MAX - nresults)) ||
++ ((SIZE_MAX / sizeof(char *)) < (z = nresults + i))) {
++ errstr = "too many results";
++ goto errout;
++ }
++ if ((r2 = realloc(results, z * sizeof(char *))) == NULL) {
++ oom:
++ errstr = "not enough memory";
++ goto errout;
++ }
++ results = r2;
++ while (j < i) {
++ cp = glob_block.gl_pathv[j++];
++ if (strlen(cp) >= pathlen)
++ cp += pathlen;
++ results[nresults++] = strdup(cp);
++ }
++ }
++
++ /* next round */
++ globfree(&glob_block);
++ if (*pp)
++ goto glob_repeatedly;
++
++ /* operate on the postprocessed results */
++ switch ((i = (int)nresults)) {
++ case 0:
++ goto ok_out;
++ default:
++ z = globit_pfxlen(results, i);
++ if (z == 0) {
++ i = 0;
++ goto ok_out;
++ }
++ results[0][z] = '\0';
++ /* FALLTHROUGH */
++ case 1:
++ *result = globit_escape(results[0]);
++ break;
++ }
++
++ while (nresults--)
++ free(results[nresults]);
++ free(results);
++ goto ok_out;
++
++ errout:
++ if (results) {
++ while (nresults--)
++ free(results[nresults]);
++ free(results);
++ }
++ free(pf);
++ free(pathpfx);
++ free(pathstr);
++ free(pattern);
++ *result = errstr ? strdup(errstr) : NULL;
++ return (-1);
++}
+--- /dev/null
++++ b/src/globit.h
+@@ -0,0 +1,14 @@
++#ifndef GLOBIT_H
++#define GLOBIT_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++extern int globit_best(const char *, char **);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* GLOBIT_H */
+--- a/src/yinput.cc
++++ b/src/yinput.cc
+@@ -4,6 +4,7 @@
+ * Copyright (C) 1997-2001 Marko Macek
+ */
+ #include "config.h"
++#include "globit.h"
+
+ #ifndef LITE
+ #include "ykey.h"
+@@ -15,6 +16,7 @@
+ #include "prefs.h"
+
+ #include <string.h>
++#include <stdlib.h>
+
+ #include "intl.h"
+
+@@ -206,6 +208,10 @@ bool YInputLine::handleKey(const XKeyEve
+ case XK_KP_Insert:
+ copySelection();
+ return true;
++ case 'i':
++ case 'I':
++ complete();
++ return true;
+ }
+ }
+ if (m & ShiftMask) {
+@@ -300,6 +306,7 @@ bool YInputLine::handleKey(const XKeyEve
+ }
+ break;
+ case XK_Tab:
++ complete();
+ break;
+ default:
+ {
+@@ -714,4 +721,22 @@ void YInputLine::autoScroll(int delta, c
+ fAutoScrollDelta = delta;
+ beginAutoScroll(delta ? true : false, motion);
+ }
++
++void YInputLine::complete() {
++ char *res;
++ int res_count;
++ cstring t(fText);
++
++ res_count = globit_best(t.c_str(), &res);
++ if (res_count == -1) { //error-case
++ free(res);
++ return;
++ }
++ if (res_count == 0) { //no match found
++ return;
++ }
++ setText(ustring(res, strlen(res)));
++ free(res);
++}
++
+ #endif
+--- a/src/yinputline.h
++++ b/src/yinputline.h
+@@ -42,6 +42,7 @@ public:
+ void unselectAll();
+ void cutSelection();
+ void copySelection();
++ void complete();
+
+ private:
+ ustring fText;
diff -Nru icewm-1.3.8/debian/patches/series icewm-1.3.8/debian/patches/series
--- icewm-1.3.8/debian/patches/series 2014-10-20 00:24:11.000000000 +0200
+++ icewm-1.3.8/debian/patches/series 2014-12-30 15:31:56.000000000 +0100
@@ -4,3 +4,4 @@
i18n_updates
ifstate_exact_check
format_buffer_overflow
+complete
--- End Message ---