1. Christian Hudon
  2. vcprompt

Commits

Christian Hudon  committed 0d80337

Add support for VC system-specific VCPROMPT_FORMAT environment variables (e.g. VCPROMPT_FORMAT_GIT, etc.).

  • Participants
  • Parent commits 582a6fd
  • Branches default

Comments (0)

Files changed (8)

File README.txt

View file
  • Ignore whitespace
 
 You can customize the output of vcprompt using format strings, which can
 be specified either on the command line or in the VCPROMPT_FORMAT
-environment variable.  For example:
+environment variables.  For example:
 
   vcprompt -f "%b"
 
 
 are equivalent.
 
+If you want to set a different format string for different VC systems, you
+can do so via VCPROMPT_FORMAT_GIT, VCPROMPT_FORMAT_HG, etc., which are
+checked before the generic VCPROMPT_FORMAT environment variable.
+
 Format strings use printf-like "%" escape sequences:
 
   %n  name of the VC system managing the current directory
 
 In chronological order:
 
+  Christian Hudon
   Daniel Serpell
   Jannis Leidel
   Yuya Nishihara
 Copyright & License
 ===================
 
-Copyright (C) 2009, 2010, Gregory P. Ward and contributors.
+Copyright (C) 2009, 2010, 2012, Gregory P. Ward and contributors.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by

File src/common.c

View file
  • Ignore whitespace
 /*
- * Copyright (C) 2009, 2010, Gregory P. Ward and contributors.
+ * Copyright (C) 2009, 2010, 2012, Gregory P. Ward and contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
 #include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
+#include <ctype.h>
 
 #include "common.h"
 
     return !!result->branch;
 }
 
+void parse_format(options_t* options)
+{
+    size_t i;
+
+    options->show_branch = 0;
+    options->show_unknown = 0;
+    options->show_modified = 0;
+
+    char* format = options->format;
+    size_t len = strlen(format);
+    for (i = 0; i < len; i++) {
+        if (format[i] == '%') {
+            i++;
+            switch (format[i]) {
+                case '\0':              /* at end of string: ignore */
+                    break;
+                case 'b':
+                    options->show_branch = 1;
+                    break;
+                case 'r':
+                    options->show_revision = 1;
+                    break;
+                case 'u':
+                    options->show_unknown = 1;
+                    break;
+                case 'm':
+                    options->show_modified = 1;
+                    break;
+                case 'n':               /* name of VC system */
+                case '%':
+                    break;
+                default:
+                    fprintf(stderr,
+                            "error: invalid format string: %%%c\n",
+                            format[i]);
+                    break;
+            }
+        }
+    }
+}
+
 vccontext_t*
 init_context(const char *name,
              options_t* options,
              result_t* (*get_info)(vccontext_t*))
 {
     vccontext_t* context = (vccontext_t*) calloc(1, sizeof(vccontext_t));
-    context->options = options;
+    context->options = *options;
     context->name = name;
     context->probe = probe;
     context->get_info = get_info;
+
+    if (context->options.format == NULL)
+        context->options.format = get_format_from_env(context->name);
+
+    parse_format(&context->options);
+
     return context;
 }
 
     strncpy(dest, src, nchars);
     dest[nchars] = '\0';
 }
+
+char*
+get_format_from_env(const char *vcname)
+{
+    char vc_format_envname[30];
+    snprintf(vc_format_envname, sizeof (vc_format_envname),
+             "VCPROMPT_FORMAT_%s", vcname);
+    /* Make sure vc_format_envname is NULL-terminated. */
+    vc_format_envname[sizeof(vc_format_envname)-1] = '\0';
+
+    /* Convert vc_format_envname to uppercase. */
+    char* s = vc_format_envname;
+    while (*s) {
+        *s = toupper(*s);
+        s++;
+    }
+
+    char* format = getenv(vc_format_envname);
+    if (format == NULL) {
+        format = getenv("VCPROMPT_FORMAT");
+        if (format == NULL)
+            format = DEFAULT_FORMAT;
+    }
+
+    return format;
+}

File src/common.h

