Ticket #2344: Fix line jump when started as editor
[midnight-commander.git] / src / setup.c
bloba307a90e329b155c7ccb4feb9436a5296c9713e8
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 /*** file scope macro definitions **************************************/
115 /* In order to use everywhere the same setup for the locale we use defines */
116 #define FMTYEAR _("%b %e %Y")
117 #define FMTTIME _("%b %e %H:%M")
119 /*** file scope type declarations **************************************/
121 /*** file scope variables **********************************************/
123 static char *panels_profile_name = NULL; /* .mc/panels.ini */
125 /* *INDENT-OFF* */
126 static const struct
128 const char *key;
129 int list_type;
130 } list_types [] = {
131 { "full", list_full },
132 { "brief", list_brief },
133 { "long", list_long },
134 { "user", list_user },
135 { NULL, 0 }
138 static const struct
140 const char *opt_name;
141 panel_view_mode_t opt_type;
142 } panel_types [] = {
143 { "listing", view_listing },
144 { "quickview", view_quick },
145 { "info", view_info },
146 { "tree", view_tree },
147 { NULL, view_listing }
150 static const struct
152 const char *opt_name;
153 int *opt_addr;
154 } layout [] = {
155 { "equal_split", &equal_split },
156 { "first_panel_size", &first_panel_size },
157 { "message_visible", &message_visible },
158 { "keybar_visible", &keybar_visible },
159 { "xterm_title", &xterm_title },
160 { "output_lines", &output_lines },
161 { "command_prompt", &command_prompt },
162 { "menubar_visible", &menubar_visible },
163 { "show_mini_info", &show_mini_info },
164 { "free_space", &free_space },
165 { NULL, NULL }
168 static const struct
170 const char *opt_name;
171 int *opt_addr;
172 } int_options [] = {
173 { "verbose", &verbose },
174 { "pause_after_run", &pause_after_run },
175 { "shell_patterns", &easy_patterns },
176 { "auto_save_setup", &auto_save_setup },
177 { "auto_menu", &auto_menu },
178 { "use_internal_view", &use_internal_view },
179 { "use_internal_edit", &use_internal_edit },
180 { "clear_before_exec", &clear_before_exec },
181 { "confirm_delete", &confirm_delete },
182 { "confirm_overwrite", &confirm_overwrite },
183 { "confirm_execute", &confirm_execute },
184 { "confirm_history_cleanup", &confirm_history_cleanup },
185 { "confirm_exit", &confirm_exit },
186 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
187 { "safe_delete", &safe_delete },
188 { "mouse_repeat_rate", &mou_auto_repeat },
189 { "double_click_speed", &double_click_speed },
190 #ifndef HAVE_CHARSET
191 { "eight_bit_clean", &eight_bit_clean },
192 { "full_eight_bits", &full_eight_bits },
193 #endif /* !HAVE_CHARSET */
194 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
195 { "confirm_view_dir", &confirm_view_dir },
196 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
197 { "mouse_close_dialog", &mouse_close_dialog},
198 { "fast_refresh", &fast_refresh },
199 { "drop_menus", &drop_menus },
200 { "wrap_mode", &mcview_global_wrap_mode},
201 { "old_esc_mode", &old_esc_mode },
202 { "old_esc_mode_timeout", &old_esc_mode_timeout },
203 { "cd_symlinks", &cd_symlinks },
204 { "show_all_if_ambiguous", &show_all_if_ambiguous },
205 { "max_dirt_limit", &mcview_max_dirt_limit },
206 { "torben_fj_mode", &torben_fj_mode },
207 { "use_file_to_guess_type", &use_file_to_check_type },
208 { "alternate_plus_minus", &alternate_plus_minus },
209 { "only_leading_plus_minus", &only_leading_plus_minus },
210 { "show_output_starts_shell", &output_starts_shell },
211 { "xtree_mode", &xtree_mode },
212 { "num_history_items_recorded", &num_history_items_recorded },
213 { "file_op_compute_totals", &file_op_compute_totals },
214 { "classic_progressbar", &classic_progressbar},
215 #ifdef ENABLE_VFS
216 { "vfs_timeout", &vfs_timeout },
217 #ifdef ENABLE_VFS_FTP
218 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
219 { "use_netrc", &ftpfs_use_netrc },
220 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
221 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
222 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
223 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
224 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
225 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
226 #endif /* ENABLE_VFS_FTP */
227 #ifdef ENABLE_VFS_FISH
228 { "fish_directory_timeout", &fish_directory_timeout },
229 #endif /* ENABLE_VFS_FISH */
230 #endif /* ENABLE_VFS */
231 /* option_tab_spacing is used in internal viewer */
232 { "editor_tab_spacing", &option_tab_spacing },
233 #ifdef USE_INTERNAL_EDIT
234 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
235 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
236 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
237 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
238 { "editor_fake_half_tabs", &option_fake_half_tabs },
239 { "editor_option_save_mode", &option_save_mode },
240 { "editor_option_save_position", &option_save_position },
241 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
242 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
243 { "editor_edit_confirm_save", &edit_confirm_save },
244 { "editor_syntax_highlighting", &option_syntax_highlighting },
245 { "editor_persistent_selections", &option_persistent_selections },
246 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
247 { "editor_visible_tabs", &visible_tabs },
248 { "editor_visible_spaces", &visible_tws },
249 { "editor_line_state", &option_line_state },
250 { "editor_simple_statusbar", &simple_statusbar },
251 { "editor_check_new_line", &option_check_nl_at_eof },
252 { "editor_show_right_margin", &show_right_margin },
253 #endif /* USE_INTERNAL_EDIT */
254 { "nice_rotating_dash", &nice_rotating_dash },
255 { "horizontal_split", &horizontal_split },
256 { "mcview_remember_file_position", &mcview_remember_file_position },
257 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
258 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
259 { "select_flags", &select_flags },
260 { NULL, NULL }
263 static const struct
265 const char *opt_name;
266 char **opt_addr;
267 const char *opt_defval;
268 } str_options[] = {
269 #ifdef USE_INTERNAL_EDIT
270 { "editor_backup_extension", &option_backup_ext, "~" },
271 #endif
272 { "mcview_eof", &mcview_show_eof, "" },
273 { NULL, NULL, NULL }
276 static const struct
278 const char *opt_name;
279 const char *opt_old_name;
280 gboolean *opt_addr;
281 } panels_ini_options[] = {
282 { "kilobyte_si", NULL, &panels_options.kilobyte_si },
283 { "mix_all_files", NULL, &panels_options.mix_all_files },
284 { "show_backups", NULL, &panels_options.show_backups },
285 { "show_dot_files", NULL, &panels_options.show_dot_files },
286 { "fast_reload", NULL, &panels_options.fast_reload },
287 { "fast_reload_msg_shown", NULL, &panels_options.fast_reload_msg_shown },
288 { "mark_moves_down", NULL, &panels_options.mark_moves_down },
289 { "reverse_files_only", NULL, &panels_options.reverse_files_only },
290 { "auto_save_setup_panels", "auto_save_setup", &panels_options.auto_save_setup },
291 { "navigate_with_arrows", NULL, &panels_options.navigate_with_arrows },
292 { "panel_scroll_pages", "scroll_pages", &panels_options.scroll_pages },
293 { "mouse_move_pages", NULL, &panels_options.mouse_move_pages },
294 { "filetype_mode", NULL, &panels_options.filetype_mode },
295 { "permission_mode", NULL, &panels_options.permission_mode },
296 { NULL, NULL, NULL }
298 /* *INDENT-ON* */
300 static const char *panels_section = "Panels";
302 /*** file scope functions **********************************************/
305 Get name of config file.
307 \param subdir
308 if not NULL, then config also search into specified subdir.
310 \param config_file_name
311 If specified filename is relative, then will search in standart patches.
313 \return
314 Newly allocated path to config name or NULL if file not found.
316 If config_file_name is a relative path, then search config in stantart pathes.
318 static char *
319 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
322 TODO: IMHO, in future this function must be placed into mc_config module.
323 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
324 home_mc => mc_user_homedir
326 char *lc_basename, *ret;
328 if (config_file_name == NULL)
329 return NULL;
331 if (g_path_is_absolute (config_file_name))
332 return g_strdup (config_file_name);
335 lc_basename = g_path_get_basename (config_file_name);
336 if (lc_basename == NULL)
337 return NULL;
339 if (subdir != NULL)
340 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
341 else
342 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
344 if (exist_file (ret))
346 g_free (lc_basename);
347 return ret;
349 g_free (ret);
351 if (subdir != NULL)
352 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
353 else
354 ret = g_build_filename (mc_home, lc_basename, NULL);
356 if (exist_file (ret))
358 g_free (lc_basename);
359 return ret;
361 g_free (ret);
363 if (subdir != NULL)
364 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
365 else
366 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
368 g_free (lc_basename);
370 if (exist_file (ret))
371 return ret;
373 g_free (ret);
374 return NULL;
378 static const char *
379 setup__is_cfg_group_must_panel_config (const char *grp)
381 return (!strcasecmp ("Dirs", grp) ||
382 !strcasecmp ("Temporal:New Right Panel", grp) ||
383 !strcasecmp ("Temporal:New Left Panel", grp) ||
384 !strcasecmp ("New Left Panel", grp) || !strcasecmp ("New Right Panel", grp))
385 ? grp : NULL;
388 static void
389 setup__move_panels_config_into_separate_file (const char *profile)
391 mc_config_t *tmp_cfg;
392 char **groups, **curr_grp;
393 const char *need_grp;
395 if (!exist_file (profile))
396 return;
398 tmp_cfg = mc_config_init (profile);
399 if (!tmp_cfg)
400 return;
402 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
403 if (!groups)
405 mc_config_deinit (tmp_cfg);
406 return;
409 while (*curr_grp)
411 if (setup__is_cfg_group_must_panel_config (*curr_grp) == NULL)
412 mc_config_del_group (tmp_cfg, *curr_grp);
413 curr_grp++;
416 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
417 mc_config_deinit (tmp_cfg);
419 tmp_cfg = mc_config_init (profile);
420 if (!tmp_cfg)
422 g_strfreev (groups);
423 return;
426 curr_grp = groups;
428 while (*curr_grp)
430 need_grp = setup__is_cfg_group_must_panel_config (*curr_grp);
431 if (need_grp != NULL)
433 mc_config_del_group (tmp_cfg, need_grp);
435 curr_grp++;
437 g_strfreev (groups);
439 mc_config_save_file (tmp_cfg, NULL);
440 mc_config_deinit (tmp_cfg);
444 Create new mc_config object from specified ini-file or
445 append data to existing mc_config object from ini-file
448 static void
449 load_setup_init_config_from_file (mc_config_t ** config, const char *fname)
452 TODO: IMHO, in future this function must be placed into mc_config module.
454 if (exist_file (fname))
456 if (*config != NULL)
457 mc_config_read_file (*config, fname);
458 else
459 *config = mc_config_init (fname);
463 static void
464 load_layout (void)
466 size_t i;
468 for (i = 0; layout[i].opt_name != NULL; i++)
469 *layout[i].opt_addr = mc_config_get_int (mc_main_config, "Layout",
470 layout[i].opt_name, *layout[i].opt_addr);
473 static void
474 load_keys_from_section (const char *terminal, mc_config_t * cfg)
476 char *section_name;
477 gchar **profile_keys, **keys;
478 gchar **values, **curr_values;
479 char *valcopy, *value;
480 long key_code;
481 gsize len, values_len;
483 if (terminal == NULL)
484 return;
486 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
487 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
489 while (*profile_keys != NULL)
491 /* copy=other causes all keys from [terminal:other] to be loaded. */
492 if (g_ascii_strcasecmp (*profile_keys, "copy") == 0)
494 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
495 load_keys_from_section (valcopy, cfg);
496 g_free (valcopy);
497 profile_keys++;
498 continue;
501 curr_values = values =
502 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
504 key_code = lookup_key (*profile_keys, NULL);
506 if (key_code != 0)
508 if (curr_values != NULL)
510 while (*curr_values != NULL)
512 valcopy = convert_controls (*curr_values);
513 define_sequence (key_code, valcopy, MCKEY_NOACTION);
514 g_free (valcopy);
515 curr_values++;
518 else
520 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
521 valcopy = convert_controls (value);
522 define_sequence (key_code, valcopy, MCKEY_NOACTION);
523 g_free (valcopy);
524 g_free (value);
528 profile_keys++;
530 if (values != NULL)
531 g_strfreev (values);
533 g_strfreev (keys);
534 g_free (section_name);
537 static void
538 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
540 gchar **profile_keys, **keys;
541 gchar **values, **curr_values;
542 char *valcopy, *value;
543 int action;
544 gsize len, values_len;
546 if (section_name == NULL)
547 return;
549 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
551 while (*profile_keys != NULL)
553 curr_values = values =
554 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
556 action = lookup_action (*profile_keys);
558 if (action > 0)
560 if (curr_values != NULL)
562 while (*curr_values != NULL)
564 valcopy = convert_controls (*curr_values);
565 keybind_cmd_bind (keymap, valcopy, action);
566 g_free (valcopy);
567 curr_values++;
570 else
572 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
573 valcopy = convert_controls (value);
574 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
575 g_free (valcopy);
576 g_free (value);
580 profile_keys++;
582 if (values != NULL)
583 g_strfreev (values);
585 g_strfreev (keys);
588 static mc_config_t *
589 load_setup_get_keymap_profile_config (void)
592 TODO: IMHO, in future this function must be placed into mc_config module.
594 mc_config_t *keymap_config = NULL;
595 char *fname, *fname2;
597 /* 1) /usr/share/mc (mc_home_alt) */
598 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
599 load_setup_init_config_from_file (&keymap_config, fname);
600 g_free (fname);
602 /* 2) /etc/mc (mc_home) */
603 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
604 load_setup_init_config_from_file (&keymap_config, fname);
605 g_free (fname);
607 /* 3) ~/.mc (home_dir?) */
608 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
609 load_setup_init_config_from_file (&keymap_config, fname);
610 g_free (fname);
612 /* 4) main config; [Midnight Commander] -> keymap */
614 fname2 =
615 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, "keymap", GLOBAL_KEYMAP_FILE);
616 fname = load_setup_get_full_config_name (NULL, fname2);
617 if (fname != NULL)
619 load_setup_init_config_from_file (&keymap_config, fname);
620 g_free (fname);
622 g_free (fname2);
624 /* 5) getenv("MC_KEYMAP") */
625 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
626 if (fname != NULL)
628 load_setup_init_config_from_file (&keymap_config, fname);
629 g_free (fname);
632 /* 6) --keymap=<keymap> */
633 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
634 if (fname != NULL)
636 load_setup_init_config_from_file (&keymap_config, fname);
637 g_free (fname);
640 return keymap_config;
643 static panel_view_mode_t
644 setup__load_panel_state (const char *section)
646 char *buffer;
647 size_t i;
648 panel_view_mode_t mode = view_listing;
650 /* Load the display mode */
651 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
653 for (i = 0; panel_types[i].opt_name != NULL; i++)
654 if (g_ascii_strcasecmp (panel_types[i].opt_name, buffer) == 0)
656 mode = panel_types[i].opt_type;
657 break;
660 g_free (buffer);
662 return mode;
665 static void
666 panel_save_type (const char *section, panel_view_mode_t type)
668 size_t i;
670 for (i = 0; panel_types[i].opt_name != NULL; i++)
671 if (panel_types[i].opt_type == type)
673 mc_config_set_string (mc_panels_config, section, "display", panel_types[i].opt_name);
674 break;
678 /*** public functions **************************************************/
680 char *
681 setup_init (void)
683 char *profile;
684 char *inifile;
686 if (profile_name != NULL)
687 return profile_name;
689 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
690 if (!exist_file (profile))
692 inifile = concat_dir_and_file (mc_home, "mc.ini");
693 if (exist_file (inifile))
695 g_free (profile);
696 profile = inifile;
698 else
700 g_free (inifile);
701 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
702 if (exist_file (inifile))
704 g_free (profile);
705 profile = inifile;
707 else
708 g_free (inifile);
712 profile_name = profile;
714 return profile;
717 void
718 load_setup (void)
720 char *profile;
721 size_t i;
722 char *buffer;
723 const char *kt;
725 profile = setup_init ();
727 /* mc.lib is common for all users, but has priority lower than
728 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
729 global_profile_name = concat_dir_and_file (mc_home, MC_GLOBAL_CONFIG_FILE);
730 if (!exist_file (global_profile_name))
732 g_free (global_profile_name);
733 global_profile_name = concat_dir_and_file (mc_home_alt, MC_GLOBAL_CONFIG_FILE);
736 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
738 mc_main_config = mc_config_init (profile);
740 if (!exist_file (panels_profile_name))
741 setup__move_panels_config_into_separate_file (profile);
743 mc_panels_config = mc_config_init (panels_profile_name);
745 /* Load integer boolean options */
746 for (i = 0; int_options[i].opt_name != NULL; i++)
747 *int_options[i].opt_addr =
748 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
749 *int_options[i].opt_addr);
751 if (option_tab_spacing <= 0)
752 option_tab_spacing = DEFAULT_TAB_SPACING;
754 #ifdef USE_INTERNAL_EDIT
755 if (option_word_wrap_line_length <= 0)
756 option_word_wrap_line_length = DEFAULT_WRAP_LINE_LENGTH;
757 #endif /* USE_INTERNAL_EDIT */
759 /* overwrite old_esc_mode_timeout */
760 kt = getenv ("KEYBOARD_KEY_TIMEOUT_US");
761 if ((kt != NULL) && (kt[0] != '\0'))
762 old_esc_mode_timeout = atoi (kt);
764 /* Load string options */
765 for (i = 0; str_options[i].opt_name != NULL; i++)
766 *str_options[i].opt_addr =
767 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
768 str_options[i].opt_defval);
770 load_layout ();
771 panels_load_options ();
772 load_panelize ();
774 startup_left_mode = setup__load_panel_state ("New Left Panel");
775 startup_right_mode = setup__load_panel_state ("New Right Panel");
777 /* At least one of the panels is a listing panel */
778 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
779 startup_left_mode = view_listing;
781 if (mc_run_param1 == NULL)
783 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
784 if (vfs_file_is_local (buffer))
785 mc_run_param1 = buffer;
786 else
787 g_free (buffer);
790 boot_current_is_left = mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
792 /* Load time formats */
793 user_recent_timeformat =
794 mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
795 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
797 #ifdef ENABLE_VFS_FTP
798 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
799 ftpfs_ignore_chattr_errors = mc_config_get_bool (mc_main_config, CONFIG_APP_SECTION,
800 "ignore_ftp_chattr_errors", TRUE);
801 ftpfs_init_passwd ();
802 #endif /* ENABLE_VFS_FTP */
804 /* The default color and the terminal dependent color */
805 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
806 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
807 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
809 /* Load the directory history */
810 /* directory_history_load (); */
811 /* Remove the temporal entries */
813 #ifdef HAVE_CHARSET
814 if (load_codepages_list () > 0)
816 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
817 if (buffer[0] != '\0')
819 display_codepage = get_codepage_index (buffer);
820 cp_display = get_codepage_id (display_codepage);
822 g_free (buffer);
823 buffer = mc_config_get_string (mc_main_config, "Misc", "source_codepage", "");
824 if (buffer[0] != '\0')
826 default_source_codepage = get_codepage_index (buffer);
827 source_codepage = default_source_codepage; /* May be source_codepage don't needed this */
828 cp_source = get_codepage_id (source_codepage);
830 g_free (buffer);
833 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
834 if ((autodetect_codeset[0] != '\0') && (strcmp (autodetect_codeset, "off") != 0))
835 is_autodetect_codeset_enabled = TRUE;
837 g_free (init_translation_table (source_codepage, display_codepage));
838 buffer = (char *) get_codepage_id (display_codepage);
839 if (buffer != NULL)
840 utf8_display = str_isutf8 (buffer);
841 #endif /* HAVE_CHARSET */
842 clipboard_store_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_store", "");
843 clipboard_paste_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_paste", "");
846 gboolean
847 save_setup (void)
849 char *tmp_profile;
850 gboolean ret;
852 saving_setup = 1;
854 save_config ();
855 save_layout ();
856 panels_save_options ();
857 save_hotlist ();
858 save_panelize ();
859 save_panel_types ();
860 /* directory_history_save (); */
862 #ifdef ENABLE_VFS_FTP
863 mc_config_set_string (mc_main_config, "Misc", "ftpfs_password", ftpfs_anonymous_passwd);
864 if (ftpfs_proxy_host)
865 mc_config_set_string (mc_main_config, "Misc", "ftp_proxy_host", ftpfs_proxy_host);
866 #endif /* ENABLE_VFS_FTP */
868 #ifdef HAVE_CHARSET
869 mc_config_set_string (mc_main_config, "Misc", "display_codepage",
870 get_codepage_id (display_codepage));
871 mc_config_set_string (mc_main_config, "Misc", "source_codepage",
872 get_codepage_id (default_source_codepage));
873 mc_config_set_string (mc_main_config, "Misc", "autodetect_codeset", autodetect_codeset);
874 #endif /* HAVE_CHARSET */
875 mc_config_set_string (mc_main_config, "Misc", "clipboard_store", clipboard_store_path);
876 mc_config_set_string (mc_main_config, "Misc", "clipboard_paste", clipboard_paste_path);
878 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
879 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
881 g_free (tmp_profile);
882 saving_setup = 0;
883 return ret;
886 void
887 done_setup (void)
889 size_t i;
891 g_free (profile_name);
892 g_free (global_profile_name);
893 g_free (color_terminal_string);
894 g_free (term_color_string);
895 g_free (setup_color_string);
896 g_free (panels_profile_name);
897 mc_config_deinit (mc_main_config);
898 mc_config_deinit (mc_panels_config);
900 g_free (user_recent_timeformat);
901 g_free (user_old_timeformat);
903 for (i = 0; str_options[i].opt_name != NULL; i++)
904 g_free (*str_options[i].opt_addr);
906 done_hotlist ();
907 done_panelize ();
908 /* directory_history_free (); */
911 void
912 save_config (void)
914 char *profile;
915 GError *error = NULL;
916 size_t i;
918 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
920 /* Save integer options */
921 for (i = 0; int_options[i].opt_name != NULL; i++)
922 mc_config_set_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
923 *int_options[i].opt_addr);
925 /* Save string options */
926 for (i = 0; str_options[i].opt_name != NULL; i++)
927 mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
928 *str_options[i].opt_addr);
930 if (!mc_config_save_to_file (mc_main_config, profile, &error))
931 setup_save_config_show_error (profile, &error);
933 g_free (profile);
936 void
937 setup_save_config_show_error (const char *filename, GError ** error)
939 if (error != NULL && *error != NULL)
941 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"), filename, (*error)->message);
942 g_error_free (*error);
943 *error = NULL;
947 void
948 save_layout (void)
950 char *profile;
951 size_t i;
953 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
954 /* Save integer options */
955 for (i = 0; layout[i].opt_name != NULL; i++)
956 mc_config_set_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
957 mc_config_save_to_file (mc_main_config, profile, NULL);
958 g_free (profile);
961 void
962 load_key_defs (void)
965 * Load keys from mc.lib before ~/.mc/ini, so that the user
966 * definitions override global settings.
968 mc_config_t *mc_global_config;
970 mc_global_config = mc_config_init (global_profile_name);
971 if (mc_global_config != NULL)
973 load_keys_from_section ("general", mc_global_config);
974 load_keys_from_section (getenv ("TERM"), mc_global_config);
975 mc_config_deinit (mc_global_config);
978 load_keys_from_section ("general", mc_main_config);
979 load_keys_from_section (getenv ("TERM"), mc_main_config);
982 #ifdef ENABLE_VFS_FTP
983 char *
984 load_anon_passwd (void)
986 char *buffer;
988 buffer = mc_config_get_string (mc_main_config, "Misc", "ftpfs_password", "");
990 if ((buffer != NULL) && (buffer[0] != '\0'))
991 return buffer;
993 g_free (buffer);
994 return NULL;
996 #endif /* ENABLE_VFS_FTP */
998 void
999 load_keymap_defs (void)
1002 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
1003 * definitions override global settings.
1005 mc_config_t *mc_global_keymap;
1007 mc_global_keymap = load_setup_get_keymap_profile_config ();
1009 if (mc_global_keymap != NULL)
1011 #ifdef USE_INTERNAL_EDIT
1012 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1013 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
1014 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1015 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
1016 #endif
1018 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1019 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1020 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1021 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1023 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1024 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1025 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1026 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1028 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1029 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1031 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1032 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1034 listbox_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1035 load_keymap_from_section ("listbox", listbox_keymap, mc_global_keymap);
1037 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1038 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1040 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1041 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1043 dialog_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1044 load_keymap_from_section ("dialog", dialog_keymap, mc_global_keymap);
1046 #ifdef USE_DIFF_VIEW
1047 diff_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1048 load_keymap_from_section ("diffviewer", diff_keymap, mc_global_keymap);
1049 #endif
1050 mc_config_deinit (mc_global_keymap);
1053 main_map = default_main_map;
1054 if (main_keymap && main_keymap->len > 0)
1055 main_map = (global_keymap_t *) main_keymap->data;
1057 main_x_map = default_main_x_map;
1058 if (main_x_keymap && main_x_keymap->len > 0)
1059 main_x_map = (global_keymap_t *) main_x_keymap->data;
1061 panel_map = default_panel_keymap;
1062 if (panel_keymap && panel_keymap->len > 0)
1063 panel_map = (global_keymap_t *) panel_keymap->data;
1065 input_map = default_input_keymap;
1066 if (input_keymap && input_keymap->len > 0)
1067 input_map = (global_keymap_t *) input_keymap->data;
1069 listbox_map = default_listbox_keymap;
1070 if (listbox_keymap && listbox_keymap->len > 0)
1071 listbox_map = (global_keymap_t *) listbox_keymap->data;
1073 tree_map = default_tree_keymap;
1074 if (tree_keymap && tree_keymap->len > 0)
1075 tree_map = (global_keymap_t *) tree_keymap->data;
1077 help_map = default_help_keymap;
1078 if (help_keymap && help_keymap->len > 0)
1079 help_map = (global_keymap_t *) help_keymap->data;
1081 dialog_map = default_dialog_keymap;
1082 if (dialog_keymap && dialog_keymap->len > 0)
1083 dialog_map = (global_keymap_t *) dialog_keymap->data;
1085 #ifdef USE_DIFF_VIEW
1086 diff_map = default_diff_keymap;
1087 if (diff_keymap && diff_keymap->len > 0)
1088 diff_map = (global_keymap_t *) diff_keymap->data;
1089 #endif
1093 void
1094 free_keymap_defs (void)
1096 #ifdef USE_INTERNAL_EDIT
1097 if (editor_keymap != NULL)
1098 g_array_free (editor_keymap, TRUE);
1099 if (editor_x_keymap != NULL)
1100 g_array_free (editor_x_keymap, TRUE);
1101 #endif
1102 if (viewer_keymap != NULL)
1103 g_array_free (viewer_keymap, TRUE);
1104 if (viewer_hex_keymap != NULL)
1105 g_array_free (viewer_hex_keymap, TRUE);
1106 if (main_keymap != NULL)
1107 g_array_free (main_keymap, TRUE);
1108 if (main_x_keymap != NULL)
1109 g_array_free (main_x_keymap, TRUE);
1110 if (panel_keymap != NULL)
1111 g_array_free (panel_keymap, TRUE);
1112 if (input_keymap != NULL)
1113 g_array_free (input_keymap, TRUE);
1114 if (listbox_keymap != NULL)
1115 g_array_free (listbox_keymap, TRUE);
1116 if (tree_keymap != NULL)
1117 g_array_free (tree_keymap, TRUE);
1118 if (help_keymap != NULL)
1119 g_array_free (help_keymap, TRUE);
1120 if (dialog_keymap != NULL)
1121 g_array_free (dialog_keymap, TRUE);
1122 #ifdef USE_DIFF_VIEW
1123 if (diff_keymap != NULL)
1124 g_array_free (diff_keymap, TRUE);
1125 #endif
1128 void
1129 panel_load_setup (WPanel * panel, const char *section)
1131 size_t i;
1132 char *buffer, buffer2[BUF_TINY];
1134 panel->reverse = mc_config_get_int (mc_panels_config, section, "reverse", 0);
1135 panel->case_sensitive =
1136 mc_config_get_int (mc_panels_config, section, "case_sensitive",
1137 OS_SORT_CASE_SENSITIVE_DEFAULT);
1138 panel->exec_first = mc_config_get_int (mc_panels_config, section, "exec_first", 0);
1140 /* Load sort order */
1141 buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
1142 panel->current_sort_field = panel_get_field_by_id (buffer);
1143 if (panel->current_sort_field == NULL)
1144 panel->current_sort_field = panel_get_field_by_id ("name");
1146 g_free (buffer);
1148 /* Load the listing mode */
1149 buffer = mc_config_get_string (mc_panels_config, section, "list_mode", "full");
1150 panel->list_type = list_full;
1151 for (i = 0; list_types[i].key != NULL; i++)
1152 if (g_ascii_strcasecmp (list_types[i].key, buffer) == 0)
1154 panel->list_type = list_types[i].list_type;
1155 break;
1157 g_free (buffer);
1159 /* User formats */
1160 g_free (panel->user_format);
1161 panel->user_format =
1162 mc_config_get_string (mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
1164 for (i = 0; i < LIST_TYPES; i++)
1166 g_free (panel->user_status_format[i]);
1167 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
1168 panel->user_status_format[i] =
1169 mc_config_get_string (mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
1172 panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0);
1175 void
1176 panel_save_setup (struct WPanel *panel, const char *section)
1178 char buffer[BUF_TINY];
1179 size_t i;
1181 mc_config_set_int (mc_panels_config, section, "reverse", panel->reverse);
1182 mc_config_set_int (mc_panels_config, section, "case_sensitive", panel->case_sensitive);
1183 mc_config_set_int (mc_panels_config, section, "exec_first", panel->exec_first);
1185 mc_config_set_string (mc_panels_config, section, "sort_order", panel->current_sort_field->id);
1187 for (i = 0; list_types[i].key != NULL; i++)
1188 if (list_types[i].list_type == panel->list_type)
1190 mc_config_set_string (mc_panels_config, section, "list_mode", list_types[i].key);
1191 break;
1194 mc_config_set_string (mc_panels_config, section, "user_format", panel->user_format);
1196 for (i = 0; i < LIST_TYPES; i++)
1198 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
1199 mc_config_set_string (mc_panels_config, section, buffer, panel->user_status_format[i]);
1202 mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status);
1205 void
1206 save_panel_types (void)
1208 panel_view_mode_t type;
1210 if (mc_run_mode != MC_RUN_FULL)
1211 return;
1213 if (!panels_options.auto_save_setup)
1214 return;
1216 type = get_display_type (0);
1217 panel_save_type ("New Left Panel", type);
1218 if (type == view_listing)
1219 panel_save_setup (left_panel, left_panel->panel_name);
1220 type = get_display_type (1);
1221 panel_save_type ("New Right Panel", type);
1222 if (type == view_listing)
1223 panel_save_setup (right_panel, right_panel->panel_name);
1225 mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel));
1227 if (current_panel != NULL)
1228 mc_config_set_string (mc_panels_config, "Dirs", "current_is_left",
1229 get_current_index () == 0 ? "1" : "0");
1231 if (mc_panels_config->ini_path == NULL)
1232 mc_panels_config->ini_path = g_strdup (panels_profile_name);
1234 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
1235 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
1237 mc_config_save_file (mc_panels_config, NULL);
1241 Load panels options from [Panels] section.
1243 void
1244 panels_load_options (void)
1246 size_t i;
1247 int qmode;
1249 /* Backward compatibility: load old parameters */
1250 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1251 *panels_ini_options[i].opt_addr =
1252 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1253 panels_ini_options[i].opt_old_name != NULL
1254 ? panels_ini_options[i].opt_old_name : panels_ini_options[i].opt_name,
1255 *panels_ini_options[i].opt_addr);
1257 qmode = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1258 "quick_search_case_sensitive", (int) panels_options.qsearch_mode);
1259 if (qmode < 0)
1260 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1261 else if (qmode >= QSEARCH_NUM)
1262 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1263 else
1264 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1266 /* overwrite by new parameters */
1267 if (mc_config_has_group (mc_main_config, panels_section))
1269 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1270 *panels_ini_options[i].opt_addr =
1271 mc_config_get_bool (mc_main_config, panels_section,
1272 panels_ini_options[i].opt_name,
1273 *panels_ini_options[i].opt_addr);
1275 qmode = mc_config_get_int (mc_main_config, panels_section,
1276 "quick_search_mode", (int) panels_options.qsearch_mode);
1277 if (qmode < 0)
1278 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1279 else if (qmode >= QSEARCH_NUM)
1280 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1281 else
1282 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1287 Save panels options in [Panels] section.
1289 void
1290 panels_save_options (void)
1292 size_t i;
1294 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1295 mc_config_set_bool (mc_main_config, panels_section,
1296 panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr);
1298 mc_config_set_int (mc_main_config, panels_section,
1299 "quick_search_mode", (int) panels_options.qsearch_mode);