Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/tig/line.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ struct ref;
_(PP_REFS, "Refs: "), \
_(PP_REFLOG, "Reflog: "), \
_(PP_REFLOGMSG, "Reflog message: "), \
_(PP_AUTHOR, "Author: " ), \
_(PP_DATE, "Date: "), \
_(PP_AUTHORDATE, "AuthorDate: "), \
_(PP_COMMITTER, "Commit: " ), \
_(PP_COMMITDATE, "CommitDate: "), \
_(COMMIT, "commit "), \
_(PARENT, "parent "), \
_(TREE, "tree "), \
Expand Down Expand Up @@ -84,6 +89,7 @@ struct ref;
_(STAT_UNTRACKED, ""), \
_(HELP_GROUP, ""), \
_(HELP_ACTION, ""), \
_(HELP_TOGGLE, ""), \
_(DIFF_STAT, ""), \
_(PALETTE_0, ""), \
_(PALETTE_1, ""), \
Expand Down
4 changes: 2 additions & 2 deletions include/tig/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ typedef struct view_column *view_settings;
_(vertical_split, enum vertical_split, VIEW_RESET_DISPLAY | VIEW_DIFF_LIKE) \
_(wrap_lines, bool, VIEW_DIFF_LIKE) \
_(wrap_search, bool, VIEW_NO_FLAGS) \
_(committer, bool, VIEW_LOG_LIKE | VIEW_BLAME_LIKE) \

#define DEFINE_OPTION_EXTERNS(name, type, flags) extern type opt_##name;
OPTION_INFO(DEFINE_OPTION_EXTERNS)
Expand All @@ -111,7 +112,6 @@ OPTION_INFO(DEFINE_OPTION_EXTERNS)

#define DATE_COLUMN_OPTIONS(_) \
_(display, enum date, VIEW_NO_FLAGS) \
_(use_author, bool, VIEW_BLAME_LIKE | VIEW_LOG_LIKE) \
_(local, bool, VIEW_NO_FLAGS) \
_(format, const char *, VIEW_NO_FLAGS) \
_(width, int, VIEW_NO_FLAGS) \
Expand Down Expand Up @@ -198,7 +198,7 @@ void update_options_from_argv(const char *argv[]);
const char *ignore_space_arg();
const char *commit_order_arg();
const char *commit_order_arg_with_graph(enum graph_display graph_display);
const char *log_custom_pretty_arg(bool use_author_date);
const char *log_custom_pretty_arg();
const char *use_mailmap_arg();
const char *diff_context_arg();
const char *diff_prefix_arg();
Expand Down
2 changes: 1 addition & 1 deletion include/tig/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct blame_header {
};

bool parse_blame_header(struct blame_header *header, const char *text);
bool parse_blame_info(struct blame_commit *commit, char author[SIZEOF_STR], char *line, bool use_author_date);
bool parse_blame_info(struct blame_commit *commit, char author[SIZEOF_STR], char *line);

/* Parse author lines where the name may be empty:
* author <email@address.tld> 1138474660 +0100
Expand Down
1 change: 1 addition & 0 deletions include/tig/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum view_flag {
VIEW_SORTABLE = 1 << 16,
VIEW_FLEX_WIDTH = 1 << 17,
VIEW_RESET_DISPLAY = 1 << 18,
VIEW_COMMIT_NAMEDATE = 1 << 19,
};

#define view_has_flags(view, flag) ((view)->ops->flags & (flag))
Expand Down
6 changes: 2 additions & 4 deletions src/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,6 @@ static bool
blame_read(struct view *view, struct buffer *buf, bool force_stop)
{
struct blame_state *state = view->private;
struct view_column *column = get_view_column(view, VIEW_COLUMN_DATE);
bool use_author_date = column && column->opt.date.use_author;

if (!buf) {
if (failed_to_load_initial_view(view))
Expand Down Expand Up @@ -255,7 +253,7 @@ blame_read(struct view *view, struct buffer *buf, bool force_stop)

state->commit = NULL;

} else if (parse_blame_info(state->commit, state->author, buf->data, use_author_date)) {
} else if (parse_blame_info(state->commit, state->author, buf->data)) {
if (!state->commit->filename)
return false;

Expand Down Expand Up @@ -504,7 +502,7 @@ blame_select(struct view *view, struct line *line)
static struct view_ops blame_ops = {
"line",
argv_env.commit,
VIEW_SEND_CHILD_ENTER | VIEW_BLAME_LIKE | VIEW_REFRESH,
VIEW_SEND_CHILD_ENTER | VIEW_BLAME_LIKE | VIEW_REFRESH | VIEW_COMMIT_NAMEDATE,
sizeof(struct blame_state),
blame_open,
blame_read,
Expand Down
2 changes: 1 addition & 1 deletion src/diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ diff_blame_line(const char *ref, const char *file, unsigned long lineno,
break;
header = NULL;

} else if (parse_blame_info(commit, author, buf.data, false)) {
} else if (parse_blame_info(commit, author, buf.data)) {
ok = commit->filename != NULL;
break;
}
Expand Down
108 changes: 95 additions & 13 deletions src/help.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,21 @@
#include "tig/argv.h"
#include "tig/view.h"
#include "tig/search.h"
#include "tig/prompt.h"
#include "tig/draw.h"

extern const struct menu_item toggle_menu_items[];

static const char collapse_expand_names[2][14] = {
"Collapse all", "Expand all"
};
static struct keymap collapse_expand_keymap = {
collapse_expand_names[0], NULL, 0, false
};
static struct keymap toggle_menu_keymap = {
"toggle", NULL, 0, false
};

/*
* Help backend
*/
Expand All @@ -26,8 +39,11 @@ struct help_state {
};

