diff --git a/ep.c b/ep.c index 3f3153e..2e29bf5 100644 --- a/ep.c +++ b/ep.c @@ -47,7 +47,7 @@ int main(int argc, char **argv) /* start threads for long(er) running steps */ pthread_t git_handle; - if (pthread_create(&git_handle, NULL, get_git_branch_name, NULL)) { + if (pthread_create(&git_handle, NULL, git_thread, NULL)) { e(WARN, "couldn't create git thread", errno); } @@ -67,10 +67,7 @@ int main(int argc, char **argv) /* git status */ pthread_join(git_handle, NULL); - if (git_branch_name) { - p(" "); - p(git_branch_name); - } + print_git(); /* print currently active shell jobs */ if (shell_jobs) { diff --git a/ep.h b/ep.h index 8541b0b..2f313bb 100644 --- a/ep.h +++ b/ep.h @@ -15,7 +15,7 @@ extern const int fish_style_dir; void print_pwd(const char *); /* from git.c */ -extern char *git_branch_name; -void *get_git_branch_name(void *); +void *git_thread(void *); +void print_git(void); #endif diff --git a/git.c b/git.c index 7c1f956..545b55a 100644 --- a/git.c +++ b/git.c @@ -1,30 +1,88 @@ +#include #include +#include #include "ep.h" -char *git_branch_name; +static char *git_branch_name, *git_status; +void print_git(void) +{ + if (git_branch_name) { + p(" "); + p(git_branch_name); -void *get_git_branch_name(void *arg) + if (git_status) { + p(" ["); + p(git_status); + p("]"); + } + } +} + +struct rlfc_data { + char *line; + size_t n; + ssize_t l; + int status; +}; + +static void read_line_from_command(const char *c, struct rlfc_data *d) { FILE *f = popen("git rev-parse --abbrev-ref HEAD 2>/dev/null", "re"); - if (!f) { + if (!f) + return; + + d->l = getline(&d->line, &d->n, f); + d->status = pclose(f); +} + +static char *get_git_status(void); + +void *git_thread(void *arg) +{ + struct rlfc_data c = { 0 }; + read_line_from_command("git rev-parse --abbrev-ref HEAD 2>/dev/null", &c); + + if (!c.status) { + /* if git exits with 0, we are in a repo */ + + if (c.l > 0) { + /* TODO: treat case where it reads HEAD */ + c.line[c.l-1] = 0; + /* line ownserhip goes to outside this function */ + git_branch_name = c.line; + } + } else { return NULL; } - char *line = NULL; - size_t n = 0; - ssize_t l = getline(&line, &n, f); + /* since we are in a repo, read git status; + * if we add more stuff to do in repos, launch more threads */ - if (!pclose(f)) { - /* if git exits with 0, we are in a repo */ - - if (l > 0) { - /* TODO: treat case where it reads HEAD */ - line[l-1] = 0; - /* line ownserhip goes to outside this function */ - git_branch_name = line; - } - } + get_git_status(); return NULL; } + +static char *get_git_status(void) +{ + size_t modified = 0; + + FILE *f = popen("git status --porcelain=v1 -z 2>/dev/null", "re"); + if (!f) + return NULL; + + char *line = NULL; + size_t n = 0; + ssize_t l; + while ((l = getdelim(&line, &n, 0, f)) != -1) { + modified += l>4 && line[1] == 'M'; + } + free(line); + + if (!pclose(f)) { + asprintf(&git_status, "~%zu", modified); + } + + return git_status; +}