From 5ed64b2f123767ed1012d3ed8dabc2af77376a61 Mon Sep 17 00:00:00 2001
From: Daniel Carl <danielcarl@gmx.de>
Date: Mon, 8 Jul 2013 21:07:31 +0200
Subject: [PATCH] Added command 'bookmark-remove' or 'bmr'.

This allows to remove bookmark for bookmark file.
---
 doc/vimb.1.txt |  4 ++++
 src/bookmark.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/bookmark.h |  1 +
 src/command.c  | 10 +++++++++-
 4 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/doc/vimb.1.txt b/doc/vimb.1.txt
index 62a454f..e41cd30 100644
--- a/doc/vimb.1.txt
+++ b/doc/vimb.1.txt
@@ -320,6 +320,10 @@ commands and search queries.
 .TP
 .BI "bookmark-add [" TAGS "], bma [" TAGS ]
 Save the current opened uri with \fITAGS\fP to the bookmark file.
+.TP
+.BI "bookmark-remove [" URI "], bmr [" URI ]
+Removes all bookmarks for given \fIURI\fP or if not given the current opened
+page.
 
 .SS Misc
 .TP
diff --git a/src/bookmark.c b/src/bookmark.c
index 9ef4ba1..968449d 100644
--- a/src/bookmark.c
+++ b/src/bookmark.c
@@ -55,6 +55,49 @@ gboolean bookmark_add(const char *uri, const char *tags)
     return false;
 }
 
+gboolean bookmark_remove(const char *uri)
+{
+    char **lines, *line, *p;
+    int len, i;
+    GString *new;
+    gboolean removed = false;
+
+    if (!uri) {
+        return false;
+    }
+
+    lines = util_get_lines(vb.files[FILES_BOOKMARK]);
+    if (lines) {
+        new = g_string_new(NULL);
+        len = g_strv_length(lines) - 1;
+        for (i = 0; i < len; i++) {
+            line = lines[i];
+            g_strstrip(line);
+            /* ignore the bookmark tags and test only the uri */
+            if ((p = strchr(line, ' '))) {
+                *p = '\0';
+                if (!strcmp(uri, line)) {
+                    removed = true;
+                    continue;
+                } else {
+                    /* reappend the tags */
+                    *p = ' ';
+                }
+            }
+            if (!strcmp(uri, line)) {
+                removed = true;
+                continue;
+            }
+            g_string_append_printf(new, "%s\n", line);
+        }
+        g_strfreev(lines);
+        g_file_set_contents(vb.files[FILES_BOOKMARK], new->str, -1, NULL);
+        g_string_free(new, true);
+    }
+
+    return removed;
+}
+
 /**
  * Retrieves all bookmark uri matching the given space separated tags string.
  * Don't forget to free the returned list.
diff --git a/src/bookmark.h b/src/bookmark.h
index 0404601..8d8968c 100644
--- a/src/bookmark.h
+++ b/src/bookmark.h
@@ -21,6 +21,7 @@
 #define _BOOKMARK_H
 
 gboolean bookmark_add(const char *uri, const char *tags);
+gboolean bookmark_remove(const char *uri);
 GList *bookmark_get_by_tags(const char *tags);
 
 #endif /* end of include guard: _BOOKMARK_H */
diff --git a/src/command.c b/src/command.c
index 02aedf1..5aca6ff 100644
--- a/src/command.c
+++ b/src/command.c
@@ -113,6 +113,7 @@ static CommandInfo cmd_list[] = {
     {"hist-prev",                 NULL,    command_history,              {1}},
     {"run",                       NULL,    command_run_multi,            {0}},
     {"bookmark-add",              "bma",   command_bookmark,             {1}},
+    {"bookmark-remove",           "bmr",   command_bookmark,             {0}},
     {"eval",                      "e",     command_eval,                 {0}},
     {"editor",                    NULL,    command_editor,               {0}},
     {"next",                      "n",     command_nextprev,             {0}},
@@ -703,11 +704,18 @@ gboolean command_bookmark(const Arg *arg)
 {
     vb_set_mode(VB_MODE_NORMAL, false);
 
-    if (bookmark_add(GET_URI(), arg->s)) {
+    if (!arg->i) {
+        if (bookmark_remove(arg->s ? arg->s : GET_URI())) {
+            vb_echo_force(VB_MSG_NORMAL, false, "Bookmark removed");
+
+            return true;
+        }
+    } else if (bookmark_add(GET_URI(), arg->s)) {
         vb_echo_force(VB_MSG_NORMAL, false, "Bookmark added");
 
         return true;
     }
+
     return false;
 }
 
-- 
2.20.1