summaryrefslogtreecommitdiff
path: root/mail
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-03-13 10:16:41 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2012-03-13 10:43:38 +0200
commit9f726ee08feeefd295bd5b2e3f6c676d2248f3f5 (patch)
treef92b0aef2a49be962fbc4d40240eb82b8fe54055 /mail
parentb4d7b1a6cb3f17fdce8759ded4ade0188e86d20d (diff)
downloadmailutils-9f726ee08feeefd295bd5b2e3f6c676d2248f3f5.tar.gz
mailutils-9f726ee08feeefd295bd5b2e3f6c676d2248f3f5.tar.bz2
mail: Implement folder completion in "save"
* mail/mailline.c (file_compl_internal): New function (from file_compl); (file_compl): Call file_compl_internal. (msglist_file_compl): Call file_compl_internal.
Diffstat (limited to 'mail')
-rw-r--r--mail/mailline.c192
1 files changed, 155 insertions, 37 deletions
diff --git a/mail/mailline.c b/mail/mailline.c
index d1944675f..1d206ae57 100644
--- a/mail/mailline.c
+++ b/mail/mailline.c
@@ -121,7 +121,7 @@ ml_readline_internal ()
char *buf = NULL;
size_t size = 0, n;
int rc;
-
+
rc = mu_stream_getline (mu_strin, &buf, &size, &n);
if (rc)
{
@@ -200,7 +200,7 @@ ml_command_completion (char *cmd, int start, int end)
char **ret;
char *p;
struct mu_wordsplit ws;
-
+
for (p = rl_line_buffer; p < rl_line_buffer + start && mu_isblank (*p); p++)
;
@@ -211,7 +211,7 @@ ml_command_completion (char *cmd, int start, int end)
return NULL;
}
rl_completion_append_character = ' ';
-
+
if (ws.ws_wordc == 0 ||
(ws.ws_wordc == 1 && strlen (ws.ws_wordv[0]) <= end - start))
{
@@ -241,7 +241,7 @@ ml_command_generator (const char *text, int state)
static int i, len;
const char *name;
const struct mail_command *cp;
-
+
if (!state)
{
i = 0;
@@ -291,14 +291,6 @@ msglist_compl (int argc, char **argv, int ws)
}
char **
-msglist_file_compl (int argc, char **argv, int ws MU_ARG_UNUSED)
-{
- if (argc == 1)
- ml_attempted_completion_over ();
- return NULL;
-}
-
-char **
command_compl (int argc, char **argv, int ws)
{
ml_set_completion_append_character (0);
@@ -313,24 +305,24 @@ command_compl (int argc, char **argv, int ws)
Select only those files that match given FLAGS (MU_FOLDER_ATTRIBUTE_*
constants).
-
+
STATE is 0 for the first call, 1 otherwise.
*/
static char *
file_generator (const char *text, int state,
char *path, size_t pathlen,
- char repl,
+ char repl,
int flags)
{
static mu_list_t list;
static mu_iterator_t itr;
-
+
if (!state)
{
char *wcard;
mu_folder_t folder;
size_t count;
-
+
wcard = xmalloc (strlen (text) + 2);
strcat (strcpy (wcard, text), "*");
@@ -339,7 +331,7 @@ file_generator (const char *text, int state,
free (wcard);
return NULL;
}
-
+
mu_folder_list (folder, path, wcard, 1, &list);
free (wcard);
mu_folder_destroy (&folder);
@@ -351,7 +343,7 @@ file_generator (const char *text, int state,
}
else if (count == 1)
ml_set_completion_append_character (0);
-
+
if (mu_list_get_iterator (list, &itr))
{
mu_list_destroy (&list);
@@ -372,7 +364,7 @@ file_generator (const char *text, int state,
{
size_t len = strlen (resp->name + pathlen);
char *ptr;
-
+
ret = xmalloc (len + (repl ? 1 : 0) + 1);
ptr = ret;
if (repl)
@@ -395,13 +387,13 @@ folder_generator (const char *text, int state)
{
char *ret;
static size_t pathlen;
-
+
if (!state)
{
char *path = util_folder_path ("");
if (!path)
return NULL;
-
+
pathlen = strlen (path);
ret = file_generator (text, state, path, pathlen, '+',
MU_FOLDER_ATTRIBUTE_ALL);
@@ -413,8 +405,102 @@ folder_generator (const char *text, int state)
return ret;
}
-char **
-file_compl (int argc, char **argv, int ws)
+static char *
+msgtype_generator (const char *text, int state)
+{
+ static char types[] = "dnorTtu";
+ static int i;
+ char *s;
+
+ if (!state)
+ {
+ if (text[1])
+ return NULL;
+ i = 0;
+ }
+ if (!types[i])
+ return NULL;
+ s = malloc (2);
+ if (s)
+ {
+ s[0] = types[i++];
+ s[1] = 0;
+ }
+ return s;
+}
+
+static char *
+header_generator (const char *text, int state)
+{
+ static int i, len;
+ char *hdr;
+ char *hdrlist[] = {
+ MU_HEADER_RETURN_PATH,
+ MU_HEADER_RECEIVED,
+ MU_HEADER_DATE,
+ MU_HEADER_DCC,
+ MU_HEADER_FROM,
+ MU_HEADER_SENDER,
+ MU_HEADER_RESENT_FROM,
+ MU_HEADER_SUBJECT,
+ MU_HEADER_RESENT_SENDER,
+ MU_HEADER_TO,
+ MU_HEADER_RESENT_TO,
+ MU_HEADER_CC,
+ MU_HEADER_RESENT_CC,
+ MU_HEADER_BCC,
+ MU_HEADER_RESENT_BCC,
+ MU_HEADER_REPLY_TO,
+ MU_HEADER_RESENT_REPLY_TO,
+ MU_HEADER_MESSAGE_ID,
+ MU_HEADER_RESENT_MESSAGE_ID,
+ MU_HEADER_IN_REPLY_TO,
+ MU_HEADER_REFERENCE,
+ MU_HEADER_REFERENCES,
+ MU_HEADER_ENCRYPTED,
+ MU_HEADER_PRECEDENCE,
+ MU_HEADER_STATUS,
+ MU_HEADER_CONTENT_LENGTH,
+ MU_HEADER_CONTENT_LANGUAGE,
+ MU_HEADER_CONTENT_TRANSFER_ENCODING,
+ MU_HEADER_CONTENT_ID,
+ MU_HEADER_CONTENT_TYPE,
+ MU_HEADER_CONTENT_DESCRIPTION,
+ MU_HEADER_CONTENT_DISPOSITION,
+ MU_HEADER_CONTENT_MD5,
+ MU_HEADER_CONTENT_LOCATION,
+ MU_HEADER_MIME_VERSION,
+ MU_HEADER_X_MAILER,
+ MU_HEADER_X_UIDL,
+ MU_HEADER_X_UID,
+ MU_HEADER_X_IMAPBASE,
+ MU_HEADER_ENV_SENDER,
+ MU_HEADER_ENV_DATE,
+ MU_HEADER_FCC,
+ MU_HEADER_DELIVERY_DATE,
+ MU_HEADER_ENVELOPE_TO,
+ MU_HEADER_X_EXPIRE_TIMESTAMP,
+ NULL
+ };
+
+ if (!state)
+ {
+ i = 0;
+ len = strlen (text);
+ }
+
+ while ((hdr = hdrlist[i]))
+ {
+ i++;
+ if (mu_c_strncasecmp (hdr, text, len) == 0)
+ return strdup (hdr);
+ }
+
+ return NULL;
+}
+
+static char **
+file_compl_internal (int argc, char **argv, int ws, int msglist)
{
char *text;
@@ -424,26 +510,59 @@ file_compl (int argc, char **argv, int ws)
ml_attempted_completion_over ();
return NULL;
}
-
+
text = argv[argc-1];
+
+ if (msglist)
+ {
+ if (text[0] == ':')
+ {
+ ml_set_completion_append_character (' ');
+ return rl_completion_matches (text, msgtype_generator);
+ }
+ else if (mu_isalpha (text[0]))
+ {
+ ml_set_completion_append_character (':');
+ return rl_completion_matches (text, header_generator);
+ }
+ else if (mu_isdigit (text[0]))
+ {
+ ml_attempted_completion_over ();
+ return NULL;
+ }
+ }
+
switch (text[0])
{
case '+':
text++;
break;
+ case '%':
case '#':
case '&':
ml_attempted_completion_over ();
return NULL;
-
+
default:
return NULL; /* Will be expanded by readline itself */
}
-
+
return rl_completion_matches (text, folder_generator);
}
+char **
+file_compl (int argc, char **argv, int ws)
+{
+ return file_compl_internal (argc, argv, ws, 0);
+}
+
+char **
+msglist_file_compl (int argc, char **argv, int ws)
+{
+ return file_compl_internal (argc, argv, ws, 1);
+}
+
static char *
dir_generator (const char *text, int state)
{
@@ -479,13 +598,13 @@ dir_generator (const char *text, int state)
pathlen = 0;
repl = 0;
break;
-
+
default:
path = strdup ("./");
pathlen = 2;
repl = 0;
}
-
+
ret = file_generator (text, state, path, pathlen, repl,
MU_FOLDER_ATTRIBUTE_DIRECTORY);
free (path);
@@ -513,7 +632,7 @@ alias_generator (const char *text, int state)
{
static alias_iterator_t itr;
const char *p;
-
+
if (!state)
p = alias_iterate_first (text, &itr);
else
@@ -557,7 +676,7 @@ exec_generator (const char *text, int state)
static size_t dsize;
static DIR *dp;
struct dirent *ent;
-
+
if (!state)
{
var = getenv ("PATH");
@@ -580,13 +699,13 @@ exec_generator (const char *text, int state)
break;
else
var++;
-
+
p = strchr (var, ':');
if (!p)
len = strlen (var) + 1;
else
len = p - var + 1;
-
+
if (dsize == 0)
{
dir = malloc (len);
@@ -597,13 +716,13 @@ exec_generator (const char *text, int state)
dir = realloc (dir, len);
dsize = len;
}
-
+
if (!dir)
return NULL;
memcpy (dir, var, len - 1);
dir[len - 1] = 0;
var += len - 1;
-
+
dp = opendir (dir);
if (!dp)
continue;
@@ -614,13 +733,13 @@ exec_generator (const char *text, int state)
char *name = mkfilename (dir, ent->d_name);
if (name)
{
- int rc = access (name, X_OK);
+ int rc = access (name, X_OK);
if (rc == 0)
{
struct stat st;
rc = !(stat (name, &st) == 0 && S_ISREG (st.st_mode));
}
-
+
free (name);
if (rc == 0
&& strlen (ent->d_name) >= prefix_len
@@ -944,4 +1063,3 @@ ml_attempted_completion_over ()
}
#endif
-

Return to:

Send suggestions and report system problems to the System administrator.