Moved declaration of "easy_patterns" variable from lib/util.[ch] to src/setup.[ch].
[pantumic.git] / src / setup.c
blob3620ef6c3d74f4aa9563b0793e3ca1df35d128e1
1 /* Setup loading/saving.
2 Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19 /** \file setup.c
20 * \brief Source: setup loading/saving
23 #include <config.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
31 #include "lib/global.h"
33 #include "lib/tty/tty.h"
34 #include "lib/tty/key.h"
35 #include "lib/mcconfig.h"
36 #include "lib/fileloc.h"
37 #include "lib/util.h" /* time formats */
39 #include "lib/vfs/mc-vfs/vfs.h"
41 #ifdef ENABLE_VFS_FTP
42 #include "lib/vfs/mc-vfs/ftpfs.h"
43 #endif
44 #ifdef ENABLE_VFS_FISH
45 #include "lib/vfs/mc-vfs/fish.h"
46 #endif
48 #include "args.h"
49 #include "dir.h"
50 #include "panel.h"
51 #include "main.h"
52 #include "tree.h" /* xtree_mode */
53 #include "hotlist.h" /* load/save/done hotlist */
54 #include "panelize.h" /* load/save/done panelize */
55 #include "layout.h"
56 #include "menu.h" /* menubar_visible declaration */
57 #include "cmd.h"
58 #include "file.h" /* safe_delete */
59 #include "keybind.h" /* lookup_action */
60 #include "wtools.h"
62 #ifdef HAVE_CHARSET
63 #include "charsets.h"
64 #endif
66 #ifdef USE_INTERNAL_EDIT
67 #include "src/editor/edit.h"
68 #endif
70 #include "src/viewer/mcviewer.h" /* For the externs */
72 #include "setup.h"
74 /*** global variables **************************************************/
76 char *profile_name; /* .mc/ini */
77 char *global_profile_name; /* mc.lib */
79 char *setup_color_string;
80 char *term_color_string;
81 char *color_terminal_string;
83 panel_view_mode_t startup_left_mode;
84 panel_view_mode_t startup_right_mode;
86 int setup_copymove_persistent_attr = 1;
88 /* Tab size */
89 int option_tab_spacing = DEFAULT_TAB_SPACING;
91 /* Ugly hack to allow panel_save_setup to work as a place holder for */
92 /* default panel values */
93 int saving_setup;
95 panels_options_t panels_options = {
96 .kilobyte_si = FALSE,
97 .mix_all_files = FALSE,
98 .show_backups = TRUE,
99 .show_dot_files = TRUE,
100 .fast_reload = FALSE,
101 .fast_reload_msg_shown = FALSE,
102 .mark_moves_down = TRUE,
103 .reverse_files_only = TRUE,
104 .auto_save_setup = FALSE,
105 .navigate_with_arrows = FALSE,
106 .scroll_pages = TRUE,
107 .mouse_move_pages = TRUE,
108 .filetype_mode = TRUE,
109 .permission_mode = FALSE,
110 .qsearch_mode = QSEARCH_PANEL_CASE
113 int easy_patterns = 1;
115 /*** file scope macro definitions **************************************/
117 /* In order to use everywhere the same setup for the locale we use defines */
118 #define FMTYEAR _("%b %e %Y")
119 #define FMTTIME _("%b %e %H:%M")
121 /*** file scope type declarations **************************************/
123 /*** file scope variables **********************************************/
125 static char *panels_profile_name = NULL; /* .mc/panels.ini */
127 /* *INDENT-OFF* */
128 static const struct
130 const char *key;
131 int list_type;
132 } list_types [] = {
133 { "full", list_full },
134 { "brief", list_brief },
135 { "long", list_long },
136 { "user", list_user },
137 { NULL, 0 }
140 static const struct
142 const char *opt_name;
143 panel_view_mode_t opt_type;
144 } panel_types [] = {
145 { "listing", view_listing },
146 { "quickview", view_quick },
147 { "info", view_info },
148 { "tree", view_tree },
149 { NULL, view_listing }
152 static const struct
154 const char *opt_name;
155 int *opt_addr;
156 } layout [] = {
157 { "equal_split", &equal_split },
158 { "first_panel_size", &first_panel_size },
159 { "message_visible", &message_visible },
160 { "keybar_visible", &keybar_visible },
161 { "xterm_title", &xterm_title },
162 { "output_lines", &output_lines },
163 { "command_prompt", &command_prompt },
164 { "menubar_visible", &menubar_visible },
165 { "show_mini_info", &show_mini_info },
166 { "free_space", &free_space },
167 { NULL, NULL }
170 static const struct
172 const char *opt_name;
173 int *opt_addr;
174 } int_options [] = {
175 { "verbose", &verbose },
176 { "pause_after_run", &pause_after_run },
177 { "shell_patterns", &easy_patterns },
178 { "auto_save_setup", &auto_save_setup },
179 { "auto_menu", &auto_menu },
180 { "use_internal_view", &use_internal_view },
181 { "use_internal_edit", &use_internal_edit },
182 { "clear_before_exec", &clear_before_exec },
183 { "confirm_delete", &confirm_delete },
184 { "confirm_overwrite", &confirm_overwrite },
185 { "confirm_execute", &confirm_execute },
186 { "confirm_history_cleanup", &confirm_history_cleanup },
187 { "confirm_exit", &confirm_exit },
188 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
189 { "safe_delete", &safe_delete },
190 { "mouse_repeat_rate", &mou_auto_repeat },
191 { "double_click_speed", &double_click_speed },
192 #ifndef HAVE_CHARSET
193 { "eight_bit_clean", &eight_bit_clean },
194 { "full_eight_bits", &full_eight_bits },
195 #endif /* !HAVE_CHARSET */
196 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
197 { "confirm_view_dir", &confirm_view_dir },
198 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
199 { "mouse_close_dialog", &mouse_close_dialog},
200 { "fast_refresh", &fast_refresh },
201 { "drop_menus", &drop_menus },
202 { "wrap_mode", &mcview_global_wrap_mode},
203 { "old_esc_mode", &old_esc_mode },
204 { "old_esc_mode_timeout", &old_esc_mode_timeout },
205 { "cd_symlinks", &cd_symlinks },
206 { "show_all_if_ambiguous", &show_all_if_ambiguous },
207 { "max_dirt_limit", &mcview_max_dirt_limit },
208 { "torben_fj_mode", &torben_fj_mode },
209 { "use_file_to_guess_type", &use_file_to_check_type },
210 { "alternate_plus_minus", &alternate_plus_minus },
211 { "only_leading_plus_minus", &only_leading_plus_minus },
212 { "show_output_starts_shell", &output_starts_shell },
213 { "xtree_mode", &xtree_mode },
214 { "num_history_items_recorded", &num_history_items_recorded },
215 { "file_op_compute_totals", &file_op_compute_totals },
216 { "classic_progressbar", &classic_progressbar},
217 #ifdef ENABLE_VFS
218 { "vfs_timeout", &vfs_timeout },
219 #ifdef ENABLE_VFS_FTP
220 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
221 { "use_netrc", &ftpfs_use_netrc },
222 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
223 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
224 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
225 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
226 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
227 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
228 #endif /* ENABLE_VFS_FTP */
229 #ifdef ENABLE_VFS_FISH
230 { "fish_directory_timeout", &fish_directory_timeout },
231 #endif /* ENABLE_VFS_FISH */
232 #endif /* ENABLE_VFS */
233 /* option_tab_spacing is used in internal viewer */
234 { "editor_tab_spacing", &option_tab_spacing },
235 #ifdef USE_INTERNAL_EDIT
236 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
237 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
238 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
239 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
240 { "editor_fake_half_tabs", &option_fake_half_tabs },
241 { "editor_option_save_mode", &option_save_mode },
242 { "editor_option_save_position", &option_save_position },
243 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
244 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
245 { "editor_edit_confirm_save", &edit_confirm_save },
246 { "editor_syntax_highlighting", &option_syntax_highlighting },
247 { "editor_persistent_selections", &option_persistent_selections },
248 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
249 { "editor_visible_tabs", &visible_tabs },
250 { "editor_visible_spaces", &visible_tws },
251 { "editor_line_state", &option_line_state },
252 { "editor_simple_statusbar", &simple_statusbar },
253 { "editor_check_new_line", &option_check_nl_at_eof },
254 { "editor_show_right_margin", &show_right_margin },
255 #endif /* USE_INTERNAL_EDIT */
256 { "nice_rotating_dash", &nice_rotating_dash },
257 { "horizontal_split", &horizontal_split },
258 { "mcview_remember_file_position", &mcview_remember_file_position },
259 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
260 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
261 { "select_flags", &select_flags },
262 { NULL, NULL }
265 static const struct
267 const char *opt_name;
268 char **opt_addr;
269 const char *opt_defval;
270 } str_options[] = {
271 #ifdef USE_INTERNAL_EDIT
272 { "editor_backup_extension", &option_backup_ext, "~" },
273 #endif
274 { "mcview_eof", &mcview_show_eof, "" },
275 { NULL, NULL, NULL }
278 static const struct
280 const char *opt_name;
281 const char *opt_old_name;
282 gboolean *opt_addr;
283 } panels_ini_options[] = {
284 { "kilobyte_si", NULL, &panels_options.kilobyte_si },
285 { "mix_all_files", NULL, &panels_options.mix_all_files },
286 { "show_backups", NULL, &panels_options.show_backups },
287 { "show_dot_files", NULL, &panels_options.show_dot_files },
288 { "fast_reload", NULL, &panels_options.fast_reload },
289 { "fast_reload_msg_shown", NULL, &panels_options.fast_reload_msg_shown },
290 { "mark_moves_down", NULL, &panels_options.mark_moves_down },
291 { "reverse_files_only", NULL, &panels_options.reverse_files_only },
292 { "auto_save_setup_panels", "auto_save_setup", &panels_options.auto_save_setup },
293 { "navigate_with_arrows", NULL, &panels_options.navigate_with_arrows },
294 { "panel_scroll_pages", "scroll_pages", &panels_options.scroll_pages },
295 { "mouse_move_pages", NULL, &panels_options.mouse_move_pages },
296 { "filetype_mode", NULL, &panels_options.filetype_mode },
297 { "permission_mode", NULL, &panels_options.permission_mode },
298 { NULL, NULL, NULL }
300 /* *INDENT-ON* */
302 static const char *panels_section = "Panels";
304 /*** file scope functions **********************************************/
307 Get name of config file.
309 \param subdir
310 if not NULL, then config also search into specified subdir.
312 \param config_file_name
313 If specified filename is relative, then will search in standart patches.
315 \return
316 Newly allocated path to config name or NULL if file not found.
318 If config_file_name is a relative path, then search config in stantart pathes.
320 static char *
321 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
324 TODO: IMHO, in future this function must be placed into mc_config module.
325 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
326 home_mc => mc_user_homedir
328 char *lc_basename, *ret;
330 if (config_file_name == NULL)
331 return NULL;
333 if (g_path_is_absolute (config_file_name))
334 return g_strdup (config_file_name);
337 lc_basename = g_path_get_basename (config_file_name);
338 if (lc_basename == NULL)
339 return NULL;
341 if (subdir != NULL)
342 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
343 else
344 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
346 if (exist_file (ret))
348 g_free (lc_basename);
349 return ret;
351 g_free (ret);
353 if (subdir != NULL)
354 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
355 else
356 ret = g_build_filename (mc_home, lc_basename, NULL);
358 if (exist_file (ret))
360 g_free (lc_basename);
361 return ret;
363 g_free (ret);
365 if (subdir != NULL)
366 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
367 else
368 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
370 g_free (lc_basename);
372 if (exist_file (ret))
373 return ret;
375 g_free (ret);
376 return NULL;
380 static const char *
381 setup__is_cfg_group_must_panel_config (const char *grp)
383 return (!strcasecmp ("Dirs", grp) ||
384 !strcasecmp ("Temporal:New Right Panel", grp) ||
385 !strcasecmp ("Temporal:New Left Panel", grp) ||
386 !strcasecmp ("New Left Panel", grp) || !strcasecmp ("New Right Panel", grp))
387 ? grp : NULL;
390 static void
391 setup__move_panels_config_into_separate_file (const char *profile)
393 mc_config_t *tmp_cfg;
394 char **groups, **curr_grp;
395 const char *need_grp;
397 if (!exist_file (profile))
398 return;
400 tmp_cfg = mc_config_init (profile);
401 if (!tmp_cfg)
402 return;
404 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
405 if (!groups)
407 mc_config_deinit (tmp_cfg);
408 return;
411 while (*curr_grp)
413 if (setup__is_cfg_group_must_panel_config (*curr_grp) == NULL)
414 mc_config_del_group (tmp_cfg, *curr_grp);
415 curr_grp++;
418 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
419 mc_config_deinit (tmp_cfg);
421 tmp_cfg = mc_config_init (profile);
422 if (!tmp_cfg)
424 g_strfreev (groups);
425 return;
428 curr_grp = groups;
430 while (*curr_grp)
432 need_grp = setup__is_cfg_group_must_panel_config (*curr_grp);
433 if (need_grp != NULL)
435 mc_config_del_group (tmp_cfg, need_grp);
437 curr_grp++;
439 g_strfreev (groups);
441 mc_config_save_file (tmp_cfg, NULL);
442 mc_config_deinit (tmp_cfg);
446 Create new mc_config object from specified ini-file or
447 append data to existing mc_config object from ini-file
450 static void
451 load_setup_init_config_from_file (mc_config_t ** config, const char *fname)
454 TODO: IMHO, in future this function must be placed into mc_config module.
456 if (exist_file (fname))
458 if (*config != NULL)
459 mc_config_read_file (*config, fname);
460 else
461 *config = mc_config_init (fname);
465 static void
466 load_layout (void)
468 size_t i;
470 for (i = 0; layout[i].opt_name != NULL; i++)
471 *layout[i].opt_addr = mc_config_get_int (mc_main_config, "Layout",
472 layout[i].opt_name, *layout[i].opt_addr);
475 static void
476 load_keys_from_section (const char *terminal, mc_config_t * cfg)
478 char *section_name;
479 gchar **profile_keys, **keys;
480 gchar **values, **curr_values;
481 char *valcopy, *value;
482 long key_code;
483 gsize len, values_len;
485 if (terminal == NULL)
486 return;
488 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
489 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
491 while (*profile_keys != NULL)
493 /* copy=other causes all keys from [terminal:other] to be loaded. */
494 if (g_ascii_strcasecmp (*profile_keys, "copy") == 0)
496 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
497 load_keys_from_section (valcopy, cfg);
498 g_free (valcopy);
499 profile_keys++;
500 continue;
503 curr_values = values =
504 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
506 key_code = lookup_key (*profile_keys, NULL);
508 if (key_code != 0)
510 if (curr_values != NULL)
512 while (*curr_values != NULL)
514 valcopy = convert_controls (*curr_values);
515 define_sequence (key_code, valcopy, MCKEY_NOACTION);
516 g_free (valcopy);
517 curr_values++;
520 else
522 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
523 valcopy = convert_controls (value);
524 define_sequence (key_code, valcopy, MCKEY_NOACTION);
525 g_free (valcopy);
526 g_free (value);
530 profile_keys++;
532 if (values != NULL)
533 g_strfreev (values);
535 g_strfreev (keys);
536 g_free (section_name);
539 static void
540 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
542 gchar **profile_keys, **keys;
543 gchar **values, **curr_values;
544 char *valcopy, *value;
545 int action;
546 gsize len, values_len;
548 if (section_name == NULL)
549 return;
551 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
553 while (*profile_keys != NULL)
555 curr_values = values =
556 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
558 action = lookup_action (*profile_keys);
560 if (action > 0)
562 if (curr_values != NULL)
564 while (*curr_values != NULL)
566 valcopy = convert_controls (*curr_values);
567 keybind_cmd_bind (keymap, valcopy, action);
568 g_free (valcopy);
569 curr_values++;
572 else
574 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
575 valcopy = convert_controls (value);
576 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
577 g_free (valcopy);
578 g_free (value);
582 profile_keys++;
584 if (values != NULL)
585 g_strfreev (values);
587 g_strfreev (keys);
590 static mc_config_t *
591 load_setup_get_keymap_profile_config (void)
594 TODO: IMHO, in future this function must be placed into mc_config module.
596 mc_config_t *keymap_config = NULL;
597 char *fname, *fname2;
599 /* 1) /usr/share/mc (mc_home_alt) */
600 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
601 load_setup_init_config_from_file (&keymap_config, fname);
602 g_free (fname);
604 /* 2) /etc/mc (mc_home) */
605 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
606 load_setup_init_config_from_file (&keymap_config, fname);
607 g_free (fname);
609 /* 3) ~/.mc (home_dir?) */
610 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
611 load_setup_init_config_from_file (&keymap_config, fname);
612 g_free (fname);
614 /* 4) main config; [Midnight Commander] -> keymap */
616 fname2 =
617 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, "keymap", GLOBAL_KEYMAP_FILE);
618 fname = load_setup_get_full_config_name (NULL, fname2);
619 if (fname != NULL)
621 load_setup_init_config_from_file (&keymap_config, fname);
622 g_free (fname);
624 g_free (fname2);
626 /* 5) getenv("MC_KEYMAP") */
627 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
628 if (fname != NULL)
630 load_setup_init_config_from_file (&keymap_config, fname);
631 g_free (fname);
634 /* 6) --keymap=<keymap> */
635 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
636 if (fname != NULL)
638 load_setup_init_config_from_file (&keymap_config, fname);
639 g_free (fname);
642 return keymap_config;
645 static panel_view_mode_t
646 setup__load_panel_state (const char *section)
648 char *buffer;
649 size_t i;
650 panel_view_mode_t mode = view_listing;
652 /* Load the display mode */
653 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
655 for (i = 0; panel_types[i].opt_name != NULL; i++)
656 if (g_ascii_strcasecmp (panel_types[i].opt_name, buffer) == 0)
658 mode = panel_types[i].opt_type;
659 break;
662 g_free (buffer);
664 return mode;
667 static void
668 panel_save_type (const char *section, panel_view_mode_t type)
670 size_t i;
672 for (i = 0; panel_types[i].opt_name != NULL; i++)
673 if (panel_types[i].opt_type == type)
675 mc_config_set_string (mc_panels_config, section, "display", panel_types[i].opt_name);
676 break;
680 /*** public functions **************************************************/
682 char *
683 setup_init (void)
685 char *profile;
686 char *inifile;
688 if (profile_name != NULL)
689 return profile_name;
691 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
692 if (!exist_file (profile))
694 inifile = concat_dir_and_file (mc_home, "mc.ini");
695 if (exist_file (inifile))
697 g_free (profile);
698 profile = inifile;
700 else
702 g_free (inifile);
703 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
704 if (exist_file (inifile))
706 g_free (profile);
707 profile = inifile;
709 else
710 g_free (inifile);
714 profile_name = profile;
716 return profile;
719 void
720 load_setup (void)
722 char *profile;
723 size_t i;
724 char *buffer;
725 const char *kt;
727 #ifdef HAVE_CHARSET
728 load_codepages_list ();
729 #endif /* HAVE_CHARSET */
731 profile = setup_init ();
733 /* mc.lib is common for all users, but has priority lower than
734 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
735 global_profile_name = g_build_filename (mc_home, MC_GLOBAL_CONFIG_FILE, (char *) NULL);
736 if (!exist_file (global_profile_name))
738 g_free (global_profile_name);
739 global_profile_name = g_build_filename (mc_home_alt, MC_GLOBAL_CONFIG_FILE, (char *) NULL);
742 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
744 mc_main_config = mc_config_init (profile);
746 if (!exist_file (panels_profile_name))
747 setup__move_panels_config_into_separate_file (profile);
749 mc_panels_config = mc_config_init (panels_profile_name);
751 /* Load integer boolean options */
752 for (i = 0; int_options[i].opt_name != NULL; i++)
753 *int_options[i].opt_addr =
754 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
755 *int_options[i].opt_addr);
757 if (option_tab_spacing <= 0)
758 option_tab_spacing = DEFAULT_TAB_SPACING;
760 #ifdef USE_INTERNAL_EDIT
761 if (option_word_wrap_line_length <= 0)
762 option_word_wrap_line_length = DEFAULT_WRAP_LINE_LENGTH;
763 #endif /* USE_INTERNAL_EDIT */
765 /* overwrite old_esc_mode_timeout */
766 kt = getenv ("KEYBOARD_KEY_TIMEOUT_US");
767 if ((kt != NULL) && (kt[0] != '\0'))
768 old_esc_mode_timeout = atoi (kt);
770 /* Load string options */
771 for (i = 0; str_options[i].opt_name != NULL; i++)
772 *str_options[i].opt_addr =
773 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
774 str_options[i].opt_defval);
776 load_layout ();
777 panels_load_options ();
778 load_panelize ();
780 startup_left_mode = setup__load_panel_state ("New Left Panel");
781 startup_right_mode = setup__load_panel_state ("New Right Panel");
783 /* At least one of the panels is a listing panel */
784 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
785 startup_left_mode = view_listing;
787 if (mc_run_param1 == NULL)
789 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
790 if (vfs_file_is_local (buffer))
791 mc_run_param1 = buffer;
792 else
793 g_free (buffer);
796 boot_current_is_left = mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
798 /* Load time formats */
799 user_recent_timeformat =
800 mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
801 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
803 #ifdef ENABLE_VFS_FTP
804 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
805 ftpfs_ignore_chattr_errors = mc_config_get_bool (mc_main_config, CONFIG_APP_SECTION,
806 "ignore_ftp_chattr_errors", TRUE);
807 ftpfs_init_passwd ();
808 #endif /* ENABLE_VFS_FTP */
810 /* The default color and the terminal dependent color */
811 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
812 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
813 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
815 /* Load the directory history */
816 /* directory_history_load (); */
817 /* Remove the temporal entries */
819 #ifdef HAVE_CHARSET
820 if (codepages->len > 1)
822 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
823 if (buffer[0] != '\0')
825 display_codepage = get_codepage_index (buffer);
826 cp_display = get_codepage_id (display_codepage);
828 g_free (buffer);
829 buffer = mc_config_get_string (mc_main_config, "Misc", "source_codepage", "");
830 if (buffer[0] != '\0')
832 default_source_codepage = get_codepage_index (buffer);
833 source_codepage = default_source_codepage; /* May be source_codepage doesn't need this */
834 cp_source = get_codepage_id (source_codepage);
836 g_free (buffer);
839 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
840 if ((autodetect_codeset[0] != '\0') && (strcmp (autodetect_codeset, "off") != 0))
841 is_autodetect_codeset_enabled = TRUE;
843 g_free (init_translation_table (source_codepage, display_codepage));
844 buffer = (char *) get_codepage_id (display_codepage);
845 if (buffer != NULL)
846 utf8_display = str_isutf8 (buffer);
847 #endif /* HAVE_CHARSET */
849 clipboard_store_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_store", "");
850 clipboard_paste_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_paste", "");
853 gboolean
854 save_setup (void)
856 char *tmp_profile;
857 gboolean ret;
859 saving_setup = 1;
861 save_config ();
862 save_layout ();
863 panels_save_options ();
864 save_hotlist ();
865 save_panelize ();
866 save_panel_types ();
867 /* directory_history_save (); */
869 #ifdef ENABLE_VFS_FTP
870 mc_config_set_string (mc_main_config, "Misc", "ftpfs_password", ftpfs_anonymous_passwd);
871 if (ftpfs_proxy_host)
872 mc_config_set_string (mc_main_config, "Misc", "ftp_proxy_host", ftpfs_proxy_host);
873 #endif /* ENABLE_VFS_FTP */
875 #ifdef HAVE_CHARSET
876 mc_config_set_string (mc_main_config, "Misc", "display_codepage",
877 get_codepage_id (display_codepage));
878 mc_config_set_string (mc_main_config, "Misc", "source_codepage",
879 get_codepage_id (default_source_codepage));
880 mc_config_set_string (mc_main_config, "Misc", "autodetect_codeset", autodetect_codeset);
881 #endif /* HAVE_CHARSET */
882 mc_config_set_string (mc_main_config, "Misc", "clipboard_store", clipboard_store_path);
883 mc_config_set_string (mc_main_config, "Misc", "clipboard_paste", clipboard_paste_path);
885 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
886 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
888 g_free (tmp_profile);
889 saving_setup = 0;
890 return ret;
893 void
894 done_setup (void)
896 size_t i;
898 g_free (profile_name);
899 g_free (global_profile_name);
900 g_free (color_terminal_string);
901 g_free (term_color_string);
902 g_free (setup_color_string);
903 g_free (panels_profile_name);
904 mc_config_deinit (mc_main_config);
905 mc_config_deinit (mc_panels_config);
907 g_free (user_recent_timeformat);
908 g_free (user_old_timeformat);
910 for (i = 0; str_options[i].opt_name != NULL; i++)
911 g_free (*str_options[i].opt_addr);
913 done_hotlist ();
914 done_panelize ();
915 /* directory_history_free (); */
918 void
919 save_config (void)
921 char *profile;
922 GError *error = NULL;
923 size_t i;
925 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
927 /* Save integer options */
928 for (i = 0; int_options[i].opt_name != NULL; i++)
929 mc_config_set_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
930 *int_options[i].opt_addr);
932 /* Save string options */
933 for (i = 0; str_options[i].opt_name != NULL; i++)
934 mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
935 *str_options[i].opt_addr);
937 if (!mc_config_save_to_file (mc_main_config, profile, &error))
938 setup_save_config_show_error (profile, &error);
940 g_free (profile);
943 void
944 setup_save_config_show_error (const char *filename, GError ** error)
946 if (error != NULL && *error != NULL)
948 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"), filename, (*error)->message);
949 g_error_free (*error);
950 *error = NULL;
954 void
955 save_layout (void)
957 char *profile;
958 size_t i;
960 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
961 /* Save integer options */
962 for (i = 0; layout[i].opt_name != NULL; i++)
963 mc_config_set_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
964 mc_config_save_to_file (mc_main_config, profile, NULL);
965 g_free (profile);
968 void
969 load_key_defs (void)
972 * Load keys from mc.lib before ~/.mc/ini, so that the user
973 * definitions override global settings.
975 mc_config_t *mc_global_config;
977 mc_global_config = mc_config_init (global_profile_name);
978 if (mc_global_config != NULL)
980 load_keys_from_section ("general", mc_global_config);
981 load_keys_from_section (getenv ("TERM"), mc_global_config);
982 mc_config_deinit (mc_global_config);
985 load_keys_from_section ("general", mc_main_config);
986 load_keys_from_section (getenv ("TERM"), mc_main_config);
989 #ifdef ENABLE_VFS_FTP
990 char *
991 load_anon_passwd (void)
993 char *buffer;
995 buffer = mc_config_get_string (mc_main_config, "Misc", "ftpfs_password", "");
997 if ((buffer != NULL) && (buffer[0] != '\0'))
998 return buffer;
1000 g_free (buffer);
1001 return NULL;
1003 #endif /* ENABLE_VFS_FTP */
1005 void
1006 load_keymap_defs (void)
1009 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
1010 * definitions override global settings.
1012 mc_config_t *mc_global_keymap;
1014 mc_global_keymap = load_setup_get_keymap_profile_config ();
1016 if (mc_global_keymap != NULL)
1018 #ifdef USE_INTERNAL_EDIT
1019 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1020 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
1021 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1022 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
1023 #endif
1025 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1026 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1027 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1028 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1030 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1031 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1032 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1033 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1035 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1036 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1038 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1039 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1041 listbox_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1042 load_keymap_from_section ("listbox", listbox_keymap, mc_global_keymap);
1044 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1045 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1047 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1048 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1050 dialog_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1051 load_keymap_from_section ("dialog", dialog_keymap, mc_global_keymap);
1053 #ifdef USE_DIFF_VIEW
1054 diff_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1055 load_keymap_from_section ("diffviewer", diff_keymap, mc_global_keymap);
1056 #endif
1057 mc_config_deinit (mc_global_keymap);
1060 main_map = default_main_map;
1061 if (main_keymap && main_keymap->len > 0)
1062 main_map = (global_keymap_t *) main_keymap->data;
1064 main_x_map = default_main_x_map;
1065 if (main_x_keymap && main_x_keymap->len > 0)
1066 main_x_map = (global_keymap_t *) main_x_keymap->data;
1068 panel_map = default_panel_keymap;
1069 if (panel_keymap && panel_keymap->len > 0)
1070 panel_map = (global_keymap_t *) panel_keymap->data;
1072 input_map = default_input_keymap;
1073 if (input_keymap && input_keymap->len > 0)
1074 input_map = (global_keymap_t *) input_keymap->data;
1076 listbox_map = default_listbox_keymap;
1077 if (listbox_keymap && listbox_keymap->len > 0)
1078 listbox_map = (global_keymap_t *) listbox_keymap->data;
1080 tree_map = default_tree_keymap;
1081 if (tree_keymap && tree_keymap->len > 0)
1082 tree_map = (global_keymap_t *) tree_keymap->data;
1084 help_map = default_help_keymap;
1085 if (help_keymap && help_keymap->len > 0)
1086 help_map = (global_keymap_t *) help_keymap->data;
1088 dialog_map = default_dialog_keymap;
1089 if (dialog_keymap && dialog_keymap->len > 0)
1090 dialog_map = (global_keymap_t *) dialog_keymap->data;
1092 #ifdef USE_DIFF_VIEW
1093 diff_map = default_diff_keymap;
1094 if (diff_keymap && diff_keymap->len > 0)
1095 diff_map = (global_keymap_t *) diff_keymap->data;
1096 #endif
1100 void
1101 free_keymap_defs (void)
1103 #ifdef USE_INTERNAL_EDIT
1104 if (editor_keymap != NULL)
1105 g_array_free (editor_keymap, TRUE);
1106 if (editor_x_keymap != NULL)
1107 g_array_free (editor_x_keymap, TRUE);
1108 #endif
1109 if (viewer_keymap != NULL)
1110 g_array_free (viewer_keymap, TRUE);
1111 if (viewer_hex_keymap != NULL)
1112 g_array_free (viewer_hex_keymap, TRUE);
1113 if (main_keymap != NULL)
1114 g_array_free (main_keymap, TRUE);
1115 if (main_x_keymap != NULL)
1116 g_array_free (main_x_keymap, TRUE);
1117 if (panel_keymap != NULL)
1118 g_array_free (panel_keymap, TRUE);
1119 if (input_keymap != NULL)
1120 g_array_free (input_keymap, TRUE);
1121 if (listbox_keymap != NULL)
1122 g_array_free (listbox_keymap, TRUE);
1123 if (tree_keymap != NULL)
1124 g_array_free (tree_keymap, TRUE);
1125 if (help_keymap != NULL)
1126 g_array_free (help_keymap, TRUE);
1127 if (dialog_keymap != NULL)
1128 g_array_free (dialog_keymap, TRUE);
1129 #ifdef USE_DIFF_VIEW
1130 if (diff_keymap != NULL)
1131 g_array_free (diff_keymap, TRUE);
1132 #endif
1135 void
1136 panel_load_setup (WPanel * panel, const char *section)
1138 size_t i;
1139 char *buffer, buffer2[BUF_TINY];
1141 panel->reverse = mc_config_get_int (mc_panels_config, section, "reverse", 0);
1142 panel->case_sensitive =
1143 mc_config_get_int (mc_panels_config, section, "case_sensitive",
1144 OS_SORT_CASE_SENSITIVE_DEFAULT);
1145 panel->exec_first = mc_config_get_int (mc_panels_config, section, "exec_first", 0);
1147 /* Load sort order */
1148 buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
1149 panel->current_sort_field = panel_get_field_by_id (buffer);
1150 if (panel->current_sort_field == NULL)
1151 panel->current_sort_field = panel_get_field_by_id ("name");
1153 g_free (buffer);
1155 /* Load the listing mode */
1156 buffer = mc_config_get_string (mc_panels_config, section, "list_mode", "full");
1157 panel->list_type = list_full;
1158 for (i = 0; list_types[i].key != NULL; i++)
1159 if (g_ascii_strcasecmp (list_types[i].key, buffer) == 0)
1161 panel->list_type = list_types[i].list_type;
1162 break;
1164 g_free (buffer);
1166 /* User formats */
1167 g_free (panel->user_format);
1168 panel->user_format =
1169 mc_config_get_string (mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
1171 for (i = 0; i < LIST_TYPES; i++)
1173 g_free (panel->user_status_format[i]);
1174 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
1175 panel->user_status_format[i] =
1176 mc_config_get_string (mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
1179 panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0);
1182 void
1183 panel_save_setup (struct WPanel *panel, const char *section)
1185 char buffer[BUF_TINY];
1186 size_t i;
1188 mc_config_set_int (mc_panels_config, section, "reverse", panel->reverse);
1189 mc_config_set_int (mc_panels_config, section, "case_sensitive", panel->case_sensitive);
1190 mc_config_set_int (mc_panels_config, section, "exec_first", panel->exec_first);
1192 mc_config_set_string (mc_panels_config, section, "sort_order", panel->current_sort_field->id);
1194 for (i = 0; list_types[i].key != NULL; i++)
1195 if (list_types[i].list_type == panel->list_type)
1197 mc_config_set_string (mc_panels_config, section, "list_mode", list_types[i].key);
1198 break;
1201 mc_config_set_string (mc_panels_config, section, "user_format", panel->user_format);
1203 for (i = 0; i < LIST_TYPES; i++)
1205 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
1206 mc_config_set_string (mc_panels_config, section, buffer, panel->user_status_format[i]);
1209 mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status);
1212 void
1213 save_panel_types (void)
1215 panel_view_mode_t type;
1217 if (mc_run_mode != MC_RUN_FULL)
1218 return;
1220 if (!panels_options.auto_save_setup)
1221 return;
1223 type = get_display_type (0);
1224 panel_save_type ("New Left Panel", type);
1225 if (type == view_listing)
1226 panel_save_setup (left_panel, left_panel->panel_name);
1227 type = get_display_type (1);
1228 panel_save_type ("New Right Panel", type);
1229 if (type == view_listing)
1230 panel_save_setup (right_panel, right_panel->panel_name);
1232 mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel));
1234 if (current_panel != NULL)
1235 mc_config_set_string (mc_panels_config, "Dirs", "current_is_left",
1236 get_current_index () == 0 ? "1" : "0");
1238 if (mc_panels_config->ini_path == NULL)
1239 mc_panels_config->ini_path = g_strdup (panels_profile_name);
1241 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
1242 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
1244 mc_config_save_file (mc_panels_config, NULL);
1248 Load panels options from [Panels] section.
1250 void
1251 panels_load_options (void)
1253 size_t i;
1254 int qmode;
1256 /* Backward compatibility: load old parameters */
1257 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1258 *panels_ini_options[i].opt_addr =
1259 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1260 panels_ini_options[i].opt_old_name != NULL
1261 ? panels_ini_options[i].opt_old_name : panels_ini_options[i].opt_name,
1262 *panels_ini_options[i].opt_addr);
1264 qmode = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1265 "quick_search_case_sensitive", (int) panels_options.qsearch_mode);
1266 if (qmode < 0)
1267 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1268 else if (qmode >= QSEARCH_NUM)
1269 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1270 else
1271 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1273 /* overwrite by new parameters */
1274 if (mc_config_has_group (mc_main_config, panels_section))
1276 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1277 *panels_ini_options[i].opt_addr =
1278 mc_config_get_bool (mc_main_config, panels_section,
1279 panels_ini_options[i].opt_name,
1280 *panels_ini_options[i].opt_addr);
1282 qmode = mc_config_get_int (mc_main_config, panels_section,
1283 "quick_search_mode", (int) panels_options.qsearch_mode);
1284 if (qmode < 0)
1285 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1286 else if (qmode >= QSEARCH_NUM)
1287 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1288 else
1289 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1294 Save panels options in [Panels] section.
1296 void
1297 panels_save_options (void)
1299 size_t i;
1301 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1302 mc_config_set_bool (mc_main_config, panels_section,
1303 panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr);
1305 mc_config_set_int (mc_main_config, panels_section,
1306 "quick_search_mode", (int) panels_options.qsearch_mode);