struct help {
struct keymap *keymap;
enum request request;
union {
struct keymap *keymap;
struct menu_item *menu;
} item;
union {
const char *text;
const struct request_info *req_info;
Expand All @@ -38,16 +54,31 @@ static bool
help_draw(struct view *view, struct line *line, unsigned int lineno)
{
struct help *help = line->data;
const struct keymap *keymap = help->keymap;
const struct keymap *keymap = help->item.keymap;
struct help_state *state = view->private;

if (line->type == LINE_SECTION) {
draw_formatted(view, line->type, "[%c] %s bindings",
keymap->hidden ? '+' : '-', keymap->name);
if (line->type == LINE_SECTION && keymap) {
draw_formatted(view, line->type, "[%c] %s %s",
keymap->hidden ? '+' : '-', keymap->name,
(keymap == &collapse_expand_keymap) ? "sections" : "bindings" );

} else if (line->type == LINE_HELP_GROUP || !keymap) {
draw_text(view, line->type, help->data.text);

} else if (line->type == LINE_HELP_TOGGLE) {
struct menu_item *item = help->item.menu;
char text_buf[40];

snprintf(text_buf, sizeof(text_buf), "%c", item->hotkey);
if (draw_field(view, LINE_DEFAULT, text_buf, 28, ALIGN_RIGHT, false))
return true;

if (draw_field(view, LINE_HELP_ACTION, (char*)item->data, 28, ALIGN_LEFT, false))
return true;

snprintf(text_buf, sizeof(text_buf), "Toggle %s", item->text);
draw_text(view, LINE_DEFAULT, text_buf);

} else if (help->request > REQ_RUN_REQUESTS) {
struct run_request *req = get_run_request(help->request);
const char *key = get_keys(keymap, help->request, true);
Expand Down Expand Up @@ -83,9 +114,9 @@ static bool
help_grep(struct view *view, struct line *line)
{
struct help *help = line->data;
const struct keymap *keymap = help->keymap;
const struct keymap *keymap = help->item.keymap;

if (line->type == LINE_SECTION) {
if (line->type == LINE_SECTION && keymap) {
const char *text[] = { keymap->name, NULL };

return grep_text(view, text);
Expand All @@ -95,6 +126,10 @@ help_grep(struct view *view, struct line *line)

return grep_text(view, text);

} else if (line->type == LINE_HELP_TOGGLE) {
const char *text[] = { help->item.menu->text, NULL };

return grep_text(view, text);
} else if (help->request > REQ_RUN_REQUESTS) {
struct run_request *req = get_run_request(help->request);
const char *key = get_keys(keymap, help->request, true);
Expand Down Expand Up @@ -127,7 +162,7 @@ add_help_line(struct view *view, struct help **help_ptr, struct keymap *keymap,

if (!add_line_alloc(view, &help, type, 0, false))
return false;
help->keymap = keymap;
help->item.keymap = keymap;
if (help_ptr)
*help_ptr = help;
return true;
Expand All @@ -145,15 +180,15 @@ help_keys_visitor(void *data, const char *group, struct keymap *keymap,

if (iterator->keymap != keymap) {
iterator->keymap = keymap;
if (!add_help_line(iterator->view, &help, keymap, LINE_SECTION))
if (!add_help_line(view, &help, keymap, LINE_SECTION))
return false;
}

if (keymap->hidden)
return true;

if (group) {
if (!add_help_line(iterator->view, &help, keymap, LINE_HELP_GROUP))
if (!add_help_line(view, &help, keymap, LINE_HELP_GROUP))
return false;
help->data.text = group;
}
Expand All @@ -172,24 +207,64 @@ help_keys_visitor(void *data, const char *group, struct keymap *keymap,
return true;
}

static bool
help_collapse_expand_keys_visitor(void *data, const char *group, struct keymap *keymap,
enum request request, const char *key,
const struct request_info *req_info, const struct run_request *run_req)
{
struct help_request_iterator *iterator = data;

if (iterator->keymap != keymap) {
iterator->keymap = keymap;
keymap->hidden = collapse_expand_keymap.hidden;
}

return true;
}

static enum status_code
help_open(struct view *view, enum open_flags flags)
{
struct help_request_iterator iterator = { view };
struct help *help;
const struct menu_item *menu = toggle_menu_items;
int i;

reset_view(view);

if (!add_help_line(view, &help, NULL, LINE_HEADER))
return ERROR_OUT_OF_MEMORY;
help->data.text = "Quick reference for tig keybindings:";

if (!add_help_line(view, &help, &collapse_expand_keymap, LINE_SECTION))
return ERROR_OUT_OF_MEMORY;

if (!add_help_line(view, &help, NULL, LINE_DEFAULT))
return ERROR_OUT_OF_MEMORY;
help->data.text = "";

return foreach_key(help_keys_visitor, &iterator, true)
? SUCCESS : error("Failed to render key bindings");
if (!foreach_key(help_keys_visitor, &iterator, true)) {
error("Failed to render key bindings");
return ERROR_OUT_OF_MEMORY;
}

if (!add_help_line(view, &help, &toggle_menu_keymap, LINE_SECTION))
return ERROR_OUT_OF_MEMORY;
if (!toggle_menu_keymap.hidden) {
if (!add_help_line(view, &help, NULL, LINE_HELP_GROUP))
return ERROR_OUT_OF_MEMORY;
help->data.text = "Toggle keys (enter: o <key>):";

i = 0;
while (menu[i].data)
{
if (!add_help_line(view, &help, (struct keymap *)&menu[i], LINE_HELP_TOGGLE))
return ERROR_OUT_OF_MEMORY;
i++;
}
}

return SUCCESS;
}

static enum request
Expand All @@ -200,9 +275,16 @@ help_request(struct view *view, enum request request, struct line *line)
switch (request) {
case REQ_ENTER:
if (line->type == LINE_SECTION) {
struct keymap *keymap = help->keymap;
struct keymap *keymap = help->item.keymap;

keymap->hidden = !keymap->hidden;
if (keymap == &collapse_expand_keymap) {
struct help_request_iterator iterator = { view };

collapse_expand_keymap.name = collapse_expand_names[keymap->hidden];
foreach_key(help_collapse_expand_keys_visitor, &iterator, true);
toggle_menu_keymap.hidden = keymap->hidden;
}
refresh_view(view);
}
return REQ_NONE;
Expand Down
47 changes: 45 additions & 2 deletions src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct log_state {
bool commit_title_read;
bool after_commit_header;
bool reading_diff_stat;
bool external_format;
};

static inline void
Expand Down Expand Up @@ -63,16 +64,38 @@ log_select(struct view *view, struct line *line)
state->last_type = line->type;
}

static bool
log_check_external_formatter()
{
/* check if any formatter arugments in "%(logargs)", "%(cmdlineargs)" */
const char ** opt_list[] = {
opt_log_options,
opt_cmdline_args,
};
for (int i=0; i<ARRAY_SIZE(opt_list); i++) {
if (opt_list[i] &&
(argv_containsn(opt_list[i], "--pretty", STRING_SIZE("--pretty")) ||
argv_containsn(opt_list[i], "--format", STRING_SIZE("--format"))))
return true;
}
return false;
}

static enum status_code
log_open(struct view *view, enum open_flags flags)
{
struct log_state *state = view->private;
bool external_format = log_check_external_formatter();
const char *log_argv[] = {
"git", "log", encoding_arg, commit_order_arg(),
use_mailmap_arg(), "%(logargs)", "%(cmdlineargs)",
"%(revargs)", "--no-color", "--", "%(fileargs)", NULL
"%(revargs)", "--no-color",
external_format ? "" : "--pretty=fuller",
"--", "%(fileargs)", NULL
};
enum status_code code;

state->external_format = external_format;
code = begin_update(view, NULL, log_argv, flags | OPEN_WITH_STDERR);
if (code != SUCCESS)
return code;
Expand Down Expand Up @@ -148,6 +171,25 @@ log_read(struct view *view, struct buffer *buf, bool force_stop)
state->reading_diff_stat = false;
}

if (!state->external_format) {
switch (type)
{
case LINE_PP_AUTHOR:
case LINE_PP_AUTHORDATE:
case LINE_PP_DATE:
if (opt_committer)
return true;
break;
case LINE_PP_COMMITTER:
case LINE_PP_COMMITDATE:
if (!opt_committer)
return true;
break;
default:
break;
}
}

if (!pager_common_read(view, data, type, &line))
return false;
if (line && state->graph_indent)
Expand All @@ -158,7 +200,8 @@ log_read(struct view *view, struct buffer *buf, bool force_stop)
static struct view_ops log_ops = {
"line",
argv_env.head,
VIEW_ADD_PAGER_REFS | VIEW_OPEN_DIFF | VIEW_SEND_CHILD_ENTER | VIEW_LOG_LIKE | VIEW_REFRESH | VIEW_FLEX_WIDTH,
VIEW_ADD_PAGER_REFS | VIEW_OPEN_DIFF | VIEW_SEND_CHILD_ENTER | VIEW_LOG_LIKE | VIEW_REFRESH | \
VIEW_FLEX_WIDTH | VIEW_COMMIT_NAMEDATE,
sizeof(struct log_state),
log_open,
log_read,
Expand Down
Loading