removed TLast tag enum, now tags is simple defined as char *[] array, the rest is calculated correctly, rules take an int array for the tags
This commit is contained in:
		
							parent
							
								
									666b4563a0
								
							
						
					
					
						commit
						b35575574b
					
				
							
								
								
									
										4
									
								
								client.c
								
								
								
								
							
							
						
						
									
										4
									
								
								client.c
								
								
								
								
							| 
						 | 
				
			
			@ -16,7 +16,7 @@ resizetitle(Client *c)
 | 
			
		|||
	int i;
 | 
			
		||||
 | 
			
		||||
	c->tw = 0;
 | 
			
		||||
	for(i = 0; i < TLast; i++)
 | 
			
		||||
	for(i = 0; i < ntags; i++)
 | 
			
		||||
		if(c->tags[i])
 | 
			
		||||
			c->tw += textw(tags[i]);
 | 
			
		||||
	c->tw += textw(c->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -211,6 +211,7 @@ manage(Window w, XWindowAttributes *wa)
 | 
			
		|||
	XSetWindowAttributes twa;
 | 
			
		||||
 | 
			
		||||
	c = emallocz(sizeof(Client));
 | 
			
		||||
	c->tags = emallocz(ntags * sizeof(Bool));
 | 
			
		||||
	c->win = w;
 | 
			
		||||
	c->x = c->tx = wa->x;
 | 
			
		||||
	c->y = c->ty = wa->y;
 | 
			
		||||
| 
						 | 
				
			
			@ -429,6 +430,7 @@ unmanage(Client *c)
 | 
			
		|||
		if(!sel)
 | 
			
		||||
			sel = clients;
 | 
			
		||||
	}
 | 
			
		||||
	free(c->tags);
 | 
			
		||||
	free(c);
 | 
			
		||||
 | 
			
		||||
	XSync(dpy, False);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										50
									
								
								config.arg.h
								
								
								
								
							
							
						
						
									
										50
									
								
								config.arg.h
								
								
								
								
							| 
						 | 
				
			
			@ -3,18 +3,11 @@
 | 
			
		|||
 * See LICENSE file for license details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
enum { Tfnord, Tdev, Tnet, Twork, Tmisc, TLast };
 | 
			
		||||
#define TAGS \
 | 
			
		||||
const char *tags[TLast] = { \
 | 
			
		||||
	[Tfnord] = "fnord", \
 | 
			
		||||
	[Tdev] = "dev", \
 | 
			
		||||
	[Tnet] = "net", \
 | 
			
		||||
	[Twork] = "work", \
 | 
			
		||||
	[Tmisc] = "misc", \
 | 
			
		||||
};
 | 
			
		||||
const char *tags[] = { "fnord", "dev", "net", "work", "misc", NULL };
 | 
			
		||||
 | 
			
		||||
#define DEFMODE			dotile /* dofloat */
 | 
			
		||||
#define DEFTAG			Tdev
 | 
			
		||||
#define DEFTAG			1 /* index */
 | 
			
		||||
#define FONT			"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*"
 | 
			
		||||
#define BGCOLOR			"#0a2c2d"
 | 
			
		||||
#define FGCOLOR			"#ddeeee"
 | 
			
		||||