View file
  • Ignore whitespace
 /*
- * Copyright (C) 2009, 2010, Gregory P. Ward and contributors.
+ * Copyright (C) 2009, 2010, 2012, Gregory P. Ward and contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
 #ifndef VCPROMPT_H
 #define VCPROMPT_H
 
+#define DEFAULT_FORMAT "[%n:%b%m%u] "
+
 /* What the user asked for (environment + command-line).
  */
 typedef struct {
 typedef struct vccontext_t vccontext_t;
 struct vccontext_t {
     const char *name;                   /* name of the VC system */
-    options_t* options;
+    options_t options;
 
     /* context methods */
     int (*probe)(vccontext_t*);
 void
 free_result(result_t*);
 
+/* Retrieves the desired output format from environment variables, for a
+ * given version control system. First try vc-specific format environment
+ * variable (e.g. VCPROMPT_FORMAT_GIT). If that is not set, try the
+ * VCPROMPT_FORMAT environment variable. If that is not set too, fall back
+ * to default hardcoded format.
+ */
+char*
+get_format_from_env(const char *);
+
 /* printf()-style output of fmt and other args to stdout, but only if
  * debug mode is on (e.g. from the command line -d).
  */

File src/fossil.c

View file
  • Ignore whitespace
 /*
- * Copyright (C) 2011 Jan Spakula and contributors.
+ * Copyright (C) 2011, 2012, Jan Spakula and contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
     buf[rlen] = '\0';
     pclose(stream);
 
-    if (context->options->show_branch) {
+    if (context->options.show_branch) {
         if ((t = strstr(buf, "\ntags:"))) {
             // This in fact shows also other tags than just the
             // propagating ones (=branches).  So either we show all
             result_set_branch(result, "(unknown)");
         }
     }
-    if (context->options->show_revision) {
+    if (context->options.show_revision) {
         if ((t = strstr(buf, "\ncheckout:"))) {
             get_till_eol(buf2, t + tab_len + 1, 80);
             debug("found revision line: '%s'", buf2);
             result_set_revision(result, "unknown", 7);
         }
     }
-    if (context->options->show_modified) {
+    if (context->options.show_modified) {
         // This can be also done by 'test -n'ing 'fossil changes',
         // but we save a system() call this way.
         if ( strstr(buf, "\nEDITED") || strstr(buf, "\nADDED")
             || strstr(buf, "\nUPDATED") || strstr(buf, "\nMERGED") )
             result->modified = 1;
     }
-    if (context->options->show_unknown) {
+    if (context->options.show_unknown) {
         // This can't be read from 'fossil status' output
         int status = system("test -n \"$(fossil extra)\"");
         if (WEXITSTATUS(status) == 0)

File src/git.c

View file
  • Ignore whitespace
 /*
- * Copyright (C) 2009, 2010, Gregory P. Ward and contributors.
+ * Copyright (C) 2009, 2010, 2012, Gregory P. Ward and contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
         char* prefix = "ref: refs/heads/";
         int prefixlen = strlen(prefix);
 
-        if (context->options->show_branch || context->options->show_revision) {
+        if (context->options.show_branch || context->options.show_revision) {
             int found_branch = 0;
             if (strncmp(prefix, buf, prefixlen) == 0) {
                 /* yep, we're on a known branch */
                 result_set_branch(result, "(unknown)");
                 result_set_revision(result, buf, 12);
             }
-            if (context->options->show_revision && found_branch) {
+            if (context->options.show_revision && found_branch) {
                 char buf[1024];
                 char filename[1024] = ".git/refs/heads/";
                 int nchars = sizeof(filename) - strlen(filename) - 1;
                 }
             }
         }
-        if (context->options->show_modified) {
+        if (context->options.show_modified) {
             int status = system("git diff --no-ext-diff --quiet --exit-code");
             if (WEXITSTATUS(status) == 1)       /* files modified */
                 result->modified = 1;
                failure to run git, or diff error): assume no
                modifications */
         }
-        if (context->options->show_unknown) {
+        if (context->options.show_unknown) {
             int status = system("test -n \"$(git ls-files --others --exclude-standard)\"");
             if (WEXITSTATUS(status) == 0)
                 result->unknown = 1;

File src/hg.c

View file
  • Ignore whitespace
     char buf[NODEID_LEN * 2];
     size_t readsize;
 
-    if (!context->options->show_revision) return;
+    if (!context->options.show_revision) return;
 
     readsize = read_file(".hg/dirstate", buf, NODEID_LEN * 2);
     if (readsize == NODEID_LEN * 2) {

File src/svn.c

View file
  • Ignore whitespace
 /*
- * Copyright (C) 2009, 2010, Gregory P. Ward and contributors.
+ * Copyright (C) 2009, 2010, 2012, Gregory P. Ward and contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by

File src/vcprompt.c

View file
  • Ignore whitespace
 /*
- * Copyright (C) 2009, 2010, Gregory P. Ward and contributors.
+ * Copyright (C) 2009, 2010, 2012 Gregory P. Ward and contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
 #include "bzr.h"
 */
 
-#define DEFAULT_FORMAT "[%n:%b%m%u] "
-
 void parse_args(int argc, char** argv, options_t* options)
 {
     int opt;
                 );
                 printf("Environment Variables:\n"
                 " VCPROMPT_FORMAT\n"
+                " VCPROMPT_FORMAT_GIT, VCPROMPT_FORMAT_HG, etc.\n"
                 );
                 exit(1);
         }
     }
 }
 
-void parse_format(options_t* options)
+void print_result(vccontext_t* context, result_t* result)
 {
     size_t i;
-
-    options->show_branch = 0;
-    options->show_unknown = 0;
-    options->show_modified = 0;
-
-    char* format = options->format;
-    size_t len = strlen(format);
-    for (i = 0; i < len; i++) {
-        if (format[i] == '%') {
-            i++;
-            switch (format[i]) {
-                case '\0':              /* at end of string: ignore */
-                    break;
-                case 'b':
-                    options->show_branch = 1;
-                    break;
-                case 'r':
-                    options->show_revision = 1;
-                    break;
-                case 'u':
-                    options->show_unknown = 1;
-                    break;
-                case 'm':
-                    options->show_modified = 1;
-                    break;
-                case 'n':               /* name of VC system */
-                case '%':
-                    break;
-                default:
-                    fprintf(stderr,
-                            "error: invalid format string: %%%c\n",
-                            format[i]);
-                    break;
-            }
-        }
-    }
-}
-
-void print_result(vccontext_t* context, options_t* options, result_t* result)
-{
-    size_t i;
-    char* format = options->format;
+    char* format = context->options.format;
     size_t len = strlen(format);
 
     for (i = 0; i < len; i++) {
 
 int main(int argc, char** argv)
 {
-    char* format = getenv("VCPROMPT_FORMAT");
-    if (format == NULL)
-        format = DEFAULT_FORMAT;
     options_t options = {
         .debug         = 0,
-        .format        = format,
+        .format        = NULL,
         .show_branch   = 0,
         .show_revision = 0,
         .show_unknown  = 0,
     };
 
     parse_args(argc, argv, &options);
-    parse_format(&options);
     set_debug(&options);
 
     vccontext_t* contexts[] = {
     /* Analyze the working copy metadata and print the result. */
     result = context->get_info(context);
     if (result != NULL) {
-        print_result(context, &options, result);
+        print_result(context, result);
         free_result(result);
         if (options.debug)
             putc('\n', stdout);