Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge runs of joins/parts/quits into a single row (option 'merge')

  • Loading branch information...
commit 46a229c10c36351256f8ad290c7918d8416b6316 1 parent dbae880
ec429 authored
View
13 bits.c
@@ -192,13 +192,22 @@ char *mktag(char *fmt, char *from)
char *rv=NULL;
if(strlen(from)<=maxnlen)
{
- rv=(char *)malloc(strlen(fmt)+maxnlen);
+ size_t n=strlen(fmt)+maxnlen;
+ rv=malloc(n);
if(rv)
{
memset(rv, ' ', maxnlen+strlen(fmt)-1);
- sprintf(rv+maxnlen-strlen(from), fmt, from);
+ ssize_t off=maxnlen-strlen(from);
+ snprintf(rv+off, n-off, fmt, from);
}
}
+ else
+ {
+ size_t n=strlen(fmt)+strlen(from);
+ rv=malloc(n);
+ if(rv)
+ snprintf(rv, n, fmt, from);
+ }
return(rv);
}
View
83 buffer.c
@@ -515,12 +515,50 @@ int render_line(int buf, int uline)
bufs[buf].lpl[uline]=0;
return(0);
}
+ char *tag=strdup(bufs[buf].ltag[uline]?bufs[buf].ltag[uline]:"");
+ bool mergetype=((bufs[buf].lm[uline]==JOIN)&&*tag)||(bufs[buf].lm[uline]==PART)||(bufs[buf].lm[uline]==QUIT);
+ bool merged=false;
+ if(merge&&(bufs[buf].type==CHANNEL)&&mergetype)
+ {
+ int prevline=uline;
+ while(1)
+ {
+ if(--prevline<0)
+ {
+ prevline+=bufs[buf].nlines;
+ if(!bufs[buf].filled) break;
+ }
+ if(!bufs[buf].lpl[prevline]) continue;
+ if(fabs(difftime(bufs[buf].ts[prevline], bufs[buf].ts[uline]))>5) break;
+ if(bufs[buf].lm[prevline]==bufs[buf].lm[uline])
+ {
+ if((bufs[buf].lm[uline]==QUIT)&&strcmp(bufs[buf].lt[uline], bufs[buf].lt[prevline])) break;
+ const char *ltag=bufs[buf].ltag[prevline];
+ if(!ltag) ltag="";
+ if((bufs[buf].lm[uline]==JOIN)&&!*ltag) break;
+ size_t nlen=strlen(tag)+strlen(ltag)+2;
+ char *ntag=malloc(nlen);
+ snprintf(ntag, nlen, "%s=%s", ltag, tag);
+ free(tag);
+ tag=ntag;
+ int pline;
+ for(pline=0;pline<bufs[buf].lpl[prevline];pline++)
+ free(bufs[buf].lpt[prevline][pline]);
+ free(bufs[buf].lpt[prevline]);
+ bufs[buf].lpt[prevline]=NULL;
+ bufs[buf].lpl[prevline]=0;
+ merged=true;
+ continue;
+ }
+ break;
+ }
+ }
+ char *message=strdup(bufs[buf].lt[uline]);
char *proc;size_t l,i;
init_char(&proc, &l, &i);
char stamp[STAMP_LEN];
timestamp(stamp, bufs[buf].ts[uline]);
colour c={.fore=7, .back=0, .hi=false, .ul=false};
- char *tag=strdup(bufs[buf].ltag[uline]?bufs[buf].ltag[uline]:"");
switch(bufs[buf].lm[uline])
{
case MSG:
@@ -563,12 +601,49 @@ int render_line(int buf, int uline)
break;
case JOIN:
c=c_join[bufs[buf].ls[uline]?0:1];
+ if(tag&&*tag)
+ {
+ free(message);
+ const char *bn=bufs[buf].bname;
+ if(!bn) bn="the channel";
+ size_t l=16+strlen(bn);
+ message=malloc(l);
+ if(merged)
+ snprintf(message, l, "have joined %s", bufs[buf].bname);
+ else
+ snprintf(message, l, "has joined %s", bufs[buf].bname);
+ }
goto eqtag;
case PART:
c=c_part[bufs[buf].ls[uline]?0:1];
+ if(tag&&*tag)
+ {
+ free(message);
+ const char *bn=bufs[buf].bname;
+ if(!bn) bn="the channel";
+ size_t l=16+strlen(bn);
+ message=malloc(l);
+ if(merged)
+ snprintf(message, l, "have left %s", bufs[buf].bname);
+ else
+ snprintf(message, l, "has left %s", bufs[buf].bname);
+ }
goto eqtag;
case QUIT:
c=c_quit[bufs[buf].ls[uline]?0:1];
+ if(tag&&*tag)
+ {
+ const char *bn=bufs[buf].bname;
+ if(!bn) bn="the channel";
+ size_t l=16+strlen(bn)+strlen(message);
+ char *nmessage=malloc(l);
+ if(merged)
+ snprintf(nmessage, l, "have left %s (%s)", bufs[buf].bname, message);
+ else
+ snprintf(nmessage, l, "has left %s (%s)", bufs[buf].bname, message);
+ free(message);
+ message=nmessage;
+ }
goto eqtag;
case QUIT_PREFORMAT:
c=c_quit[bufs[buf].ls[uline]?0:1];
@@ -577,7 +652,8 @@ int render_line(int buf, int uline)
{
c=c_nick[bufs[buf].ls[uline]?0:1];
eqtag:
- crush(&tag, maxnlen);
+ if(!merge)
+ crush(&tag, maxnlen);
char *ntag=mktag("=%s= ", tag);
free(tag);
tag=ntag;
@@ -614,7 +690,8 @@ int render_line(int buf, int uline)
int x=wordline(stamp, 0, &proc, &l, &i, c);
x=wordline(tag, indent?x:0, &proc, &l, &i, c);
free(tag);
- wordline(bufs[buf].lt[uline], indent?x:0, &proc, &l, &i, c);
+ wordline(message, indent?x:0, &proc, &l, &i, c);
+ free(message);
bufs[buf].lpl[uline]=0;
bufs[buf].lpt[uline]=NULL;
bufs[buf].lpc[uline]=c;
View
2  buffer.h
@@ -56,7 +56,7 @@ typedef struct _buf
char *lp; // array of prefix chars (0 for use default)
char **lt; // array of (unprocessed) text for lines
char **ltag; // array of (unprocessed, uncrushed) tag text for lines
- time_t *ts; // array of timestamps for unproc lines (not used now, but there ready for eg. mergebuffers)
+ time_t *ts; // array of timestamps for unproc lines
bool filled; // buffer has filled up and looped? (the buffers are circular in nature)
bool dirty; // processed lines are out of date? (TODO: make this indicate /which/ are out of date and only re-render those)
int *lpl; // count of processed lines for each line
View
1  config.cdl
@@ -18,3 +18,4 @@ bool:show_prefix:false:::prefix:prefix:prefix:B:display nick prefixes
bool:titles:true:::titles:titles:titles:B:xterm title
bool:winch:true:::winch:winch:winch:B:react to SIGWINCH (window change)
bool:indent:true:::indent:indent:indent:B:hanging indent
+bool:merge:true:::merge:merge:merge:B:merge events
View
1  config_def.c
@@ -19,3 +19,4 @@
titles=1;
winch=1;
indent=1;
+ merge=1;
View
1  config_globals.h
@@ -19,3 +19,4 @@ bool show_prefix; // display nick prefixes
bool titles; // xterm title
bool winch; // react to SIGWINCH (window change)
bool indent; // hanging indent
+bool merge; // merge events
View
1  config_help.c
@@ -19,3 +19,4 @@
fprintf(stderr, "\t--[no-]titles : xterm title\n");
fprintf(stderr, "\t--[no-]winch : react to SIGWINCH (window change)\n");
fprintf(stderr, "\t--[no-]indent : hanging indent\n");
+ fprintf(stderr, "\t--[no-]merge : merge events\n");
View
2  config_need.c
@@ -32,3 +32,5 @@
if(strcmp(cmd, "no-winch")==0) need=false;
if(strcmp(cmd, "indent")==0) need=false;
if(strcmp(cmd, "no-indent")==0) need=false;
+ if(strcmp(cmd, "merge")==0) need=false;
+ if(strcmp(cmd, "no-merge")==0) need=false;
View
4 config_pargs.c
@@ -63,3 +63,7 @@
indent=true;
else if(strcmp(argv[arg], "--no-indent")==0)
indent=false;
+ else if(strcmp(argv[arg], "--merge")==0)
+ merge=true;
+ else if(strcmp(argv[arg], "--no-merge")==0)
+ merge=false;
View
10 config_rcread.c
@@ -191,3 +191,13 @@
else
indent=true;
}
+ else if(strcmp(cmd, "no-merge")==0)
+ merge=false;
+ else if(strcmp(cmd, "merge")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ merge=value;
+ else
+ merge=true;
+ }
View
1  config_ref.htm
@@ -60,6 +60,7 @@
<tr><td>titles</td><td><span class="bool">BOOL</span></td><td>true</td><td>titles</td><td>titles</td><td>titles</td><td>xterm title</td></tr>
<tr><td>winch</td><td><span class="bool">BOOL</span></td><td>true</td><td>winch</td><td>winch</td><td>winch</td><td>react to SIGWINCH (window change)</td></tr>
<tr><td>indent</td><td><span class="bool">BOOL</span></td><td>true</td><td>indent</td><td>indent</td><td>indent</td><td>hanging indent</td></tr>
+<tr><td>merge</td><td><span class="bool">BOOL</span></td><td>true</td><td>merge</td><td>merge</td><td>merge</td><td>merge events</td></tr>
</table>
</div><!--#table-->
</body>
View
43 config_set.c
@@ -674,3 +674,46 @@
bufs[buf].dirty=true;
redraw_buffer();
}
+ else if(strcmp(opt, "merge")==0)
+ {
+ if(val)
+ {
+ if(isdigit(*val))
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ merge=value;
+ }
+ else if(strcmp(val, "+")==0)
+ {
+ merge=true;
+ }
+ else if(strcmp(val, "-")==0)
+ {
+ merge=false;
+ }
+ else
+ {
+ add_to_buffer(cbuf, ERR, NORMAL, 0, false, "option 'merge' is boolean, use only 0/1 or -/+ to set", "/set: ");
+ }
+ }
+ else
+ merge=true;
+ if(merge)
+ add_to_buffer(cbuf, STA, QUIET, 0, false, "merge events enabled", "/set: ");
+ else
+ add_to_buffer(cbuf, STA, QUIET, 0, false, "merge events disabled", "/set: ");
+ int buf;
+ for(buf=0;buf<nbufs;buf++)
+ bufs[buf].dirty=true;
+ redraw_buffer();
+ }
+ else if(strcmp(opt, "no-merge")==0)
+ {
+ merge=0;
+ add_to_buffer(cbuf, STA, QUIET, 0, false, "merge events disabled", "/set: ");
+ int buf;
+ for(buf=0;buf<nbufs;buf++)
+ bufs[buf].dirty=true;
+ redraw_buffer();
+ }
View
5 irc.c
@@ -1534,6 +1534,7 @@ int rx_join(message pkt, int b)
int rx_part(message pkt, int b)
{
// :nick[[!user]@host] PART #chan message
+ // TODO this should be PART #chan [,#chan ...]
if(pkt.nargs<1)
{
e_buf_print(b, ERR, pkt, "Not enough arguments: ");
@@ -1609,9 +1610,7 @@ int rx_quit(message pkt, int b)
{
if(n_cull(&bufs[b2].nlist, src, bufs[b].casemapping))
{
- char dstr[24+strlen(bufs[b].bname)+strlen(reason)];
- sprintf(dstr, "has left %s (%s)", bufs[b].bname, reason);
- add_to_buffer(b2, QUIT, NORMAL, 0, false, dstr, src);
+ add_to_buffer(b2, QUIT, NORMAL, 0, false, reason, src);
}
}
}
View
2  plans
@@ -4,8 +4,6 @@ Scripting language. Under development in branch 'script'.
Need to fix the problem of the conn_rest not getting called for eg worldofspectrum (why is this happening?)
-Optionally fold runs of the same type of message. Eg.: =foo=bar=baz= have joined #whatever.
-
Leave UTF8 alone when escaping unprintables in input buffer.
Tab search, with ^T. Typing eg ^Tqu<return> should switch to the tab named quirc (assuming no other tabs have names containing "qu"). While entering the search string, all matching tabs should be highlighted on the strip.
View
5 quirc.c
@@ -96,7 +96,7 @@ int main(int argc, char *argv[])
return(1);
}
resetcol();
- char *qmsg=fname;
+ char *qmsg=strdup(fname);
char *home=getenv("HOME");
bool haveqfld=true;
if(home)
@@ -357,7 +357,7 @@ int main(int argc, char *argv[])
if(fd==fileno(stdin))
{
inputchar(&inp, &state);
- /* WARNING! Possibly non-portable code; relies on edge-case behaviour */
+ /* XXX Possibly non-portable code; relies on edge-case behaviour */
bool loop=true;
while(loop && !state)
{
@@ -569,6 +569,7 @@ int main(int argc, char *argv[])
free(bufs);
free(username);
free(fname);
+ free(qmsg);
free(nick);
free(portno);
freeservlist(servs);
Please sign in to comment.
Something went wrong with that request. Please try again.