| 
						 | 
				
			
			@ -33,11 +26,11 @@ const char *tags[TLast] = { \
 | 
			
		|||
	const char *xlock[] = { "xlock", NULL }; \
 | 
			
		||||
static Key key[] = { \
 | 
			
		||||
	/* modifier		key		function	arguments */ \
 | 
			
		||||
	{ MODKEY,		XK_0,		view,		{ .i = Tfnord } }, \
 | 
			
		||||
	{ MODKEY,		XK_1,		view,		{ .i = Tdev } }, \
 | 
			
		||||
	{ MODKEY,		XK_2,		view,		{ .i = Tnet } }, \
 | 
			
		||||
	{ MODKEY,		XK_3,		view,		{ .i = Twork } }, \
 | 
			
		||||
	{ MODKEY,		XK_4,		view,		{ .i = Tmisc} }, \
 | 
			
		||||
	{ MODKEY,		XK_0,		view,		{ .i = 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_1,		view,		{ .i = 1 } }, \
 | 
			
		||||
	{ MODKEY,		XK_2,		view,		{ .i = 2 } }, \
 | 
			
		||||
	{ MODKEY,		XK_3,		view,		{ .i = 3 } }, \
 | 
			
		||||
	{ MODKEY,		XK_4,		view,		{ .i = 4 } }, \
 | 
			
		||||
	{ MODKEY,		XK_h,		viewprev,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_j,		focusnext,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_k,		focusprev,	{ 0 } }, \
 | 
			
		||||
| 
						 | 
				
			
			@ -45,16 +38,16 @@ static Key key[] = { \
 | 
			
		|||
	{ MODKEY,		XK_m,		togglemax,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_space,	togglemode,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_Return,	zoom,		{ 0 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_0,		appendtag,	{ .i = Tfnord } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_1,		appendtag,	{ .i = Tdev } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_2,		appendtag,	{ .i = Tnet } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_3,		appendtag,	{ .i = Twork } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_4,		appendtag,	{ .i = Tmisc } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_0,		replacetag,	{ .i = Tfnord } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_1,		replacetag,	{ .i = Tdev } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_2,		replacetag,	{ .i = Tnet } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_3,		replacetag,	{ .i = Twork } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_4,		replacetag,	{ .i = Tmisc } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_0,		appendtag,	{ .i = 0 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_1,		appendtag,	{ .i = 1 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_2,		appendtag,	{ .i = 2 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_3,		appendtag,	{ .i = 3 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_4,		appendtag,	{ .i = 4 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_0,		replacetag,	{ .i = 0 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_1,		replacetag,	{ .i = 1 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_2,		replacetag,	{ .i = 2 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_3,		replacetag,	{ .i = 3 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_4,		replacetag,	{ .i = 5 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_c,		killclient,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_q,		quit,		{ 0 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_Return,	spawn,		{ .argv = term } }, \
 | 
			
		||||
| 
						 | 
				
			
			@ -64,10 +57,11 @@ static Key key[] = { \
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
#define RULES \
 | 
			
		||||
	const unsigned int firefox[] = { 2 }; \
 | 
			
		||||
static Rule rule[] = { \
 | 
			
		||||
	/* class:instance	tags		isfloat */ \
 | 
			
		||||
	{ "Firefox.*",		{ [Tnet] = True },		False }, \
 | 
			
		||||
	{ "Gimp.*",		{ 0 },				True}, \
 | 
			
		||||
	{ "MPlayer.*",		{ 0 },				True}, \
 | 
			
		||||
	{ "Acroread.*",		{ 0 },				True}, \
 | 
			
		||||
	{ "Firefox.*",		firefox,	False }, \
 | 
			
		||||
	{ "Gimp.*",		NULL,		True}, \
 | 
			
		||||
	{ "MPlayer.*",		NULL,		True}, \
 | 
			
		||||
	{ "Acroread.*",		NULL,		True}, \
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,18 +3,11 @@
 | 
			
		|||
 * See LICENSE file for license details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
enum { Tfnord, Tdev, Tnet, Twork, Tmisc, TLast };
 | 
			
		||||
#define TAGS \
 | 
			
		||||
const char *tags[TLast] = { \
 | 
			
		||||
	[Tfnord] = "fnord", \
 | 
			
		||||
	[Tdev] = "dev", \
 | 
			
		||||
	[Tnet] = "net", \
 | 
			
		||||
	[Twork] = "work", \
 | 
			
		||||
	[Tmisc] = "misc", \
 | 
			
		||||
};
 | 
			
		||||
const char *tags[] = { "0", "1", "2", "3", "4", NULL };
 | 
			
		||||
 | 
			
		||||
#define DEFMODE			dotile /* dofloat */
 | 
			
		||||
#define DEFTAG			Tdev
 | 
			
		||||
#define DEFTAG			1 /* index */
 | 
			
		||||
#define FONT			"fixed"
 | 
			
		||||
#define BGCOLOR			"#666699"
 | 
			
		||||
#define FGCOLOR			"#eeeeee"
 | 
			
		||||
| 
						 | 
				
			
			@ -27,11 +20,11 @@ const char *tags[TLast] = { \
 | 
			
		|||
	const char *term[] = { "xterm", NULL }; \
 | 
			
		||||
static Key key[] = { \
 | 
			
		||||
	/* modifier		key		function	arguments */ \
 | 
			
		||||
	{ MODKEY,		XK_0,		view,		{ .i = Tfnord } }, \
 | 
			
		||||
	{ MODKEY,		XK_1,		view,		{ .i = Tdev } }, \
 | 
			
		||||
	{ MODKEY,		XK_2,		view,		{ .i = Tnet } }, \
 | 
			
		||||
	{ MODKEY,		XK_3,		view,		{ .i = Twork } }, \
 | 
			
		||||
	{ MODKEY,		XK_4,		view,		{ .i = Tmisc} }, \
 | 
			
		||||
	{ MODKEY,		XK_0,		view,		{ .i = 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_1,		view,		{ .i = 1 } }, \
 | 
			
		||||
	{ MODKEY,		XK_2,		view,		{ .i = 2 } }, \
 | 
			
		||||
	{ MODKEY,		XK_3,		view,		{ .i = 3 } }, \
 | 
			
		||||
	{ MODKEY,		XK_4,		view,		{ .i = 4 } }, \
 | 
			
		||||
	{ MODKEY,		XK_h,		viewprev,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_j,		focusnext,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_k,		focusprev,	{ 0 } }, \
 | 
			
		||||
| 
						 | 
				
			
			@ -39,24 +32,25 @@ static Key key[] = { \
 | 
			
		|||
	{ MODKEY,		XK_m,		togglemax,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_space,	togglemode,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY,		XK_Return,	zoom,		{ 0 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_0,		appendtag,	{ .i = Tfnord } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_1,		appendtag,	{ .i = Tdev } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_2,		appendtag,	{ .i = Tnet } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_3,		appendtag,	{ .i = Twork } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_4,		appendtag,	{ .i = Tmisc } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_0,		replacetag,	{ .i = Tfnord } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_1,		replacetag,	{ .i = Tdev } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_2,		replacetag,	{ .i = Tnet } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_3,		replacetag,	{ .i = Twork } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_4,		replacetag,	{ .i = Tmisc } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_0,		appendtag,	{ .i = 0 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_1,		appendtag,	{ .i = 1 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_2,		appendtag,	{ .i = 2 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_3,		appendtag,	{ .i = 3 } }, \
 | 
			
		||||
	{ MODKEY|ControlMask,	XK_4,		appendtag,	{ .i = 4 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_0,		replacetag,	{ .i = 0 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_1,		replacetag,	{ .i = 1 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_2,		replacetag,	{ .i = 2 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_3,		replacetag,	{ .i = 3 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_4,		replacetag,	{ .i = 4 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_c,		killclient,	{ 0 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_q,		quit,		{ 0 } }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,	XK_Return,	spawn,		{ .argv = term } }, \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define RULES \
 | 
			
		||||
	const unsigned int firefox[] = { 2 }; \
 | 
			
		||||
static Rule rule[] = { \
 | 
			
		||||
	/* class:instance	tags		isfloat */ \
 | 
			
		||||
	{ "Firefox.*",		{ [Tnet] = True },		False }, \
 | 
			
		||||
	{ "Gimp.*",		{ 0 },				True}, \
 | 
			
		||||
	{ "Firefox.*",		firefox,	False }, \
 | 
			
		||||
	{ "Gimp.*",		NULL,		True}, \
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								draw.c
								
								
								
								
							
							
						
						
									
										4
									
								
								draw.c
								
								
								
								
							| 
						 | 
				
			
			@ -114,7 +114,7 @@ drawstatus()
 | 
			
		|||
	drawtext(NULL, !istile, False);
 | 
			
		||||
 | 
			
		||||
	dc.w = 0;
 | 
			
		||||
	for(i = 0; i < TLast; i++) {
 | 
			
		||||
	for(i = 0; i < ntags; i++) {
 | 
			
		||||
		dc.x += dc.w;
 | 
			
		||||
		dc.w = textw(tags[i]);
 | 
			
		||||
		if(istile)
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +153,7 @@ drawtitle(Client *c)
 | 
			
		|||
	dc.x = dc.y = 0;
 | 
			
		||||
 | 
			
		||||
	dc.w = 0;
 | 
			
		||||
	for(i = 0; i < TLast; i++) {
 | 
			
		||||
	for(i = 0; i < ntags; i++) {
 | 
			
		||||
		if(c->tags[i]) {
 | 
			
		||||
			dc.x += dc.w;
 | 
			
		||||
			dc.w = textw(tags[i]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								dwm.h
								
								
								
								
							
							
						
						
									
										5
									
								
								dwm.h
								
								
								
								
							| 
						 | 
				
			
			@ -60,16 +60,17 @@ struct Client {
 | 
			
		|||
	unsigned int border;
 | 
			
		||||
	Bool isfloat;
 | 
			
		||||
	Bool ismax;
 | 
			
		||||
	Bool tags[TLast];
 | 
			
		||||
	Bool *tags;
 | 
			
		||||
	Client *next;
 | 
			
		||||
	Client *prev;
 | 
			
		||||
	Window win;
 | 
			
		||||
	Window title;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const char *tags[TLast];
 | 
			
		||||
extern const char *tags[];
 | 
			
		||||
extern char stext[1024];
 | 
			
		||||
extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
 | 
			
		||||
extern unsigned int ntags;
 | 
			
		||||
extern void (*handler[LASTEvent])(XEvent *);
 | 
			
		||||
extern void (*arrange)(Arg *);
 | 
			
		||||
extern Atom wmatom[WMLast], netatom[NetLast];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								event.c
								
								
								
								
							
							
						
						
									
										2
									
								
								event.c
								
								
								
								
							| 
						 | 
				
			
			@ -105,7 +105,7 @@ buttonpress(XEvent *e)
 | 
			
		|||
		switch(ev->button) {
 | 
			
		||||
		default:
 | 
			
		||||
			x = 0;
 | 
			
		||||
			for(a.i = 0; a.i < TLast; a.i++) {
 | 
			
		||||
			for(a.i = 0; a.i < ntags; a.i++) {
 | 
			
		||||
				x += textw(tags[a.i]);
 | 
			
		||||
				if(ev->x < x) {
 | 
			
		||||
					view(&a);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								main.c
								
								
								
								
							
							
						
						
									
										3
									
								
								main.c
								
								
								
								
							| 
						 | 
				
			
			@ -85,6 +85,7 @@ xerrorstart(Display *dsply, XErrorEvent *ee)
 | 
			
		|||
char stext[1024];
 | 
			
		||||
int tsel = DEFTAG;
 | 
			
		||||
int screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
 | 
			
		||||
unsigned int ntags;
 | 
			
		||||
Atom wmatom[WMLast], netatom[NetLast];
 | 
			
		||||
Bool running = True;
 | 
			
		||||
Bool issel = True;
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +211,8 @@ main(int argc, char *argv[])
 | 
			
		|||
 | 
			
		||||
	grabkeys();
 | 
			
		||||
 | 
			
		||||
	for(ntags = 0; tags[ntags]; ntags++);
 | 
			
		||||
 | 
			
		||||
	/* style */
 | 
			
		||||
	dc.bg = getcolor(BGCOLOR);
 | 
			
		||||
	dc.fg = getcolor(FGCOLOR);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								tag.c
								
								
								
								
							
							
						
						
									
										19
									
								
								tag.c
								
								
								
								
							| 
						 | 
				
			
			@ -13,7 +13,7 @@
 | 
			
		|||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	const char *pattern;
 | 
			
		||||
	Bool tags[TLast];
 | 
			
		||||
	const unsigned int *tags;
 | 
			
		||||
	Bool isfloat;
 | 
			
		||||
} Rule;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +145,7 @@ replacetag(Arg *arg)
 | 
			
		|||
	if(!sel)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < TLast; i++)
 | 
			
		||||
	for(i = 0; i < ntags; i++)
 | 
			
		||||
		sel->tags[i] = False;
 | 
			
		||||
	appendtag(arg);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ settags(Client *c)
 | 
			
		|||
{
 | 
			
		||||
	char classinst[256];
 | 
			
		||||
	static unsigned int len = sizeof(rule) / sizeof(rule[0]);
 | 
			
		||||
	unsigned int i, j;
 | 
			
		||||
	unsigned int i, j, n;
 | 
			
		||||
	regex_t regex;
 | 
			
		||||
	regmatch_t tmp;
 | 
			
		||||
	Bool matched = False;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,10 +168,11 @@ settags(Client *c)
 | 
			
		|||
		for(i = 0; !matched && i < len; i++) {
 | 
			
		||||
			if(!regcomp(®ex, rule[i].pattern, 0)) {
 | 
			
		||||
				if(!regexec(®ex, classinst, 1, &tmp, 0)) {
 | 
			
		||||
					for(j = 0; j < TLast; j++) {
 | 
			
		||||
						if((c->tags[j] = rule[i].tags[j]))
 | 
			
		||||
							matched = True;
 | 
			
		||||
					}
 | 
			
		||||
					n = rule[i].tags ?
 | 
			
		||||
						sizeof(rule[i].tags) / sizeof(rule[i].tags[0]) : 0;
 | 
			
		||||
					matched = n != 0;
 | 
			
		||||
					for(j = 0; j < n; j++)
 | 
			
		||||
						c->tags[rule[i].tags[j]] = True;
 | 
			
		||||
					c->isfloat = rule[i].isfloat;
 | 
			
		||||
				}
 | 
			
		||||
				regfree(®ex);
 | 
			
		||||
| 
						 | 
				
			
			@ -204,13 +205,13 @@ view(Arg *arg)
 | 
			
		|||
void
 | 
			
		||||
viewnext(Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
	arg->i = (tsel < TLast-1) ? tsel+1 : 0;
 | 
			
		||||
	arg->i = (tsel < ntags-1) ? tsel+1 : 0;
 | 
			
		||||
	view(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
viewprev(Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
	arg->i = (tsel > 0) ? tsel-1 : TLast-1;
 | 
			
		||||
	arg->i = (tsel > 0) ? tsel-1 : ntags-1;
 | 
			
		||||
	view(arg);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue