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 <axel.di...@arcor.de>  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 <axel.di...@arcor.de>, Thorsten “mirabilos” Glaser <t.gla...@tarent.de>
+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 <t.gla...@tarent.de>
++ *
++ * 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

Reply via email to