From 6d5c2628fe4d0907e492c775a262e771dd41d560 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Mon, 10 May 2010 13:43:34 +0400 Subject: [PATCH] Ticket #2042: added a capability to create relative symlinks. The original patch was posted by Anton Monroe to mc-devel@gnome.org mailing list: http://mail.gnome.org/archives/mc-devel/2006-April/msg00020.html Signed-off-by: Andrew Borodin --- doc/man/mc.1.in | 53 +++++++++++++++++++++++++++--------- doc/man/ru/mc.1.in | 61 +++++++++++++++++++++++++++++++----------- misc/mc.keymap.default | 1 + misc/mc.keymap.emacs | 1 + src/cmd.c | 32 +++++++++------------- src/cmd.h | 10 +++++-- src/cmddef.h | 1 + src/keybind.c | 2 ++ src/main.c | 10 ++++--- 9 files changed, 119 insertions(+), 52 deletions(-) diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in index 653e62d77..d02d16c4d 100644 --- a/doc/man/mc.1.in +++ b/doc/man/mc.1.in @@ -384,10 +384,17 @@ Chown command on the current file or on the tagged files. .TP .B C\-x l -run the link command. +run the hard link command. .TP .B C\-x s -run the symbolic link command. +run the absolute symbolic link command. +.TP +.B C\-x v +run the relative symbolic link command. See the +.\"LINK2" +File Menu +.\"File Menu" +section for more information about symbolic links. .TP .B C\-x i set the other panel display mode to information. @@ -994,7 +1001,7 @@ user menu\&. The user menu provides an easy way to provide users with a menu and add extra features to the Midnight Commander. .PP -.B View (F3, Shift\-F3) +.B View (F3, F13) .PP View the currently selected file. By default this invokes the .\"LINK2" @@ -1009,7 +1016,7 @@ is undefined, the .B PAGER environment variable is tried. If .B PAGER -is also undefined, the "view" command is invoked. If you use Shift\-F3 +is also undefined, the "view" command is invoked. If you use F13 instead, the viewer will be invoked without doing any formatting or preprocessing to the file. .PP @@ -1022,7 +1029,7 @@ viewer. .PP .B Edit (F4, F14) .PP -Press F4 to edit the highlighted file. Press F14 (usually Shift\-F4) +Press F4 to edit the highlighted file. Press F14 (usually F14) to start the editor with a new, empty file. Currently they invoke the .B vi @@ -1048,7 +1055,7 @@ see Mask copy/rename\&. .\"Mask Copy/Rename" .PP -F15 (usually Shift\-F5) is similar, but defaults to the directory in the +F15 (usually F15) is similar, but defaults to the directory in the selected panel. It always operates on the selected file, regardless of any tagged files. .PP @@ -1064,12 +1071,17 @@ is used to control the background process. .PP Create a hard link to the current file. .PP -.B SymLink (C\-x s) +.B Absolute symlink (C\-x s) .PP -Create a symbolic link to the current file. To those of you who don't -know what links are: creating a link to a file is a bit like copying -the file, but both the source filename and the destination filename -represent the same file image. For example, if you edit one of these +Create a absolute symbolic link to the current file. +.PP +.B Relative symLink (C\-x v) +.PP +Create a relative symbolic link to the current file. +.PP +To those of you who don't know what links are: creating a link to a file +is a bit like copying the file, but both the source filename and the destination +filename represent the same file image. For example, if you edit one of these files, all changes you make will appear in both files. Some people call links aliases or shortcuts. .PP @@ -1089,6 +1101,23 @@ The original file which the link points to is shown on mini\-status line if the option is enabled. Use symbolic links when you want to avoid the confusion that can be caused by hard links. .PP +When you press "C\-x s" Midnight Commander will automatically fill in the +complete path+filename of the original file and suggest a name for the link. +You can change either one. +.PP +Sometimes you may want to change the absolute path of the original into +a relative path. An absolute path starts from the root directory: +.PP +.I /home/frodo/mc/mc -> /home/frodo/new/mc +.PP +A relative link describes the original file's location starting from the +location of the link itself: +.PP +.I /home/frodo/mc/mc -> ../new/mc +.PP +You can force Midnight Commander to suggest a relative path by pressing +"C\-x v" instead of "C\-x s". +.PP .B Rename/Move (F6, F16) .PP Press F6 to pop up an input dialog to copy the currently selected file (or @@ -1097,7 +1126,7 @@ directory/filename you specify in the input dialog. The destination defaults to the directory in the non\-selected panel. For more details look at Copy (F5) operation above, most of the things are quite similar. .PP -F16 (usually Shift\-F6) is similar, but defaults to the directory in the +F16 (usually F16) is similar, but defaults to the directory in the selected panel. It always operates on the selected file, regardless of any tagged files. .PP diff --git a/doc/man/ru/mc.1.in b/doc/man/ru/mc.1.in index 8515b15d5..22886f62e 100644 --- a/doc/man/ru/mc.1.in +++ b/doc/man/ru/mc.1.in @@ -388,7 +388,14 @@ Chown Запускает команду создания жесткой ссылки. .TP .B C\-x s. -Запускает команду создания символической ссылки. +Запускает команду создания абсолютной символической ссылки. +.TP +.B C\-x v. +Запускает команду создания относительной символической ссылки. +Для более детальной информации о ссылках смотрите раздел +.\"LINK2" +.I Меню "Файл" +.\"File Menu" .TP .B C\-x i. Переводит пассивную панель в режим "Информация". @@ -998,7 +1005,7 @@ Escape\-последовательности, генерируемые клав Меню "Файл" содержит следующие команды (соответствующие "горячие" клавиши указываются в скобках): .PP -.B Просмотр файла (F3, Shift\-F3) +.B Просмотр файла (F3, F13) .PP Просмотреть файл, на который указывает подсветка. По умолчанию при этом вызывается @@ -1013,10 +1020,10 @@ Escape\-последовательности, генерируемые клав Если переменная .B PAGER не определена, вызывается встроенная программа. Если вместо F3 нажать -Shift\-F3, встроенная программа просмотра не выполняет предварительного +F13, встроенная программа просмотра не выполняет предварительного форматирования или обработки файла. .PP -.B Просмотр вывода команды (Filtered View) (M\-!) +.B Просмотр вывода команды (M\-!) .PP По этой команде на экране появляется строка ввода, в которой вы можете ввести любую команду с параметрами (по умолчанию предлагается @@ -1038,7 +1045,7 @@ Shift\-F3, встроенная программа просмотра не вы .I (use_internal_edit) в меню "Настройки / Конфигурация"). .PP -.B Копирование (F5) +.B Копирование (F5, F15) .PP Вызывается диалоговое окно, в котором предлагается скопировать подсвеченный файл из каталога, отображаемого в активной панели (или @@ -1078,14 +1085,19 @@ Shift\-F3, встроенная программа просмотра не вы .PP Создает жесткую ссылку на текущий файл. .PP -.B Символич. ссылка (C\-x s) +.B Абсолютная символическая ссылка (C\-x s) .PP -Создает символическую ссылку на текущий файл. Если вы не знаете, что -такое ссылки: создание ссылки в некотором смысле подобно копированию -файла, но и исходное имя файла и ссылка указывают на один и тот же -реальный файл на диске. Поэтому, если вы, например, редактируете файл, -то изменения будут появляться в обеих копиях. Синонимами термина -"ссылка" (link) являются термины алиас (alias) и ярлык (shortcut). +Создает абсолютную символическую ссылку на текущий файл. +.PP +.B Относительная символическая ссылка (C\-x v) +.PP +Создает относительную символическую ссылку на текущий файл. +.PP +Если вы не знаете, что такое ссылки: создание ссылки в некотором смысле +подобно копированию файла, но и исходное имя файла и ссылка указывают +на один и тот же реальный файл на диске. Поэтому, если вы, например, +редактируете файл, то изменения будут появляться в обеих копиях. Синонимами +термина "ссылка" (link) являются термины "алиас" (alias) и "ярлык" (shortcut). .PP Жесткая ссылка выглядит как реальный файл. После создания жесткой ссылки невозможно различить, где исходный файл, а где ссылка. Если вы удаляете @@ -1097,8 +1109,8 @@ Shift\-F3, встроенная программа просмотра не вы .PP Символическая ссылка \- это ссылка на имя исходного файла. Если исходный файл удален, символическая ссылка становится бесполезной. Символическую -ссылку легко отличить от первоначального имени файла и программа -Midnight Commander указывает символические ссылки выводя знак "@" перед +ссылку легко отличить от первоначального имени файла, и программа +Midnight Commander указывает символические ссылки, выводя знак "@" перед именем такой ссылки (кроме ссылок на каталоги, которые обозначаются знаком тильды "~"). Если на экран выводится строка мини\-статуса (опция "Показывать мини\-статус" ("Show mini\-status") включена), то в ней @@ -1106,13 +1118,32 @@ Midnight Commander указывает символические ссылки в случаях, когда хотите избежать путаницы, связанной с применением жестких ссылок. .PP +Когда вы нажимаете клавиатурное сочетание "C\-x s", Midnight Commander +автоматически заполняет поля диалога создания ссылки: имя ссылки и имя файла, +на который будет указывать ссылка. Вы можете изменить их. +.PP +Но иногда требуется, чтобы ссылка указывала на файл не по абсолютному пути, +а по относительному. Абсолютный путь начинается с корневого каталога: +.PP +.I /home/frodo/mc/mc -> /home/frodo/new/mc +.PP +Относительный путь указывает на расположение файла относительно места, где +будет располагаться создаваемая ссылка: +.PP +.I /home/frodo/mc/mc -> ../new/mc +.PP +Для того, чтобы создать относительную символическую ссылку, используйте +клавиатурное сочетание "C\-x v" вместо "C\-x s". +.PP .B Владелец/группа (C\-x o) +.PP Позволяет выполнить команду chown. .PP .B Права (расширенные) +.PP Позволяет изменить права доступа и владения файлом. .PP -.B Переименование (F6) +.B Переименование (F6, F16) .PP Вызывается диалоговое окно, в котором предлагается перенести подсвеченный файл из каталога, отображаемого в активной панели (или diff --git a/misc/mc.keymap.default b/misc/mc.keymap.default index 3ca804357..3d5574fe9 100644 --- a/misc/mc.keymap.default +++ b/misc/mc.keymap.default @@ -247,6 +247,7 @@ CmdCompareDirs = d CmdEditSymlink = ctrl-s CmdLink = l CmdSymlink = s +CmdRelativeSymlink = v CmdInfo = i CmdQuickView = q CmdExternalPanelize = exclamation diff --git a/misc/mc.keymap.emacs b/misc/mc.keymap.emacs index 8ce705638..535299d9b 100644 --- a/misc/mc.keymap.emacs +++ b/misc/mc.keymap.emacs @@ -251,6 +251,7 @@ CmdCompareDirs = d CmdEditSymlink = ctrl-s CmdLink = l CmdSymlink = s +CmdRelativeSymlink = v CmdInfo = i CmdQuickView = q CmdExternalPanelize = exclamation diff --git a/src/cmd.c b/src/cmd.c index d31749468..859dbc8ed 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1000,11 +1000,11 @@ view_other_cmd (void) } static void -do_link (int symbolic_link, const char *fname) +do_link (link_type_t link_type, const char *fname) { char *dest = NULL, *src = NULL; - if (!symbolic_link) + if (link_type == LINK_HARDLINK) { src = g_strdup_printf (_("Link %s to:"), str_trunc (fname, 46)); dest = input_expand_dialog (_(" Link "), src, MC_HISTORY_FM_LINK, ""); @@ -1019,17 +1019,17 @@ do_link (int symbolic_link, const char *fname) char *s; char *d; - /* suggest the full path for symlink */ + /* suggest the full path for symlink, and either the full or + relative path to the file it points to */ s = concat_dir_and_file (current_panel->cwd, fname); if (get_other_type () == view_listing) - { d = concat_dir_and_file (other_panel->cwd, fname); - } else - { d = g_strdup (fname); - } + + if (link_type == LINK_SYMLINK_RELATIVE) + s = diff_two_paths (other_panel->cwd, s); symlink_dialog (s, d, &dest, &src); g_free (d); @@ -1041,6 +1041,7 @@ do_link (int symbolic_link, const char *fname) if (-1 == mc_symlink (dest, src)) message (D_ERROR, MSG_ERROR, _(" symlink: %s "), unix_error_string (errno)); } + update_panels (UP_OPTIMIZE, UP_KEEPSEL); repaint_screen (); @@ -1050,21 +1051,12 @@ do_link (int symbolic_link, const char *fname) } void -link_cmd (void) +link_cmd (link_type_t link_type) { - do_link (0, selection (current_panel)->fname); -} + char *filename = selection (current_panel)->fname; -void -symlink_cmd (void) -{ - char *filename = NULL; - filename = selection (current_panel)->fname; - - if (filename) - { - do_link (1, filename); - } + if (filename != NULL) + do_link (link_type, filename); } void diff --git a/src/cmd.h b/src/cmd.h index f17818ed4..d06e11062 100644 --- a/src/cmd.h +++ b/src/cmd.h @@ -8,6 +8,13 @@ #ifndef MC_CMD_H #define MC_CMD_H +typedef enum +{ + LINK_HARDLINK = 0, + LINK_SYMLINK_ABSOLUTE, + LINK_SYMLINK_RELATIVE +} link_type_t; + void netlink_cmd (void); void ftplink_cmd (void); void fishlink_cmd (void); @@ -46,8 +53,7 @@ void compare_dirs_cmd (void); void diff_view_cmd (void); void history_cmd (void); void tree_cmd (void); -void link_cmd (void); -void symlink_cmd (void); +void link_cmd (link_type_t link_type); void edit_symlink_cmd (void); void reverse_selection_cmd (void); void unselect_cmd (void); diff --git a/src/cmddef.h b/src/cmddef.h index cfde3ab5e..dfd61f1f5 100644 --- a/src/cmddef.h +++ b/src/cmddef.h @@ -379,6 +379,7 @@ #define CK_TogglePanelsSplit 7075 #define CK_DiffViewCmd 7076 #define CK_PanelOptionsBox 7077 +#define CK_RelativeSymlinkCmd 7078 /* panels */ #define CK_PanelChdirOtherPanel 8001 diff --git a/src/keybind.c b/src/keybind.c index 5a66a2822..fbc118cf2 100644 --- a/src/keybind.c +++ b/src/keybind.c @@ -372,6 +372,7 @@ static name_keymap_t command_names[] = { { "CmdQuickChdir", CK_QuickChdirCmd }, { "CmdQuickView", CK_QuickViewCmd }, { "CmdQuietQuit", CK_QuietQuitCmd }, + { "CmdRelativeSymlink", CK_RelativeSymlinkCmd }, { "CmdRename", CK_RenameCmd }, { "CmdReread", CK_RereadCmd }, { "CmdReselectVfs", CK_ReselectVfs }, @@ -958,6 +959,7 @@ const global_keymap_t default_main_x_map[] = { { XCTRL ('r'), CK_CopyOtherReadlink, "C-r" }, { 'l', CK_LinkCmd, "l" }, { 's', CK_SymlinkCmd, "s" }, + { 'v', CK_RelativeSymlinkCmd, "v" }, { XCTRL ('s'), CK_EditSymlinkCmd, "C-s" }, { 'i', CK_InfoCmd, "i" }, { 'q', CK_QuickViewCmd, "q" }, diff --git a/src/main.c b/src/main.c index c23036257..7ba1a6bf4 100644 --- a/src/main.c +++ b/src/main.c @@ -699,7 +699,8 @@ create_file_menu (void) entries = g_list_append (entries, menu_entry_create (_("&Copy"), CK_CopyCmd)); entries = g_list_append (entries, menu_entry_create (_("C&hmod"), CK_ChmodCmd)); entries = g_list_append (entries, menu_entry_create (_("&Link"), CK_LinkCmd)); - entries = g_list_append (entries, menu_entry_create (_("&SymLink"), CK_SymlinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Symlink"), CK_SymlinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("Relative symlin&k"), CK_RelativeSymlinkCmd)); entries = g_list_append (entries, menu_entry_create (_("Edit s&ymlink"), CK_EditSymlinkCmd)); entries = g_list_append (entries, menu_entry_create (_("Ch&own"), CK_ChownCmd)); entries = @@ -1242,7 +1243,7 @@ midnight_execute_cmd (Widget * sender, unsigned long command) learn_keys (); break; case CK_LinkCmd: - link_cmd (); + link_cmd (LINK_HARDLINK); break; case CK_ListingCmd: listing_cmd (); @@ -1292,6 +1293,9 @@ midnight_execute_cmd (Widget * sender, unsigned long command) case CK_QuitCmd: quit_cmd (); break; + case CK_RelativeSymlinkCmd: + link_cmd (LINK_SYMLINK_RELATIVE); + break; case CK_RenameCmd: rename_cmd (); break; @@ -1336,7 +1340,7 @@ midnight_execute_cmd (Widget * sender, unsigned long command) swap_cmd (); break; case CK_SymlinkCmd: - symlink_cmd (); + link_cmd (LINK_SYMLINK_ABSOLUTE); break; case CK_ToggleListingCmd: toggle_listing_cmd ();