struct encoding * get_path_encoding(const char *path, struct encoding *default_encoding) { const char *check_attr_argv[] = { "git", "check-attr", "encoding", "--", path, NULL }; char buf[SIZEOF_STR]; char *encoding; /* <path>: encoding: <encoding> */ if (!*path || !io_run_buf(check_attr_argv, buf, sizeof(buf)) || !(encoding = strstr(buf, ENCODING_SEP))) return default_encoding; encoding += STRING_SIZE(ENCODING_SEP); if (!strcmp(encoding, ENCODING_UTF8) || !strcmp(encoding, "unspecified") || !strcmp(encoding, "set")) { const char *file_argv[] = { "file", "-I", "--", path, NULL }; if (!*path || !io_run_buf(file_argv, buf, sizeof(buf)) || !(encoding = strstr(buf, CHARSET_SEP))) return default_encoding; encoding += STRING_SIZE(CHARSET_SEP); } return encoding_open(encoding); }
static bool blob_open(struct view *view, enum open_flags flags) { static const char *blob_argv[] = { "git", "cat-file", "blob", "%(blob)", NULL }; if (!view->env->blob[0] && view->env->file[0]) { const char *commit = view->env->commit[0] ? view->env->commit : "HEAD"; char blob_spec[SIZEOF_STR]; const char *rev_parse_argv[] = { "git", "rev-parse", blob_spec, NULL }; if (!string_format(blob_spec, "%s:%s", commit, view->env->file) || !io_run_buf(rev_parse_argv, view->env->blob, sizeof(view->env->blob))) { report("Failed to resolve blob from file name"); return FALSE; } } if (!view->env->blob[0]) { report("No file chosen, press %s to open tree view", get_view_key(view, REQ_VIEW_TREE)); return FALSE; } view->encoding = get_path_encoding(view->env->file, default_encoding); return begin_update(view, NULL, blob_argv, flags); }
static int reload_refs(bool force) { const char *head_argv[] = { "git", "symbolic-ref", "HEAD", NULL }; const char *ls_remote_argv[SIZEOF_ARG] = { "git", "ls-remote", repo.git_dir, NULL }; static bool init = FALSE; struct ref_opt opt = { repo.remote, repo.head, WATCH_NONE }; struct repo_info old_repo = repo; size_t i; if (!init) { if (!argv_from_env(ls_remote_argv, "TIG_LS_REMOTE")) return ERR; init = TRUE; } if (!*repo.git_dir) return OK; if ((force || !*repo.head) && io_run_buf(head_argv, repo.head, sizeof(repo.head)) && !prefixcmp(repo.head, "refs/heads/")) { char *offset = repo.head + STRING_SIZE("refs/heads/"); memmove(repo.head, offset, strlen(offset) + 1); } if (strcmp(old_repo.head, repo.head)) opt.changed |= WATCH_HEAD; refs_head = NULL; for (i = 0; i < refs_size; i++) refs[i]->valid = 0; done_ref_lists(); if (io_run_load(ls_remote_argv, "\t", read_ref, &opt) == ERR) return ERR; for (i = 0; i < refs_size; i++) if (!refs[i]->valid) { refs[i]->id[0] = 0; opt.changed |= WATCH_REFS; } if (opt.changed) watch_apply(NULL, opt.changed); qsort(refs, refs_size, sizeof(*refs), compare_refs); return OK; }
static bool add_describe_ref(char *buf, size_t *bufpos, const char *commit_id, const char *sep) { const char *describe_argv[] = { "git", "describe", commit_id, NULL }; char ref[SIZEOF_STR]; if (!io_run_buf(describe_argv, ref, sizeof(ref)) || !*ref) return TRUE; /* This is the only fatal call, since it can "corrupt" the buffer. */ if (!string_nformat(buf, SIZEOF_STR, bufpos, "%s%s", sep, ref)) return FALSE; return TRUE; }
static int reload_refs(const char *git_dir, const char *remote_name, char *head, size_t headlen) { const char *head_argv[] = { "git", "symbolic-ref", "HEAD", NULL }; const char *ls_remote_argv[SIZEOF_ARG] = { "git", "ls-remote", git_dir, NULL }; static bool init = FALSE; struct ref_opt opt = { remote_name, head }; size_t i; if (!init) { if (!argv_from_env(ls_remote_argv, "TIG_LS_REMOTE")) return ERR; init = TRUE; } if (!*git_dir) return OK; if (!*head && io_run_buf(head_argv, head, headlen) && !prefixcmp(head, "refs/heads/")) { char *offset = head + STRING_SIZE("refs/heads/"); memmove(head, offset, strlen(offset) + 1); } refs_head = NULL; for (i = 0; i < refs_size; i++) refs[i]->valid = 0; done_ref_lists(); if (io_run_load(ls_remote_argv, "\t", read_ref, &opt) == ERR) return ERR; for (i = 0; i < refs_size; i++) if (!refs[i]->valid) refs[i]->id[0] = 0; qsort(refs, refs_size, sizeof(*refs), compare_refs); return OK; }
bool open_external_viewer(const char *argv[], const char *dir, bool silent, bool confirm, bool echo, bool refresh, const char *notice) { bool ok; if (echo) { char buf[SIZEOF_STR] = ""; io_run_buf(argv, buf, sizeof(buf), dir, false); if (*buf) { report("%s", buf); return true; } else { report("No output"); return false; } } else if (silent || is_script_executing()) { ok = io_run_bg(argv, dir); } else { clear(); refresh(); endwin(); /* restore original tty modes */ ok = io_run_fg(argv, dir); if (confirm || !ok) { if (!ok && *notice) fprintf(stderr, "%s", notice); fprintf(stderr, "Press Enter to continue"); getc(opt_tty); fseek(opt_tty, 0, SEEK_END); } set_terminal_modes(); } if (watch_update(WATCH_EVENT_AFTER_COMMAND) && refresh) { struct view *view; int i; foreach_displayed_view (view, i) { if (watch_dirty(&view->watch)) refresh_view(view); } } redraw_display(true); return ok; }