aboutsummaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2014-03-28 02:09:08 -0400
committerThiago de Arruda <tpadilha84@gmail.com>2014-03-29 20:47:39 -0300
commitd9f5cd6290755b0fc571c89db5f213844cbe9eef (patch)
treeae8e325f1cc2efbfc79cf59c7cc7f61e8ed38db8 /src/buffer.c
parent28b3659955d154d04ac8e531b54f1ec32f3136a7 (diff)
downloadrneovim-d9f5cd6290755b0fc571c89db5f213844cbe9eef.tar.gz
rneovim-d9f5cd6290755b0fc571c89db5f213844cbe9eef.tar.bz2
rneovim-d9f5cd6290755b0fc571c89db5f213844cbe9eef.zip
Re-integrate FEAT_SIGNS code, close #383
- omit FEAT_NETBEANS_INTG and FEAT_SIGN_ICONS - omit FEAT_GUI blocks
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c269
1 files changed, 269 insertions, 0 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 90f965f42d..4486611540 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -91,6 +91,7 @@ static void clear_wininfo(buf_T *buf);
# define dev_T unsigned
#endif
+static void insert_sign(buf_T *buf, signlist_T *prev, signlist_T *next, int id, linenr_T lnum, int typenr);
static char *msg_loclist = N_("[Location List]");
static char *msg_qflist = N_("[Quickfix List]");
@@ -568,6 +569,7 @@ free_buffer_stuff (
vars_clear(&buf->b_vars->dv_hashtab); /* free all internal variables */
hash_init(&buf->b_vars->dv_hashtab);
uc_clear(&buf->b_ucmds); /* clear local user commands */
+ buf_delete_signs(buf); /* delete any signs */
map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE); /* clear local mappings */
map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE); /* clear local abbrevs */
vim_free(buf->b_start_fenc);
@@ -4410,6 +4412,273 @@ win_found:
}
#endif
+/*
+ * Insert the sign into the signlist.
+ */
+static void insert_sign(
+ buf_T *buf, /* buffer to store sign in */
+ signlist_T *prev, /* previous sign entry */
+ signlist_T *next, /* next sign entry */
+ int id, /* sign ID */
+ linenr_T lnum, /* line number which gets the mark */
+ int typenr /* typenr of sign we are adding */
+ )
+{
+ signlist_T *newsign;
+
+ newsign = (signlist_T *)lalloc((long_u)sizeof(signlist_T), FALSE);
+ if (newsign != NULL) {
+ newsign->id = id;
+ newsign->lnum = lnum;
+ newsign->typenr = typenr;
+ newsign->next = next;
+
+ if (prev == NULL) {
+ /* When adding first sign need to redraw the windows to create the
+ * column for signs. */
+ if (buf->b_signlist == NULL) {
+ redraw_buf_later(buf, NOT_VALID);
+ changed_cline_bef_curs();
+ }
+
+ /* first sign in signlist */
+ buf->b_signlist = newsign;
+ }
+ else {
+ prev->next = newsign;
+ }
+ }
+}
+
+/*
+ * Add the sign into the signlist. Find the right spot to do it though.
+ */
+void buf_addsign(
+ buf_T *buf, /* buffer to store sign in */
+ int id, /* sign ID */
+ linenr_T lnum, /* line number which gets the mark */
+ int typenr /* typenr of sign we are adding */
+ )
+{
+ signlist_T *sign; /* a sign in the signlist */
+ signlist_T *prev; /* the previous sign */
+
+ prev = NULL;
+ for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
+ if (lnum == sign->lnum && id == sign->id) {
+ sign->typenr = typenr;
+ return;
+ }
+ else if (id < 0 /* keep signs sorted by lnum */
+ && lnum < sign->lnum)
+ {
+ insert_sign(buf, prev, sign, id, lnum, typenr);
+ return;
+ }
+ prev = sign;
+ }
+ insert_sign(buf, prev, sign, id, lnum, typenr);
+
+ return;
+}
+
+linenr_T buf_change_sign_type(
+ buf_T *buf, /* buffer to store sign in */
+ int markId, /* sign ID */
+ int typenr /* typenr of sign we are adding */
+ )
+{
+ signlist_T *sign; /* a sign in the signlist */
+
+ for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
+ if (sign->id == markId) {
+ sign->typenr = typenr;
+ return sign->lnum;
+ }
+ }
+
+ return (linenr_T)0;
+}
+
+int buf_getsigntype(
+ buf_T *buf,
+ linenr_T lnum,
+ int type /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */
+ )
+{
+ signlist_T *sign; /* a sign in a b_signlist */
+
+ for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
+ if (sign->lnum == lnum
+ && (type == SIGN_ANY
+ || (type == SIGN_TEXT
+ && sign_get_text(sign->typenr) != NULL)
+ || (type == SIGN_LINEHL
+ && sign_get_attr(sign->typenr, TRUE) != 0))) {
+ return sign->typenr;
+ }
+ }
+ return 0;
+}
+
+
+linenr_T buf_delsign(
+ buf_T *buf, /* buffer sign is stored in */
+ int id /* sign id */
+ )
+{
+ signlist_T **lastp; /* pointer to pointer to current sign */
+ signlist_T *sign; /* a sign in a b_signlist */
+ signlist_T *next; /* the next sign in a b_signlist */
+ linenr_T lnum; /* line number whose sign was deleted */
+
+ lastp = &buf->b_signlist;
+ lnum = 0;
+ for (sign = buf->b_signlist; sign != NULL; sign = next) {
+ next = sign->next;
+ if (sign->id == id) {
+ *lastp = next;
+ lnum = sign->lnum;
+ vim_free(sign);
+ break;
+ } else {
+ lastp = &sign->next;
+ }
+ }
+
+ /* When deleted the last sign needs to redraw the windows to remove the
+ * sign column. */
+ if (buf->b_signlist == NULL) {
+ redraw_buf_later(buf, NOT_VALID);
+ changed_cline_bef_curs();
+ }
+
+ return lnum;
+}
+
+
+/*
+ * Find the line number of the sign with the requested id. If the sign does
+ * not exist, return 0 as the line number. This will still let the correct file
+ * get loaded.
+ */
+int buf_findsign(
+ buf_T *buf, /* buffer to store sign in */
+ int id /* sign ID */
+ )
+{
+ signlist_T *sign; /* a sign in the signlist */
+
+ for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
+ if (sign->id == id) {
+ return sign->lnum;
+ }
+ }
+
+ return 0;
+}
+
+int buf_findsign_id(
+ buf_T *buf, /* buffer whose sign we are searching for */
+ linenr_T lnum /* line number of sign */
+ )
+{
+ signlist_T *sign; /* a sign in the signlist */
+
+ for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
+ if (sign->lnum == lnum) {
+ return sign->id;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * Delete signs in buffer "buf".
+ */
+void buf_delete_signs(buf_T *buf)
+{
+ signlist_T *next;
+
+ while (buf->b_signlist != NULL) {
+ next = buf->b_signlist->next;
+ vim_free(buf->b_signlist);
+ buf->b_signlist = next;
+ }
+}
+
+/*
+ * Delete all signs in all buffers.
+ */
+void buf_delete_all_signs()
+{
+ buf_T *buf; /* buffer we are checking for signs */
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (buf->b_signlist != NULL) {
+ /* Need to redraw the windows to remove the sign column. */
+ redraw_buf_later(buf, NOT_VALID);
+ buf_delete_signs(buf);
+ }
+ }
+}
+
+/*
+ * List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers.
+ */
+void sign_list_placed(buf_T *rbuf)
+{
+ buf_T *buf;
+ signlist_T *p;
+ char lbuf[BUFSIZ];
+
+ MSG_PUTS_TITLE(_("\n--- Signs ---"));
+ msg_putchar('\n');
+ if (rbuf == NULL) {
+ buf = firstbuf;
+ } else {
+ buf = rbuf;
+ }
+ while (buf != NULL && !got_int) {
+ if (buf->b_signlist != NULL) {
+ vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname);
+ MSG_PUTS_ATTR(lbuf, hl_attr(HLF_D));
+ msg_putchar('\n');
+ }
+ for (p = buf->b_signlist; p != NULL && !got_int; p = p->next) {
+ vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d name=%s"),
+ (long)p->lnum, p->id, sign_typenr2name(p->typenr));
+ MSG_PUTS(lbuf);
+ msg_putchar('\n');
+ }
+ if (rbuf != NULL) {
+ break;
+ }
+ buf = buf->b_next;
+ }
+}
+
+/*
+ * Adjust a placed sign for inserted/deleted lines.
+ */
+void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
+{
+ signlist_T *sign; /* a sign in a b_signlist */
+
+ for (sign = curbuf->b_signlist; sign != NULL; sign = sign->next) {
+ if (sign->lnum >= line1 && sign->lnum <= line2) {
+ if (amount == MAXLNUM) {
+ sign->lnum = line1;
+ } else {
+ sign->lnum += amount;
+ }
+ }
+ else if (sign->lnum > line2)
+ sign->lnum += amount_after;
+ }
+}
/*
* Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed.