Here's it updated to fix some warnings, to apply to top of latest git
and also with the changes to add automatic-rename-format which you might
like to look at.

diff --git a/format.c b/format.c
index ee3339d..da939f0 100644
--- a/format.c
+++ b/format.c
@@ -34,9 +34,10 @@
  * string.
  */
 
-int    format_replace(struct format_tree *, const char *, size_t, char **,
-           size_t *, size_t *);
-void   format_window_pane_tabs(struct format_tree *, struct window_pane *);
+int     format_replace(struct format_tree *, const char *, size_t, char **,
+            size_t *, size_t *);
+char   *format_get_command(struct window_pane *);
+void    format_window_pane_tabs(struct format_tree *, struct window_pane *);
 
 /* Format key-value replacement entry. */
 RB_GENERATE(format_tree, format_entry, entry, format_cmp);
@@ -193,7 +194,7 @@ int
 format_replace(struct format_tree *ft, const char *key, size_t keylen,
     char **buf, size_t *len, size_t *off)
 {
-       char            *copy, *copy0, *endptr, *ptr;
+       char            *copy, *copy0, *endptr, *ptr, *saved;
        const char      *value;
        size_t           valuelen;
        u_long           limit = ULONG_MAX;
@@ -247,10 +248,13 @@ format_replace(struct format_tree *ft, const char *key, 
size_t keylen,
                                goto fail;
                        value = ptr + 1;
                }
+               saved = format_expand(ft, value);
+               value = saved;
        } else {
                value = format_find(ft, copy);
                if (value == NULL)
                        value = "";
+               saved = NULL;
        }
        valuelen = strlen(value);
 
