summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Fonseca <jonas.fonseca@gmail.com>2014-03-17 22:36:59 -0400
committerJonas Fonseca <jonas.fonseca@gmail.com>2014-03-17 23:00:25 -0400
commit92397274f0a7bdb4b28e5af5131a8f65fd69d604 (patch)
treed034a2c9e04cc2e2bbf6d7ca29031f7a47aaaf24
parente10b5c03f87455ac0f885890aa6a568c373efba9 (diff)
Restrict cursor navigation to actionable linesgh-255-actionable-lines
This updates the status, grep, tree and help views to only allow the cursor to move to actionable lines. Fixes #255
-rw-r--r--include/tig/view.h5
-rw-r--r--src/grep.c16
-rw-r--r--src/help.c18
-rw-r--r--src/stage.c4
-rw-r--r--src/status.c16
-rw-r--r--src/tree.c2
-rw-r--r--src/view.c56
7 files changed, 84 insertions, 33 deletions
diff --git a/include/tig/view.h b/include/tig/view.h
index 64876869..d02123ed 100644
--- a/include/tig/view.h
+++ b/include/tig/view.h
@@ -31,6 +31,7 @@ struct line {
unsigned int dirty:1;
unsigned int cleareol:1;
unsigned int wrapped:1;
+ unsigned int noaction:1;
unsigned int user_flags:6;
void *data; /* User data */
@@ -295,14 +296,14 @@ void update_view_title(struct view *view);
* Line utilities.
*/
-struct line *add_line_at(struct view *view, unsigned long pos, const void *data, enum line_type type, size_t data_size, bool custom);
+struct line *add_line_at(struct view *view, unsigned long pos, const void *data, enum line_type type, size_t data_size, bool custom, bool noaction);
struct line *add_line(struct view *view, const void *data, enum line_type type, size_t data_size, bool custom);
struct line *add_line_alloc_(struct view *view, void **ptr, enum line_type type, size_t data_size, bool custom);
#define add_line_alloc(view, data_ptr, type, extra_size, custom) \
add_line_alloc_(view, (void **) data_ptr, type, sizeof(**data_ptr) + extra_size, custom)
-struct line *add_line_nodata(struct view *view, enum line_type type);
+struct line *add_line_nodata(struct view *view, enum line_type type, bool noaction);
struct line *add_line_text(struct view *view, const char *text, enum line_type type);
struct line * PRINTF_LIKE(3, 4) add_line_format(struct view *view, enum line_type type, const char *fmt, ...);
diff --git a/src/grep.c b/src/grep.c
index bdc0038b..47a80e0c 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -123,6 +123,9 @@ grep_open(struct view *view, enum open_flags flags)
opt_cmdline_argv = NULL;
}
+ if (!view->pos.lineno) //!check_position(&view->pos))
+ view->pos.lineno = 1;
+
if (!argv_append_array(&argv, grep_args) ||
!argv_append_array(&argv, grep_argv))
return FALSE;
@@ -204,7 +207,7 @@ grep_read(struct view *view, char *line)
}
if (!strcmp(line, "--"))
- return add_line_nodata(view, LINE_DELIMITER) != NULL;
+ return add_line_nodata(view, LINE_DELIMITER, TRUE) != NULL;
lineno = io_memchr(&view->io, line, 0);
text = io_memchr(&view->io, lineno + 1, 0);
@@ -217,10 +220,17 @@ grep_read(struct view *view, char *line)
textlen = strlen(text);
file = get_path(line);
- if (!file ||
- (file != state->last_file && !add_line_text(view, file, LINE_FILENAME)))
+ if (!file)
return FALSE;
+ if (file != state->last_file) {
+ struct line *filename = add_line_text(view, file, LINE_FILENAME);
+
+ if (!filename)
+ return FALSE;
+ filename->noaction = TRUE;
+ }
+
if (!add_line_alloc(view, &grep, LINE_DEFAULT, textlen, FALSE))
return FALSE;
diff --git a/src/help.c b/src/help.c
index d3509d86..1f4362e5 100644
--- a/src/help.c
+++ b/src/help.c
@@ -132,17 +132,19 @@ struct help_request_iterator {
const char *group;
};
-static bool
+static struct line *
add_help_line(struct view *view, struct help **help_ptr, struct keymap *keymap, enum line_type type)
{
struct help *help;
+ struct line *line = add_line_alloc(view, &help, type, 0, FALSE);
- if (!add_line_alloc(view, &help, type, 0, FALSE))
- return FALSE;
+ if (!line)
+ return NULL;
help->keymap = keymap;
if (help_ptr)
*help_ptr = help;
- return TRUE;
+ line->noaction = !keymap;
+ return line;
}
static bool
@@ -229,17 +231,21 @@ help_open(struct view *view, enum open_flags flags)
{
struct keymap *keymap;
struct help *help;
+ struct line *line;
reset_view(view);
- if (!add_help_line(view, &help, NULL, LINE_DEFAULT))
+ if (!(line = add_help_line(view, &help, NULL, LINE_DEFAULT)))
return FALSE;
help->data.text = "Quick reference for tig keybindings:";
- if (!add_help_line(view, &help, NULL, LINE_DEFAULT))
+ if (!(line = add_help_line(view, &help, NULL, LINE_DEFAULT)))
return FALSE;
help->data.text = "";
+ if (!check_position(&view->prev_pos))
+ view->prev_pos.lineno = 2;
+
for (keymap = get_keymaps(); keymap; keymap = keymap->next) {
struct help_request_iterator iterator = { view, keymap, TRUE };
diff --git a/src/stage.c b/src/stage.c
index fd646509..6d673546 100644
--- a/src/stage.c
+++ b/src/stage.c
@@ -263,13 +263,13 @@ stage_insert_chunk(struct view *view, struct chunk_header *header,
if (!to)
return from;
- if (!add_line_at(view, after_lineno++, buf, LINE_DIFF_CHUNK, strlen(buf) + 1, FALSE))
+ if (!add_line_at(view, after_lineno++, buf, LINE_DIFF_CHUNK, strlen(buf) + 1, FALSE, FALSE))
return NULL;
while (from_lineno < to_lineno) {
struct line *line = &view->line[from_lineno++];
- if (!add_line_at(view, after_lineno++, line->data, line->type, strlen(line->data) + 1, FALSE))
+ if (!add_line_at(view, after_lineno++, line->data, line->type, strlen(line->data) + 1, FALSE, FALSE))
return FALSE;
}
diff --git a/src/status.c b/src/status.c
index 4e345031..c1f9eae6 100644
--- a/src/status.c
+++ b/src/status.c
@@ -77,12 +77,12 @@ status_run(struct view *view, const char *argv[], char status, enum line_type ty
struct status *unmerged = NULL;
char *buf;
struct io io;
+ struct line *section_line;
- if (!io_run(&io, IO_RD, repo.cdup, opt_env, argv))
+ if (!io_run(&io, IO_RD, repo.cdup, opt_env, argv) ||
+ !(section_line = add_line_nodata(view, type, FALSE)))
return FALSE;
- add_line_nodata(view, type);
-
while ((buf = io_get(&io, 0, TRUE))) {
struct status *file = unmerged;
@@ -140,8 +140,10 @@ error_out:
return FALSE;
}
- if (!view->line[view->lines - 1].data)
- add_line_nodata(view, LINE_STAT_NONE);
+ if (!view->line[view->lines - 1].data) {
+ section_line->noaction = TRUE;
+ add_line_nodata(view, LINE_STAT_NONE, TRUE);
+ }
io_done(&io);
return TRUE;
@@ -255,8 +257,10 @@ status_open(struct view *view, enum open_flags flags)
}
reset_view(view);
+ if (!check_position(&view->prev_pos))
+ view->prev_pos.lineno = 1;
- add_line_nodata(view, LINE_STAT_HEAD);
+ add_line_nodata(view, LINE_STAT_HEAD, TRUE);
status_update_onbranch();
io_run_bg(update_index_argv);
diff --git a/src/tree.c b/src/tree.c
index cac154fc..80634e70 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -147,6 +147,8 @@ tree_entry(struct view *view, enum line_type type, const char *path,
if (id)
string_copy_rev(entry->id, id);
entry->size = size;
+ if (type == LINE_TREE_HEAD)
+ line->noaction = TRUE;
return line;
}
diff --git a/src/view.c b/src/view.c
index fac1f003..fda2a234 100644
--- a/src/view.c
+++ b/src/view.c
@@ -32,7 +32,7 @@ goto_view_line(struct view *view, unsigned long offset, unsigned long lineno)
if (offset > lineno || offset + view->height <= lineno) {
unsigned long half = view->height / 2;
- if (lineno > half)
+ if (lineno > half && view->lines <= view->height)
offset = lineno - half;
else
offset = 0;
@@ -167,6 +167,7 @@ scroll_view(struct view *view, enum request request)
void
move_view(struct view *view, enum request request)
{
+ struct position pos = view->pos;
int scroll_steps = 0;
int steps;
@@ -203,18 +204,33 @@ move_view(struct view *view, enum request request)
die("request %d not handled in switch", request);
}
- if (steps <= 0 && view->pos.lineno == 0) {
- report("Cannot move beyond the first line");
- return;
+ while (TRUE) {
+ if (steps <= 0 && pos.lineno == 0) {
+ if (pos.lineno != view->pos.lineno)
+ report("No selectable line above this line");
+ else
+ report("Cannot move beyond the first line");
+ return;
- } else if (steps >= 0 && view->pos.lineno + 1 >= view->lines) {
- report("Cannot move beyond the last line");
- return;
+ } else if (steps >= 0 && pos.lineno + 1 >= view->lines) {
+ if (pos.lineno != view->pos.lineno)
+ report("No selectable line below this line");
+ else
+ report("Cannot move beyond the last line");
+ return;
+ }
+
+ /* Move the current line */
+ pos.lineno += steps;
+ assert(0 <= pos.lineno && pos.lineno < view->lines);
+
+ if (!view->line[pos.lineno].noaction)
+ break;
+ steps = steps > 0 ? 1 : -1;
}
- /* Move the current line */
- view->pos.lineno += steps;
- assert(0 <= view->pos.lineno && view->pos.lineno < view->lines);
+ steps = pos.lineno - view->pos.lineno;
+ view->pos = pos;
/* Check whether the view needs to be scrolled */
if (view->pos.lineno < view->pos.offset ||
@@ -477,6 +493,13 @@ restore_view_position(struct view *view)
view_is_displayed(view))
werase(view->win);
+ if (view->line[view->pos.lineno].noaction) {
+ if (view->prev_pos.lineno < view->pos.lineno)
+ move_view(view, REQ_MOVE_UP);
+ else
+ move_view(view, REQ_MOVE_DOWN);
+ }
+
view->pos.col = view->prev_pos.col;
clear_position(&view->prev_pos);
@@ -849,7 +872,7 @@ find_line_by_type(struct view *view, struct line *line, enum line_type type, int
DEFINE_ALLOCATOR(realloc_lines, struct line, 256)
struct line *
-add_line_at(struct view *view, unsigned long pos, const void *data, enum line_type type, size_t data_size, bool custom)
+add_line_at(struct view *view, unsigned long pos, const void *data, enum line_type type, size_t data_size, bool custom, bool noaction)
{
struct line *line;
unsigned long lineno;
@@ -887,6 +910,7 @@ add_line_at(struct view *view, unsigned long pos, const void *data, enum line_ty
line->type = type;
line->data = (void *) data;
line->dirty = 1;
+ line->noaction = noaction;
if (custom)
view->custom_lines++;
@@ -899,7 +923,7 @@ add_line_at(struct view *view, unsigned long pos, const void *data, enum line_ty
struct line *
add_line(struct view *view, const void *data, enum line_type type, size_t data_size, bool custom)
{
- return add_line_at(view, view->lines, data, type, data_size, custom);
+ return add_line_at(view, view->lines, data, type, data_size, custom, 0);
}
struct line *
@@ -913,9 +937,13 @@ add_line_alloc_(struct view *view, void **ptr, enum line_type type, size_t data_
}
struct line *
-add_line_nodata(struct view *view, enum line_type type)
+add_line_nodata(struct view *view, enum line_type type, bool noaction)
{
- return add_line(view, NULL, type, 0, FALSE);
+ struct line *line = add_line(view, NULL, type, 0, FALSE);
+
+ if (line)
+ line->noaction = !!noaction;
+ return line;
}
struct line *