mirror of https://github.com/djcb/mu.git
* mu mv updates:
- rename --printtarget into --print-target - support 'delta' flags - add --ignore-dups to silently ignore the src = target case
This commit is contained in:
parent
536280e1b6
commit
557a5e291c
27
man/mu-mv.1
27
man/mu-mv.1
|
@ -46,10 +46,20 @@ The flags is a sequence of characters from the set D (draft), F (flagged), N
|
|||
flags-parameter is case-sensitive. Any other characters will be silently
|
||||
ignored.
|
||||
|
||||
The \fB\-\-flags\fR also has a second, 'delta', syntax. In this syntax, each
|
||||
of the flag characters is prefixed with either '+' or '-', which means that
|
||||
the corresponding flag will be added or removed. Using this syntax, you can
|
||||
change individual flags, without changing all of them.
|
||||
|
||||
.TP
|
||||
\fB\-\-printtarget\fR
|
||||
\fB\-\-print-target\fR
|
||||
return the target path on standard output upon succesful completion of the
|
||||
move (with or without a succesful database update)
|
||||
move (with or without a succesful database update).
|
||||
|
||||
.TP
|
||||
\fB\-\-ignore-dups\fR
|
||||
silently ignore the case where the source file is the same as the target.
|
||||
|
||||
|
||||
.SH EXAMPLE
|
||||
|
||||
|
@ -76,23 +86,30 @@ To mark a message as no longer new and 'Seen', and update the database
|
|||
afterwards, you could do:
|
||||
|
||||
.nf
|
||||
mu --flags=S mv /home/roger/Maildir/inbox/new/123123123 /home/roger/Maildir/inbox/
|
||||
mu mv /home/roger/Maildir/inbox/new/123123123 /home/roger/Maildir/inbox/ --flags=S
|
||||
.fi
|
||||
|
||||
In this case, as we are not moving the message to a diffent maildir, we can
|
||||
leave off the maildir-argument; so the following is equivalent:
|
||||
|
||||
.nf
|
||||
mu --flags=S mv /home/roger/Maildir/inbox/new/123123123
|
||||
mu mv /home/roger/Maildir/inbox/new/123123123 --flags=S
|
||||
.fi
|
||||
|
||||
Finally, using the 'delta'-syntax, you can set the 'seen'-flag
|
||||
and 'replied'-flag while removing the 'new' flag with:
|
||||
|
||||
.nf
|
||||
mu mv /home/billy/Maildir/inbox/new/12aa34343 --flags=+S+R-N
|
||||
.fi
|
||||
which would give us a new file:
|
||||
\fI/home/billy/Maildir/inbox/cur/12aa34343:2,SR\fR
|
||||
|
||||
.SH LIMITATIONS
|
||||
|
||||
Both source-path and target-directory must be on the same disk partition,
|
||||
except when the target-directory is \fI/dev/null\fR.
|
||||
|
||||
|
||||
.SH RETURN VALUE
|
||||
|
||||
\fBmu mv\fR returns 0 upon success, and some other value when an error
|
||||
|
|
31
src/mu-cmd.c
31
src/mu-cmd.c
|
@ -285,19 +285,31 @@ mu_cmd_mkdir (MuConfig *opts)
|
|||
static gboolean
|
||||
mv_check_params (MuConfig *opts, MuFlags *flags)
|
||||
{
|
||||
if (!opts->params[1] || !opts->params[2]) {
|
||||
if (!opts->params[1]) {
|
||||
g_warning ("usage: mu mv [--flags=<flags>] <mailfile> "
|
||||
"<maildir>");
|
||||
"[<maildir>]");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: check for invalid flags */
|
||||
if (!opts->flagstr)
|
||||
*flags = MU_FLAG_INVALID; /* ie., ignore flags */
|
||||
else
|
||||
*flags = mu_flags_from_str (opts->flagstr,
|
||||
MU_FLAG_TYPE_MAILDIR |
|
||||
MU_FLAG_TYPE_MAILFILE);
|
||||
else {
|
||||
/* if there's a '+' or '-' sign in the string, it must
|
||||
* be a flag-delta */
|
||||
if (strstr (opts->flagstr, "+") || strstr (opts->flagstr, "-")) {
|
||||
MuFlags oldflags;
|
||||
oldflags = mu_maildir_get_flags_from_path (opts->params[1]);
|
||||
*flags = mu_flags_from_str_delta (opts->flagstr,
|
||||
oldflags,
|
||||
MU_FLAG_TYPE_MAILDIR|
|
||||
MU_FLAG_TYPE_MAILFILE);
|
||||
} else
|
||||
*flags = mu_flags_from_str (opts->flagstr,
|
||||
MU_FLAG_TYPE_MAILDIR |
|
||||
MU_FLAG_TYPE_MAILFILE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -310,7 +322,7 @@ cmd_mv_dev_null (MuConfig *opts)
|
|||
return MU_ERROR_FILE;
|
||||
}
|
||||
|
||||
if (opts->printtarget)
|
||||
if (opts->print_target)
|
||||
g_print ("/dev/null\n"); /* /dev/null */
|
||||
|
||||
return MU_OK;
|
||||
|
@ -334,7 +346,8 @@ mu_cmd_mv (MuConfig *opts)
|
|||
err = NULL;
|
||||
fullpath = mu_maildir_move_message (opts->params[1],
|
||||
opts->params[2],
|
||||
flags, &err);
|
||||
flags, opts->ignore_dups,
|
||||
&err);
|
||||
if (!fullpath) {
|
||||
if (err) {
|
||||
MuError code;
|
||||
|
@ -346,7 +359,7 @@ mu_cmd_mv (MuConfig *opts)
|
|||
return MU_ERROR_FILE;
|
||||
|
||||
} else {
|
||||
if (opts->printtarget)
|
||||
if (opts->print_target)
|
||||
g_print ("%s\n", fullpath);
|
||||
return MU_OK;
|
||||
}
|
||||
|
|
|
@ -322,7 +322,10 @@ config_options_group_mv (MuConfig *opts)
|
|||
GOptionEntry entries[] = {
|
||||
{"flags", 0, 0, G_OPTION_ARG_STRING, &opts->flagstr,
|
||||
"flags to set for the target (DFNPRST)", NULL},
|
||||
{"printtarget", 0, 0, G_OPTION_ARG_NONE, &opts->printtarget,
|
||||
{"ignore-dups", 0, 0, G_OPTION_ARG_NONE, &opts->ignore_dups,
|
||||
"whether to silently ignore the source = target case",
|
||||
NULL},
|
||||
{"print-target", 0, 0, G_OPTION_ARG_NONE, &opts->print_target,
|
||||
"whether to print the target path upon succesful completion",
|
||||
NULL},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
|
|
|
@ -128,10 +128,11 @@ struct _MuConfig {
|
|||
/* options for mv */
|
||||
char *flagstr; /* message flags to set for
|
||||
* the target */
|
||||
gboolean printtarget; /* should be print the
|
||||
* target file path on
|
||||
* stdout */
|
||||
|
||||
gboolean print_target; /* should be print the
|
||||
* target file path on
|
||||
* stdout */
|
||||
gboolean ignore_dups; /* silently ignore the
|
||||
* src=target case */
|
||||
/* options for view */
|
||||
gboolean terminator; /* add separator \f between
|
||||
* multiple messages in mu
|
||||
|
|
|
@ -60,7 +60,6 @@ mu_flag_type (MuFlags flag)
|
|||
if (flag >= MU_FLAG_SIGNED && flag <= MU_FLAG_HAS_ATTACH)
|
||||
return MU_FLAG_TYPE_CONTENT;
|
||||
|
||||
g_return_val_if_reached (MU_FLAG_TYPE_INVALID);
|
||||
return MU_FLAG_TYPE_INVALID;
|
||||
}
|
||||
|
||||
|
@ -87,7 +86,6 @@ mu_flag_char (MuFlags flag)
|
|||
case MU_FLAG_UNREAD: return 'u';
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -115,13 +113,11 @@ mu_flag_from_char (char kar)
|
|||
case 'u': return MU_FLAG_UNREAD;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (MU_FLAG_INVALID);
|
||||
return MU_FLAG_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* does not use FLAG_INFO, optimized */
|
||||
const char*
|
||||
mu_flag_name (MuFlags flag)
|
||||
|
@ -143,7 +139,6 @@ mu_flag_name (MuFlags flag)
|
|||
case MU_FLAG_UNREAD: return "unread";
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +155,7 @@ mu_flags_to_str_s (MuFlags flags, MuFlagType types)
|
|||
types & FLAG_INFO[u].flag_type)
|
||||
str[v++] = FLAG_INFO[u].kar;
|
||||
str[v] = '\0';
|
||||
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -199,3 +194,39 @@ mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data)
|
|||
func (FLAG_INFO[u].flag, user_data);
|
||||
}
|
||||
|
||||
|
||||
MuFlags
|
||||
mu_flags_from_str_delta (const char *str, MuFlags oldflags,
|
||||
MuFlagType types)
|
||||
{
|
||||
const char *cur;
|
||||
MuFlags newflags;
|
||||
|
||||
g_return_val_if_fail (str, MU_FLAG_INVALID);
|
||||
|
||||
for (cur = str, newflags = oldflags; *cur; ++cur) {
|
||||
|
||||
MuFlags f;
|
||||
if (*cur == '+' || *cur == '-') {
|
||||
f = mu_flag_from_char (cur[1]);
|
||||
if (f == 0)
|
||||
goto error;
|
||||
if (*cur == '+')
|
||||
newflags |= f;
|
||||
else
|
||||
newflags &= ~f;
|
||||
++cur;
|
||||
continue;
|
||||
}
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
return newflags;
|
||||
error:
|
||||
g_warning ("invalid flag string");
|
||||
return MU_FLAG_INVALID;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -122,6 +122,26 @@ const char* mu_flags_to_str_s (MuFlags flags, MuFlagType types);
|
|||
MuFlags mu_flags_from_str (const char *str, MuFlagType types);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update #oldflags with the flags in #str, where #str consists of the
|
||||
* the normal flag characters, but prefixed with either '+' or '-',
|
||||
* which means resp. "add this flag" or "remove this flag" from
|
||||
* oldflags. So, e.g. "-N+S" would unset the NEW flag and set the
|
||||
* SEEN flag, without affecting other flags.
|
||||
*
|
||||
* @param str the string representation
|
||||
* @param old flags to update
|
||||
* @param types the flag types to accept (other will be ignored)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
MuFlags mu_flags_from_str_delta (const char *str, MuFlags oldflags,
|
||||
MuFlagType types);
|
||||
|
||||
|
||||
|
||||
|
||||
typedef void (*MuFlagsForeachFunc) (MuFlags flag, gpointer user_data);
|
||||
|
||||
/**
|
||||
|
|
|
@ -812,10 +812,12 @@ msg_move (const char* src, const char *dst, GError **err)
|
|||
|
||||
gchar*
|
||||
mu_maildir_move_message (const char* oldpath, const char* targetmdir,
|
||||
MuFlags newflags, GError **err)
|
||||
MuFlags newflags, gboolean ignore_dups,
|
||||
GError **err)
|
||||
{
|
||||
char *newfullpath;
|
||||
gboolean rv;
|
||||
gboolean src_is_target;
|
||||
|
||||
g_return_val_if_fail (oldpath, FALSE);
|
||||
|
||||
|
@ -827,16 +829,21 @@ mu_maildir_move_message (const char* oldpath, const char* targetmdir,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (oldpath, newfullpath) == 0) {
|
||||
|
||||
src_is_target = (g_strcmp0 (oldpath, newfullpath) == 0);
|
||||
|
||||
if (!ignore_dups && src_is_target) {
|
||||
g_set_error (err, 0, MU_ERROR_FILE_TARGET_EQUALS_SOURCE,
|
||||
"target equals source");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rv = msg_move (oldpath, newfullpath, err);
|
||||
if (!rv) {
|
||||
g_free (newfullpath);
|
||||
return NULL;
|
||||
if (!src_is_target) {
|
||||
rv = msg_move (oldpath, newfullpath, err);
|
||||
if (!rv) {
|
||||
g_free (newfullpath);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return newfullpath;
|
||||
|
|
|
@ -171,14 +171,17 @@ char* mu_maildir_get_new_path (const char *oldpath, const char *new_mdir,
|
|||
* of the message are affected; note that this may still involve a
|
||||
* moved to another directory (say, from new/ to cur/)
|
||||
* @param flags to set for the target (influences the filename, path)
|
||||
* @param ignore_dups whether to silent ignore the src=target case (and return TRUE)
|
||||
* @param err (may be NULL) may contain error information; note if the
|
||||
* function return FALSE, err is not set for all error condition
|
||||
* (ie. not for parameter errors)
|
||||
*
|
||||
* @return return the full path name of the target file (g_free) if
|
||||
* the move succeeded, NULL otherwise
|
||||
*/
|
||||
gchar* mu_maildir_move_message (const char* oldpath, const char* targetmdir,
|
||||
MuFlags newflags, GError **err);
|
||||
MuFlags newflags, gboolean ignore_dups,
|
||||
GError **err);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
Loading…
Reference in New Issue