diff options
-rw-r--r-- | src/args.c | 4 | ||||
-rw-r--r-- | src/calcurse.c | 53 | ||||
-rw-r--r-- | src/calcurse.h | 13 | ||||
-rw-r--r-- | src/io.c | 22 | ||||
-rw-r--r-- | src/vars.c | 7 | ||||
-rw-r--r-- | src/wins.c | 16 |
6 files changed, 97 insertions, 18 deletions
@@ -707,8 +707,8 @@ int parse_args(int argc, char **argv) io_load_app(); io_load_todo(); io_import_data(IO_IMPORT_ICAL, ifile); - io_save_apts(); - io_save_todo(); + io_save_apts(path_apts); + io_save_todo(path_todo); non_interactive = 1; } if (xflag) { diff --git a/src/calcurse.c b/src/calcurse.c index 149d7bb..cfe8298 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -256,11 +256,54 @@ static inline void key_generic_save(void) static inline void key_generic_reload(void) { - if (io_get_modified() && status_ask_bool(_("By reloading items, you " - "will lose any unsaved modifications. " - "Continue?")) != 1) { - wins_update(FLAG_STA); - return; + if (io_get_modified()) { + const char *msg_um_prefix = + _("There are unsaved modifications:"); + const char *msg_um_discard = _("(d)iscard"); + const char *msg_um_merge = _("(m)erge"); + const char *msg_um_keep = _("(k)eep and cancel"); + const char *msg_um_choice = _("[dmk]"); + + char msg_um_asktype[BUFSIZ]; + snprintf(msg_um_asktype, BUFSIZ, "%s %s, %s, %s", + msg_um_prefix, msg_um_discard, msg_um_merge, + msg_um_keep); + + char *path_apts_backup, *path_todo_backup; + const char *backup_ext = ".sav"; + + switch (status_ask_choice(msg_um_asktype, msg_um_choice, 3)) { + case 1: + break; + case 2: + path_apts_backup = xmalloc(strlen(path_apts) + + strlen(backup_ext) + 1); + path_todo_backup = xmalloc(strlen(path_todo) + + strlen(backup_ext) + 1); + sprintf(path_apts_backup, "%s%s", path_apts, + backup_ext); + sprintf(path_todo_backup, "%s%s", path_todo, + backup_ext); + + io_save_mutex_lock(); + io_save_apts(path_apts_backup); + io_save_todo(path_todo_backup); + io_save_mutex_unlock(); + + wins_launch_external2(path_apts, path_apts_backup, + conf.mergetool); + wins_launch_external2(path_todo, path_todo_backup, + conf.mergetool); + + xfree(path_apts_backup); + xfree(path_todo_backup); + break; + case 3: + /* FALLTHROUGH */ + default: + wins_update(FLAG_STA); + return; + } } /* Reinitialize data structures. */ diff --git a/src/calcurse.h b/src/calcurse.h index ca85690..a1cf9bb 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -103,8 +103,9 @@ #define DPID_PATH DIR_NAME DPID_PATH_NAME #define NOTES_DIR DIR_NAME NOTES_DIR_NAME -#define DEFAULT_EDITOR "vi" -#define DEFAULT_PAGER "less" +#define DEFAULT_EDITOR "vi" +#define DEFAULT_PAGER "less" +#define DEFAULT_MERGETOOL "vimdiff" #define ATTR_FALSE 0 #define ATTR_TRUE 1 @@ -259,6 +260,7 @@ struct conf { unsigned progress_bar; const char *editor; const char *pager; + const char *mergetool; char output_datefmt[BUFSIZ]; /* format for displaying date */ int input_datefmt; /* format for reading date */ }; @@ -753,8 +755,10 @@ void ical_export_data(FILE *); unsigned io_fprintln(const char *, const char *, ...); void io_init(const char *, const char *); void io_extract_data(char *, const char *, int); -unsigned io_save_apts(void); -unsigned io_save_todo(void); +void io_save_mutex_lock(void); +void io_save_mutex_unlock(void); +unsigned io_save_apts(const char *); +unsigned io_save_todo(const char *); unsigned io_save_keys(void); void io_save_cal(enum save_display); void io_load_app(void); @@ -1121,6 +1125,7 @@ void wins_reset(void); void wins_prepare_external(void); void wins_unprepare_external(void); void wins_launch_external(const char *, const char *); +void wins_launch_external2(const char *, const char *, const char *); void wins_status_bar(void); void wins_erase_status_bar(void); void wins_other_status_page(int); @@ -319,12 +319,22 @@ void io_extract_data(char *dst_data, const char *org, int len) static pthread_mutex_t io_save_mutex = PTHREAD_MUTEX_INITIALIZER; +void io_save_mutex_lock(void) +{ + pthread_mutex_lock(&io_save_mutex); +} + +void io_save_mutex_unlock(void) +{ + pthread_mutex_unlock(&io_save_mutex); +} + /* * Save the apts data file, which contains the * appointments first, and then the events. * Recursive items are written first. */ -unsigned io_save_apts(void) +unsigned io_save_apts(const char *aptsfile) { llist_item_t *i; FILE *fp; @@ -332,7 +342,7 @@ unsigned io_save_apts(void) if (read_only) return 1; - if ((fp = fopen(path_apts, "w")) == NULL) + if ((fp = fopen(aptsfile, "w")) == NULL) return 0; recur_save_data(fp); @@ -356,7 +366,7 @@ unsigned io_save_apts(void) } /* Save the todo data file. */ -unsigned io_save_todo(void) +unsigned io_save_todo(const char *todofile) { llist_item_t *i; FILE *fp; @@ -364,7 +374,7 @@ unsigned io_save_todo(void) if (read_only) return 1; - if ((fp = fopen(path_todo, "w")) == NULL) + if ((fp = fopen(todofile, "w")) == NULL) return 0; LLIST_FOREACH(&todolist, i) { @@ -419,12 +429,12 @@ void io_save_cal(enum save_display display) if (show_bar) progress_bar(PROGRESS_BAR_SAVE, PROGRESS_BAR_TODO); - if (!io_save_todo()) + if (!io_save_todo(path_todo)) ERROR_MSG("%s", access_pb); if (show_bar) progress_bar(PROGRESS_BAR_SAVE, PROGRESS_BAR_APTS); - if (!io_save_apts()) + if (!io_save_apts(path_apts)) ERROR_MSG("%s", access_pb); if (show_bar) @@ -126,7 +126,7 @@ struct dmon_conf dmon; */ void vars_init(void) { - const char *ed, *pg; + const char *ed, *pg, *mt; /* Variables for user configuration */ conf.confirm_quit = 1; @@ -159,6 +159,11 @@ void vars_init(void) pg = DEFAULT_PAGER; conf.pager = pg; + mt = getenv("MERGETOOL"); + if (mt == NULL || mt[0] == '\0') + mt = DEFAULT_MERGETOOL; + conf.mergetool = mt; + wins_set_layout(1); ui_calendar_set_first_day_of_week(MONDAY); @@ -611,6 +611,22 @@ void wins_launch_external(const char *file, const char *cmd) wins_unprepare_external(); } +/* + * While inside interactive mode, launch the external command cmd on the given + * two files. + */ +void wins_launch_external2(const char *file1, const char *file2, + const char *cmd) +{ + const char *arg[] = { cmd, file1, file2, NULL }; + int pid; + + wins_prepare_external(); + if ((pid = shell_exec(NULL, NULL, *arg, arg))) + child_wait(NULL, NULL, pid); + wins_unprepare_external(); +} + #define NB_CAL_CMDS 28 /* number of commands while in cal view */ #define NB_APP_CMDS 33 /* same thing while in appointment view */ #define NB_TOD_CMDS 32 /* same thing while in todo view */ |