@@ -266,6 +270,7 @@ format_replace(struct format_tree *ft, const char *key, 
size_t keylen,
        memcpy(*buf + *off, value, valuelen);
        *off += valuelen;
 
+       free(saved);
        free(copy0);
        return (0);
 
@@ -278,10 +283,10 @@ fail:
 char *
 format_expand(struct format_tree *ft, const char *fmt)
 {
-       char            *buf, *ptr;
-       const char      *s;
+       char            *buf;
+       const char      *ptr, *s;
        size_t           off, len, n;
-       int              ch;
+       int              ch, brackets;
 
        len = 64;
        buf = xmalloc(len);
@@ -299,11 +304,16 @@ format_expand(struct format_tree *ft, const char *fmt)
                fmt++;
 
                ch = (u_char) *fmt++;
-
                switch (ch) {
                case '{':
-                       ptr = strchr(fmt, '}');
-                       if (ptr == NULL)
+                       brackets = 1;
+                       for (ptr = fmt; *ptr != '\0'; ptr++) {
+                               if (*ptr == '{')
+                                       brackets++;
+                               if (*ptr == '}' && --brackets == 0)
+                                       break;
+                       }
+                       if (*ptr != '}' || brackets != 0)
                                break;
                        n = ptr - fmt;
 
@@ -339,6 +349,21 @@ format_expand(struct format_tree *ft, const char *fmt)
        return (buf);
 }
 
+/* Get command name for format. */
+char *
+format_get_command(struct window_pane *wp)
+{
+       char    *cmd;
+
+       cmd = osdep_get_name(wp->fd, wp->tty);
+       if (cmd == NULL || *cmd == '\0') {
+               cmd = wp->cmd;
+               if (cmd == NULL || *cmd == '\0')
+                       cmd = wp->shell;
+       }
+       return (parse_window_name(cmd));
+}
+
 /* Set default format keys for a session. */
 void
 format_session(struct format_tree *ft, struct session *s)
@@ -418,26 +443,39 @@ format_client(struct format_tree *ft, struct client *c)
                format_add(ft, "client_last_session", "%s", s->name);
 }
 
-/* Set default format keys for a winlink. */
+/* Set default format keys for a window. */
 void
-format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl)
+format_window(struct format_tree *ft, struct window *w)
 {
-       struct window   *w = wl->window;
-       char            *layout, *flags;
+       char    *layout;
 
        layout = layout_dump(w);
-       flags = window_printable_flags(s, wl);
 
        format_add(ft, "window_id", "@%u", w->id);
-       format_add(ft, "window_index", "%d", wl->idx);
        format_add(ft, "window_name", "%s", w->name);
        format_add(ft, "window_width", "%u", w->sx);
        format_add(ft, "window_height", "%u", w->sy);
-       format_add(ft, "window_flags", "%s", flags);
        format_add(ft, "window_layout", "%s", layout);
-       format_add(ft, "window_active", "%d", wl == s->curw);
        format_add(ft, "window_panes", "%u", window_count_panes(w));
 
+       free(layout);
+}
+
+/* Set default format keys for a winlink. */
+void
+format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl)
+{
+       struct window   *w = wl->window;
+       char            *flags;
+
+       flags = window_printable_flags(s, wl);
+
+       format_window(ft, w);
+
+       format_add(ft, "window_index", "%d", wl->idx);
+       format_add(ft, "window_flags", "%s", flags);
+       format_add(ft, "window_active", "%d", wl == s->curw);
+
        format_add(ft, "window_bell_flag", "%u",
            !!(wl->flags & WINLINK_BELL));
        format_add(ft, "window_content_flag", "%u",
@@ -447,8 +485,8 @@ format_winlink(struct format_tree *ft, struct session *s, 
struct winlink *wl)
        format_add(ft, "window_silence_flag", "%u",
            !!(wl->flags & WINLINK_SILENCE));
 
+
        free(flags);
-       free(layout);
 }
 
 /* Add window pane tabs. */
@@ -518,7 +556,7 @@ format_window_pane(struct format_tree *ft, struct 
window_pane *wp)
                format_add(ft, "pane_start_path", "%s", wp->cwd);
        if ((cwd = osdep_get_cwd(wp->fd)) != NULL)
                format_add(ft, "pane_current_path", "%s", cwd);
-       if ((cmd = osdep_get_name(wp->fd, wp->tty)) != NULL) {
+       if ((cmd = format_get_command(wp)) != NULL) {
                format_add(ft, "pane_current_command", "%s", cmd);
                free(cmd);
        }
diff --git a/names.c b/names.c
index f536d2f..7c02961 100644
--- a/names.c
+++ b/names.c
@@ -22,12 +22,10 @@
 #include <libgen.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 #include "tmux.h"
 
 void    window_name_callback(unused int, unused short, void *);
-char   *parse_window_name(const char *);
 
 void
 queue_window_name(struct window *w)
@@ -47,7 +45,7 @@ void
 window_name_callback(unused int fd, unused short events, void *data)
 {
        struct window   *w = data;
-       char            *name, *wname;
+       char            *name;
 
        if (w->active == NULL)
                return;
@@ -59,50 +57,40 @@ window_name_callback(unused int fd, unused short events, 
void *data)
        }
        queue_window_name(w);
 
-       if (w->active->screen != &w->active->base)
-               name = NULL;
-       else
-               name = osdep_get_name(w->active->fd, w->active->tty);
-       if (name == NULL)
-               wname = default_window_name(w);
-       else {
-               /*
-                * If tmux is using the default command, it will be a login
-                * shell and argv[0] may have a - prefix. Remove this if it is
-                * present. Ick.
-                */
-               if (w->active->cmd != NULL && *w->active->cmd == '\0' &&
-                   name != NULL && name[0] == '-' && name[1] != '\0')
-                       wname = parse_window_name(name + 1);
-               else
-                       wname = parse_window_name(name);
-               free(name);
-       }
-
-       if (w->active->fd == -1) {
-               xasprintf(&name, "%s[dead]", wname);
-               free(wname);
-               wname = name;
-       }
-
-       if (strcmp(wname, w->name)) {
-               window_set_name(w, wname);
+       name = format_window_name(w);
+       if (strcmp(name, w->name) != 0) {
+               window_set_name(w, name);
                server_status_window(w);
        }
-       free(wname);
+       free(name);
 }
 
 char *
 default_window_name(struct window *w)
 {
-       if (w->active->screen != &w->active->base)
-               return (xstrdup("[tmux]"));
        if (w->active->cmd != NULL && *w->active->cmd != '\0')
                return (parse_window_name(w->active->cmd));
        return (parse_window_name(w->active->shell));
 }
 
 char *
+format_window_name(struct window *w)
+{
+       struct format_tree      *ft;
+       char                    *fmt, *name;
+
+       ft = format_create();
+       format_window(ft, w);
+       format_window_pane(ft, w->active);
+
+       fmt = options_get_string(&w->options, "automatic-rename-format");
+       name = format_expand(ft, fmt);
+
+       format_free(ft);
+       return (name);
+}
+
+char *
 parse_window_name(const char *in)
 {
        char    *copy, *name, *ptr;
@@ -111,7 +99,7 @@ parse_window_name(const char *in)
        if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0)
                name = name + (sizeof "exec ") - 1;
 
-       while (*name == ' ')
+       while (*name == ' ' || *name == '-')
                name++;
        if ((ptr = strchr(name, ' ')) != NULL)
                *ptr = '\0';
diff --git a/options-table.c b/options-table.c
index 0b86ef7..f6a1547 100644
--- a/options-table.c
+++ b/options-table.c
@@ -481,6 +481,11 @@ const struct options_table_entry window_options_table[] = {
          .default_num = 1
        },
 
+       { .name = "automatic-rename-format",
+         .type = OPTIONS_TABLE_STRING,
+         .default_str = 
"#{?pane_in_mode,[tmux],#{pane_current_command}}#{?pane_dead,[dead],}"
+       },
+
        { .name = "c0-change-trigger",
          .type = OPTIONS_TABLE_NUMBER,
          .default_num = 250,
diff --git a/tmux.1 b/tmux.1
index 19ae4a9..c93f4d9 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2710,8 +2710,8 @@ The default is on.
 Control automatic window renaming.
 When this setting is enabled,
 .Nm
-will attempt - on supported platforms - to rename the window to reflect the
-command currently running in it.
+will rename the window automatically using the format specified by
+.Ic automatic-rename-format .
 This flag is automatically disabled for an individual window when a name
 is specified at creation with
 .Ic new-window
@@ -2725,6 +2725,13 @@ It may be switched off globally with:
 set-window-option -g automatic-rename off
 .Ed
 .Pp
+.It Ic automatic-rename-format Ar format
+The format (see
+.Sx FORMATS )
+used when the
+.Ic automatic-rename
+option is enabled.
+.Pp
 .It Ic c0-change-interval Ar interval
 .It Ic c0-change-trigger Ar trigger
 These two options configure a simple form of rate limiting for a pane.
diff --git a/tmux.h b/tmux.h
index 1cb5cd8..6ab9861 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1549,16 +1549,19 @@ int              format_cmp(struct format_entry *, 
struct format_entry *);
 RB_PROTOTYPE(format_tree, format_entry, entry, format_cmp);
 struct format_tree *format_create(void);
 void            format_free(struct format_tree *);
-void printflike3 format_add(
-                    struct format_tree *, const char *, const char *, ...);
+void printflike3 format_add(struct format_tree *, const char *, const char *,
+                    ...);
 const char     *format_find(struct format_tree *, const char *);
 char           *format_expand(struct format_tree *, const char *);
 void            format_session(struct format_tree *, struct session *);
 void            format_client(struct format_tree *, struct client *);
-void            format_winlink(
-                    struct format_tree *, struct session *, struct winlink *);
-void            format_window_pane(struct format_tree *, struct window_pane *);
-void            format_paste_buffer(struct format_tree *, struct paste_buffer 
*);
+void            format_window(struct format_tree *, struct window *);
+void            format_winlink(struct format_tree *, struct session *,
+                    struct winlink *);
+void            format_window_pane(struct format_tree *,
+                    struct window_pane *);
+void            format_paste_buffer(struct format_tree *,
+                    struct paste_buffer *);
 
 /* mode-key.c */
 extern const struct mode_key_table mode_key_tables[];
@@ -2272,8 +2275,10 @@ void     window_choose_collapse_all(struct window_pane 
*);
 void   window_choose_set_current(struct window_pane *, u_int);
 
 /* names.c */
-void            queue_window_name(struct window *);
-char           *default_window_name(struct window *);
+void    queue_window_name(struct window *);
+char   *default_window_name(struct window *);
+char   *format_window_name(struct window *);
+char   *parse_window_name(const char *);
 
 /* signal.c */
 void   set_signals(void(*)(int, short, void *));



On Fri, Aug 02, 2013 at 02:11:10PM +0100, Nicholas Marriott wrote:
> How about this?
> 
> 
> diff --git a/format.c b/format.c
> index 0845df6..9a3ed07 100644
> --- a/format.c
> +++ b/format.c
> @@ -191,7 +191,7 @@ int
>  format_replace(struct format_tree *ft,
>      const char *key, size_t keylen, char **buf, size_t *len, size_t *off)
>  {
> -     char            *copy, *ptr;
> +     char            *copy, *ptr, *saved;
>       const char      *value;
>       size_t           valuelen;
>  
> @@ -223,10 +223,15 @@ format_replace(struct format_tree *ft,
>                               goto fail;
>                       value = ptr + 1;
>               }
> +             value = format_expand(ft, value);
> +
> +             saved = value;
>       } else {
>               value = format_find(ft, copy);
>               if (value == NULL)
>                       value = "";
> +
> +             saved = NULL;
>       }
>       valuelen = strlen(value);
>  
> @@ -238,6 +243,7 @@ format_replace(struct format_tree *ft,
>       memcpy(*buf + *off, value, valuelen);
>       *off += valuelen;
>  
> +     free(saved);
>       free(copy);
>       return (0);
>  
> @@ -253,7 +259,7 @@ format_expand(struct format_tree *ft, const char *fmt)
>       char            *buf, *ptr;
>       const char      *s;
>       size_t           off, len, n;
> -     int              ch;
> +     int              ch, brackets;
>  
>       len = 64;
>       buf = xmalloc(len);
> @@ -271,11 +277,16 @@ format_expand(struct format_tree *ft, const char *fmt)
>               fmt++;
>  
>               ch = (u_char) *fmt++;
> -
>               switch (ch) {
>               case '{':
> -                     ptr = strchr(fmt, '}');
> -                     if (ptr == NULL)
> +                     brackets = 1;
> +                     for (ptr = fmt; *ptr != '\0'; ptr++) {
> +                             if (*ptr == '{')
> +                                     brackets++;
> +                             if (*ptr == '}' && --brackets == 0)
> +                                     break;
> +                     }
> +                     if (*ptr != '}' || brackets != 0)
>                               break;
>                       n = ptr - fmt;
>  
> 
> 
> 
> 
> On Wed, May 15, 2013 at 05:01:53PM +0100, Nicholas Marriott wrote:
> > This still doesn't seem right.
> > 
> > If I have "#{?foo,bar,#{baz}} #{zoink}".
> > 
> > Then in format_expand it'll decide the first { is: "?foo,bar,#{baz}}
> > #{zoink".
> > 
> > Then if foo is true I'll get bar (which is fine)
> > 
> > But if it's false I'll get "#{baz}} #{zoink" which is wrong.
> > 
> > You need to replace the strchr with a loop like:
> > 
> > depth = 1;
> > ptr = fmt;
> > while (*ptr != '\0') {
> >     if (*ptr == '{')
> >             depth++;
> >     if (*ptr == '}') {
> >             if (--depth == 0)
> >                     break;
> >     }
> > }
> > 
> > Which means format_replace will be passed exactly "?foo,bar,#{baz}".
> > 
> > 
> > On Sun, Apr 28, 2013 at 01:54:44PM +0100, Thomas Adam wrote:
> > > Hi,
> > > 
> > > On Thu, Apr 25, 2013 at 10:55:56PM +0100, Nicholas Marriott wrote:
> > > > Ok. I think you have the right idea about recursing through
> > > > format_expand you are just going to need to pull out the affected format
> > > > differently (ditch strchr and use a custom loop which counts {s and }s).
> > > 
> > > Yeah, that's one way.  But actually, strchr/strchrr would both be doing 
> > > the
> > > same thing as this manual loop you refer to, it's just that their use 
> > > would
> > > vary depending on whether we're expanding a terniary-form of a format
> > > replacement or just a single element.
> > > 
> > > So I think something along the lines of the patch attached might be an 
> > > idea.
> > > It's certainly the path of least resistance (i.e., not much code changed)
> > > but that doesn't mean I particularly like it.  ;P
> > > 
> > > -- Thomas Adam
> > 
> > > diff --git a/format.c b/format.c
> > > index 7de819a..178f201 100644
> > > --- a/format.c
> > > +++ b/format.c
> > > @@ -150,8 +150,8 @@ int
> > >  format_replace(struct format_tree *ft,
> > >      const char *key, size_t keylen, char **buf, size_t *len, size_t *off)
> > >  {
> > > - char            *copy, *ptr;
> > >   const char      *value;
> > > + char            *copy, *ptr;
> > >   size_t           valuelen;
> > >  
> > >   /* Make a copy of the key. */
> > > @@ -182,6 +182,7 @@ format_replace(struct format_tree *ft,
> > >                           goto fail;
> > >                   value = ptr + 1;
> > >           }
> > > +         value = format_expand(ft, value);
> > >   } else {
> > >           value = format_find(ft, copy);
> > >           if (value == NULL)
> > > @@ -232,7 +233,11 @@ format_expand(struct format_tree *ft, const char 
> > > *fmt)
> > >           ch = (u_char) *fmt++;
> > >           switch (ch) {
> > >           case '{':
> > > -                 ptr = strchr(fmt, '}');
> > > +                 if (*fmt++ == '?')
> > > +                         ptr = strrchr(--fmt, '}');
> > > +                 else
> > > +                         ptr = strchr(--fmt, '}');
> > 
> > There is no need to do fmt++ if you then do --fmt in both branches of
> > the if.
> > 
> > > +
> > >                   if (ptr == NULL)
> > >                           break;
> > >                   n = ptr - fmt;
> > > -- 
> > > 1.7.11.4
> > > 
> > 

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent 
caught up. So what steps can you take to put your SQL databases under 
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to