You can change or delete the <quote>X-Label:</quote> field within
Mutt using the <quote>edit-label</quote> command, bound to the
<quote>y</quote> key by default. This works for tagged messages, too.
+While in the edit-label function, pressing the <complete>
+binding (TAB, by default) will perform completion against all labels
+currently in use.
</para>
<para>
}
break;
}
- else if (flags & MUTT_PATTERN && ch == OP_EDITOR_COMPLETE)
- {
- char *p;
- for (i = state->curpos; i && state->wbuf[i-1] != ',' &&
- state->wbuf[i-1] != ':'; i--)
- ;
- for (; i < state->lastchar && state->wbuf[i] == ' '; i++)
- ;
- my_wcstombs (buf, buflen, state->wbuf + i, state->curpos - i);
- p = &buf[i];
- while (p > buf && *(p-1) != '~')
- p--;
- if (*p == '~' && *(p+1) == 'y')
- {
- r = mutt_label_complete (buf, buflen, i, state->tabs);
- replace_part (state, i, buf);
- if (!r)
- {
- rv = 1;
- goto bye;
- }
- }
- else
- goto self_insert;
- break;
- }
+ else if (flags & MUTT_PATTERN && ch == OP_EDITOR_COMPLETE)
+ {
+ for (i = state->curpos; i && state->wbuf[i-1] != '~'; i--)
+ ;
+ if (i && i < state->curpos && state->wbuf[i-1] == '~' && state->wbuf[i] == 'y')
+ {
+ i++;
+ my_wcstombs (buf, buflen, state->wbuf + i, state->curpos - i);
+ r = mutt_label_complete (buf, buflen, i, state->tabs);
+ replace_part (state, i, buf);
+ if (!r)
+ {
+ rv = 1;
+ goto bye;
+ }
+ }
+ else
+ goto self_insert;
+ break;
+ }
else if (flags & MUTT_ALIAS && ch == OP_EDITOR_COMPLETE_QUERY)
{
/* invoke the query-menu to get more addresses */
}
}
+static void label_ref_dec(char *label)
+{
+ uintptr_t count;
+
+ count = (uintptr_t)hash_find(Labels, label);
+ if (count)
+ {
+ hash_delete(Labels, label, NULL, NULL);
+ count--;
+ if (count > 0)
+ hash_insert(Labels, label, (void *)count, 0);
+ }
+}
+
+static void label_ref_inc(char *label)
+{
+ uintptr_t count;
+
+ count = (uintptr_t)hash_find(Labels, label);
+ if (count)
+ hash_delete(Labels, label, NULL, NULL);
+ count++; /* was zero if not found */
+ hash_insert(Labels, label, (void *)count, 0);
+}
+
/*
* add an X-Label: field.
*/
return 0;
if (mutt_strcmp (hdr->env->x_label, new) == 0)
return 0;
+ if (hdr->env->x_label != NULL)
+ label_ref_dec(hdr->env->x_label);
mutt_str_replace (&hdr->env->x_label, new);
+ if (hdr->env->x_label != NULL)
+ label_ref_inc(hdr->env->x_label);
return hdr->changed = hdr->xlabel_changed = 1;
}
strncpy(buf, hdr->env->x_label, LONG_STRING);
}
- if (mutt_get_field("Label: ", buf, sizeof(buf), 0 /* | MUTT_CLEAR */) != 0)
+ if (mutt_get_field("Label: ", buf, sizeof(buf), MUTT_LABEL /* | MUTT_CLEAR */) != 0)
return 0;
new = buf;
return changed;
}
+
+/* scan a context (mailbox) and hash all labels we find */
+void mutt_scan_labels(CONTEXT *ctx)
+{
+ int i;
+
+ if (!ctx)
+ return;
+
+ for (i = 0; i < ctx->msgcount; i++)
+ if (ctx->hdrs[i]->env->x_label)
+ label_ref_inc(ctx->hdrs[i]->env->x_label);
+}
+
{
char *pt = buffer;
int spaces; /* keep track of the number of leading spaces on the line */
- int prefix;
SKIPWS (buffer);
spaces = buffer - pt;
- for (pt = buffer; pt && *pt && *(pt+1); pt++);
- for (; pt > buffer && !isspace(*(pt-1)); pt--);
- prefix = pt - buffer;
+ pt = buffer + pos - spaces;
+ while ((pt > buffer) && !isspace ((unsigned char) *pt))
+ pt--;
/* first TAB. Collect all the matches */
if (numtabs == 1)
Matches[(numtabs - 2) % Num_matched]);
/* return the completed label */
- strncpy (&buffer[prefix], Completed, len - spaces);
+ strncpy (buffer, Completed, len - spaces);
return 1;
}
if((Context = mx_open_mailbox (folder, ((flags & MUTT_RO) || option (OPTREADONLY)) ? MUTT_READONLY : 0, NULL))
|| !explicit_folder)
{
+ Labels = hash_create (131, 0);
+ mutt_scan_labels(Context);
#ifdef USE_SIDEBAR
mutt_sb_set_open_buffy ();
#endif
- Labels = hash_create (131, 0);
mutt_index_menu ();
if (Context)
FREE (&Context);
if (Labels)
- hash_destroy(&Labels, NULL);
+ hash_destroy(&Labels, NULL);
}
#ifdef USE_IMAP
imap_logout_all ();
void mutt_make_label_hash (CONTEXT *);
void mutt_label_hash_add (CONTEXT *ctx, HEADER *hdr);
void mutt_label_hash_remove (CONTEXT *ctx, HEADER *hdr);
+void mutt_scan_labels (CONTEXT *);
int mutt_label_complete (char *, size_t, int, int);
void mutt_curses_error (const char *, ...);
void mutt_curses_message (const char *, ...);