void print_columns(const struct string_list *list, unsigned int colopts, const struct column_options *opts) { struct column_options nopts; if (!list->nr) return; assert((colopts & COL_ENABLE_MASK) != COL_AUTO); memset(&nopts, 0, sizeof(nopts)); nopts.indent = opts && opts->indent ? opts->indent : ""; nopts.nl = opts && opts->nl ? opts->nl : "\n"; nopts.padding = opts ? opts->padding : 1; nopts.width = opts && opts->width ? opts->width : term_columns() - 1; if (!column_active(colopts)) { display_plain(list, "", "\n"); return; } switch (COL_LAYOUT(colopts)) { case COL_PLAIN: display_plain(list, nopts.indent, nopts.nl); break; case COL_ROW: case COL_COLUMN: display_table(list, colopts, &nopts); break; default: die("BUG: invalid layout mode %d", COL_LAYOUT(colopts)); } }
void setup_pager(void) { const char *pager = git_pager(isatty(1)); if (!pager) return; /* * force computing the width of the terminal before we redirect * the standard output to the pager. */ (void) term_columns(); setenv("GIT_PAGER_IN_USE", "true", 1); /* spawn the pager */ prepare_pager_args(&pager_process, pager); pager_process.in = -1; argv_array_push(&pager_process.env_array, "GIT_PAGER_IN_USE"); if (start_command(&pager_process)) return; /* original process continues, but writes to the pipe */ dup2(pager_process.in, 1); if (isatty(2)) dup2(pager_process.in, 2); close(pager_process.in); /* this makes sure that the parent terminates after the pager */ sigchain_push_common(wait_for_pager_signal); atexit(wait_for_pager_atexit); }
static void pretty_print_string_list(struct cmdnames *cmds, int longest) { int cols = 1, rows; int space = longest + 1; /* min 1 SP between words */ int max_cols = term_columns() - 1; /* don't print *on* the edge */ int i, j; if (space < max_cols) cols = max_cols / space; rows = DIV_ROUND_UP(cmds->cnt, cols); for (i = 0; i < rows; i++) { printf(" "); for (j = 0; j < cols; j++) { int n = j * rows + i; int size = space; if (n >= cmds->cnt) break; if (j == cols-1 || n + rows >= cmds->cnt) size = 1; printf("%-*s", size, cmds->names[n]->name); } putchar('\n'); } }
void setup_pager(void) { const char *pager = git_pager(isatty(1)); if (!pager) return; /* * force computing the width of the terminal before we redirect * the standard output to the pager. */ (void) term_columns(); setenv("GIT_PAGER_IN_USE", "true", 1); /* spawn the pager */ pager_argv[0] = pager; pager_process.use_shell = 1; pager_process.argv = pager_argv; pager_process.in = -1; if (!getenv("LESS") || !getenv("LV")) { static const char *env[3]; int i = 0; if (!getenv("LESS")) env[i++] = "LESS=FRX"; if (!getenv("LV")) env[i++] = "LV=-c"; env[i] = NULL; pager_process.env = env; } if (start_command(&pager_process)) return; /* original process continues, but writes to the pipe */ dup2(pager_process.in, 1); if (isatty(2)) dup2(pager_process.in, 2); close(pager_process.in); /* this makes sure that the parent terminates after the pager */ sigchain_push_common(wait_for_pager_signal); atexit(wait_for_pager); }
int cmd_column(int argc, const char **argv, const char *prefix) { struct string_list list = STRING_LIST_INIT_DUP; struct strbuf sb = STRBUF_INIT; struct column_options copts; const char *command = NULL, *real_command = NULL; struct option options[] = { OPT_STRING(0, "command", &real_command, N_("name"), N_("lookup config vars")), OPT_COLUMN(0, "mode", &colopts, N_("layout to use")), OPT_INTEGER(0, "raw-mode", &colopts, N_("layout to use")), OPT_INTEGER(0, "width", &copts.width, N_("Maximum width")), OPT_STRING(0, "indent", &copts.indent, N_("string"), N_("Padding space on left border")), OPT_INTEGER(0, "nl", &copts.nl, N_("Padding space on right border")), OPT_INTEGER(0, "padding", &copts.padding, N_("Padding space between columns")), OPT_END() }; git_config(platform_core_config, NULL); /* This one is special and must be the first one */ if (argc > 1 && starts_with(argv[1], "--command=")) { command = argv[1] + 10; git_config(column_config, (void *)command); } else git_config(column_config, NULL); memset(&copts, 0, sizeof(copts)); copts.width = term_columns(); copts.padding = 1; argc = parse_options(argc, argv, "", options, builtin_column_usage, 0); if (argc) usage_with_options(builtin_column_usage, options); if (real_command || command) { if (!real_command || !command || strcmp(real_command, command)) die(_("--command must be the first argument")); } finalize_colopts(&colopts, -1); while (!strbuf_getline(&sb, stdin)) string_list_append(&list, sb.buf); print_columns(&list, colopts, &copts); return 0; }
void setup_pager(void) { const char *pager = git_pager(isatty(1)); if (!pager) return; /* * After we redirect standard output, we won't be able to use an ioctl * to get the terminal size. Let's grab it now, and then set $COLUMNS * to communicate it to any sub-processes. */ { char buf[64]; xsnprintf(buf, sizeof(buf), "%d", term_columns()); setenv("COLUMNS", buf, 0); } setenv("GIT_PAGER_IN_USE", "true", 1); /* spawn the pager */ prepare_pager_args(&pager_process, pager); pager_process.in = -1; argv_array_push(&pager_process.env_array, "GIT_PAGER_IN_USE"); if (start_command(&pager_process)) return; /* original process continues, but writes to the pipe */ dup2(pager_process.in, 1); if (isatty(2)) dup2(pager_process.in, 2); close(pager_process.in); /* this makes sure that the parent terminates after the pager */ sigchain_push_common(wait_for_pager_signal); atexit(wait_for_pager_atexit); }
static size_t parse_padding_placeholder(struct strbuf *sb, const char *placeholder, struct format_commit_context *c) { const char *ch = placeholder; enum flush_type flush_type; int to_column = 0; switch (*ch++) { case '<': flush_type = flush_right; break; case '>': if (*ch == '<') { flush_type = flush_both; ch++; } else if (*ch == '>') { flush_type = flush_left_and_steal; ch++; } else flush_type = flush_left; break; default: return 0; } /* the next value means "wide enough to that column" */ if (*ch == '|') { to_column = 1; ch++; } if (*ch == '(') { const char *start = ch + 1; const char *end = start + strcspn(start, ",)"); char *next; int width; if (!end || end == start) return 0; width = strtol(start, &next, 10); if (next == start || width == 0) return 0; if (width < 0) { if (to_column) width += term_columns(); if (width < 0) return 0; } c->padding = to_column ? -width : width; c->flush_type = flush_type; if (*end == ',') { start = end + 1; end = strchr(start, ')'); if (!end || end == start) return 0; if (starts_with(start, "trunc)")) c->truncate = trunc_right; else if (starts_with(start, "ltrunc)")) c->truncate = trunc_left; else if (starts_with(start, "mtrunc)")) c->truncate = trunc_middle; else return 0; } else c->truncate = trunc_none; return end - placeholder + 1; } return 0; }