>From 96aef3d28edca9169c5166655733d022c79fc009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Diego=20Aur=C3=A9lio=20Mesquita?= Date: Mon, 12 Nov 2018 18:30:47 -0200 Subject: [PATCH 1/2] new feature: ability to toogle and jump to bookmarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added infrastructure to toogle and jump to bookmarks. A buffer can have multiple bookmarks but it can only have one bookmark per line. It is also possible jump to next or previous bookmark. For now, bookmarks are not visible in any way. Signed-off-by: Marco Diego Aurélio Mesquita --- src/global.c | 6 +++++ src/nano.c | 7 ++++++ src/nano.h | 2 ++ src/proto.h | 3 +++ src/text.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+) diff --git a/src/global.c b/src/global.c index a0d088c8..7cfd7b60 100644 --- a/src/global.c +++ b/src/global.c @@ -1529,6 +1529,12 @@ sc *strtosc(const char *input) s->func = do_undo; else if (!strcasecmp(input, "redo")) s->func = do_redo; + else if (!strcasecmp(input, "bookmark")) + s->func = bookmark; + else if (!strcasecmp(input, "bookmarknext")) + s->func = bookmark_next; + else if (!strcasecmp(input, "bookmarkprevious")) + s->func = bookmark_previous; #endif else if (!strcasecmp(input, "left") || !strcasecmp(input, "back")) diff --git a/src/nano.c b/src/nano.c index e121722a..75be3e2e 100644 --- a/src/nano.c +++ b/src/nano.c @@ -78,6 +78,10 @@ filestruct *make_new_node(filestruct *prevnode) newnode->prev = prevnode; newnode->next = NULL; newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1; +#ifndef NANO_TINY + /* We'll use SIZE_MAX as a sentinel value for non-bookmarked lines.*/ + newnode->bookmark_x = SIZE_MAX; +#endif #ifdef ENABLE_COLOR newnode->multidata = NULL; @@ -95,6 +99,9 @@ filestruct *copy_node(const filestruct *src) dst->next = src->next; dst->prev = src->prev; dst->lineno = src->lineno; +#ifndef NANO_TINY + dst->bookmark_x = src->bookmark_x; +#endif #ifdef ENABLE_COLOR dst->multidata = NULL; diff --git a/src/nano.h b/src/nano.h index 04aa3150..87aca1fe 100644 --- a/src/nano.h +++ b/src/nano.h @@ -279,6 +279,8 @@ typedef struct filestruct { /* Next node. */ struct filestruct *prev; /* Previous node. */ + size_t bookmark_x; + /* Bookmark position for this line. */ #ifdef ENABLE_COLOR short *multidata; /* Array of which multi-line regexes apply to this line. */ diff --git a/src/proto.h b/src/proto.h index 5923670f..f23f19ba 100644 --- a/src/proto.h +++ b/src/proto.h @@ -493,6 +493,9 @@ void do_find_bracket(void); /* Most functions in text.c. */ #ifndef NANO_TINY void do_mark(void); +void bookmark(void); +void bookmark_next(void); +void bookmark_previous(void); #endif void do_delete(void); void do_backspace(void); diff --git a/src/text.c b/src/text.c index 7190de5e..3bf68bb3 100644 --- a/src/text.c +++ b/src/text.c @@ -62,6 +62,83 @@ void do_mark(void) refresh_needed = TRUE; } } + +/* Whether the line is bookmarked. */ +bool is_bookmarked(filestruct *line) +{ + return line->bookmark_x != SIZE_MAX; +} + +/* Toggles bookmark. */ +void bookmark(void) +{ + if (is_bookmarked(openfile->current) && + openfile->current->bookmark_x != openfile->current_x){ + /* Handle the case of moving a bookmark on current line. */ + openfile->current->bookmark_x = openfile->current_x; + statusbar(_("Bookmark moved.")); + return; + } + + openfile->current->bookmark_x = is_bookmarked(openfile->current) ? + SIZE_MAX : + openfile->current_x; + + statusbar(is_bookmarked(openfile->current) ? + _("Bookmark added.") : + _("Bookmark removed.")); + refresh_needed = TRUE; +} + +/* Goes to next or previous bookmark. */ +void go_to_book_mark(bool next) +{ + filestruct *current = openfile->current; + bool iterate = TRUE; + const size_t current_x = openfile->current_x; + const size_t len = mbstrlen(current->data); + + if (is_bookmarked(current) && + current->bookmark_x != current_x) { + /* Special case when current line is bookmarked. */ + if (next && current->bookmark_x > current_x) { + iterate = FALSE; + /* Should handle the case when bookmard is beyond the end of line. */ + if (current->bookmark_x > len && current_x == len) + iterate = TRUE; + } else if (current->bookmark_x < openfile->current_x) + iterate = FALSE; + } + + if (iterate) { + do + current = next ? current->next : current->prev; + while(current != NULL && !is_bookmarked(current)); + + if (current == NULL) { + statusbar(next ? + _("No bookmark after this point.") : + _("No bookmark before this point.")); + return; + } + } + + openfile->current = current; + openfile->current_x = current->bookmark_x; + openfile->placewewant = xplustabs(); + refresh_needed = TRUE; +} + +void bookmark_next(void) +{ + go_to_book_mark(TRUE); +} + +void bookmark_previous(void) +{ + go_to_book_mark(FALSE); +} + #endif /* !NANO_TINY */ #if defined(ENABLE_COLOR) || defined(ENABLE_SPELLER) -- 2.11.0