Merge branch '2042_relative_symlink'

* 2042_relative_symlink:
  Ticket #2042: added a capability to create relative symlinks.
This commit is contained in:
Andrew Borodin 2010-05-22 12:10:26 +04:00
commit b6d4862b63
9 changed files with 119 additions and 52 deletions

View File

@ -384,10 +384,17 @@ Chown
command on the current file or on the tagged files. command on the current file or on the tagged files.
.TP .TP
.B C\-x l .B C\-x l
run the link command. run the hard link command.
.TP .TP
.B C\-x s .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 .TP
.B C\-x i .B C\-x i
set the other panel display mode to information. 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 The user menu provides an easy way to provide users with a menu and
add extra features to the Midnight Commander. add extra features to the Midnight Commander.
.PP .PP
.B View (F3, Shift\-F3) .B View (F3, F13)
.PP .PP
View the currently selected file. By default this invokes the View the currently selected file. By default this invokes the
.\"LINK2" .\"LINK2"
@ -1009,7 +1016,7 @@ is undefined, the
.B PAGER .B PAGER
environment variable is tried. If environment variable is tried. If
.B PAGER .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 instead, the viewer will be invoked without doing any formatting or
preprocessing to the file. preprocessing to the file.
.PP .PP
@ -1022,7 +1029,7 @@ viewer.
.PP .PP
.B Edit (F4, F14) .B Edit (F4, F14)
.PP .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. to start the editor with a new, empty file.
Currently they invoke the Currently they invoke the
.B vi .B vi
@ -1048,7 +1055,7 @@ see
Mask copy/rename\&. Mask copy/rename\&.
.\"Mask Copy/Rename" .\"Mask Copy/Rename"
.PP .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 selected panel. It always operates on the selected file, regardless of
any tagged files. any tagged files.
.PP .PP
@ -1064,12 +1071,17 @@ is used to control the background process.
.PP .PP
Create a hard link to the current file. Create a hard link to the current file.
.PP .PP
.B SymLink (C\-x s) .B Absolute symlink (C\-x s)
.PP .PP
Create a symbolic link to the current file. To those of you who don't Create a absolute symbolic link to the current file.
know what links are: creating a link to a file is a bit like copying .PP
the file, but both the source filename and the destination filename .B Relative symLink (C\-x v)
represent the same file image. For example, if you edit one of these .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 files, all changes you make will appear in both files. Some people call
links aliases or shortcuts. links aliases or shortcuts.
.PP .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 option is enabled. Use symbolic links when you want to avoid the
confusion that can be caused by hard links. confusion that can be caused by hard links.
.PP .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) .B Rename/Move (F6, F16)
.PP .PP
Press F6 to pop up an input dialog to copy the currently selected file (or 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 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. look at Copy (F5) operation above, most of the things are quite similar.
.PP .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 selected panel. It always operates on the selected file, regardless of
any tagged files. any tagged files.
.PP .PP

View File

@ -388,7 +388,14 @@ Chown
Запускает команду создания жесткой ссылки. Запускает команду создания жесткой ссылки.
.TP .TP
.B C\-x s. .B C\-x s.
Запускает команду создания символической ссылки. Запускает команду создания абсолютной символической ссылки.
.TP
.B C\-x v.
Запускает команду создания относительной символической ссылки.
Для более детальной информации о ссылках смотрите раздел
.\"LINK2"
.I Меню "Файл"
.\"File Menu"
.TP .TP
.B C\-x i. .B C\-x i.
Переводит пассивную панель в режим "Информация". Переводит пассивную панель в режим "Информация".
@ -998,7 +1005,7 @@ Escape\-последовательности, генерируемые клав
Меню "Файл" содержит следующие команды (соответствующие "горячие" Меню "Файл" содержит следующие команды (соответствующие "горячие"
клавиши указываются в скобках): клавиши указываются в скобках):
.PP .PP
.B Просмотр файла (F3, Shift\-F3) .B Просмотр файла (F3, F13)
.PP .PP
Просмотреть файл, на который указывает подсветка. По умолчанию при этом Просмотреть файл, на который указывает подсветка. По умолчанию при этом
вызывается вызывается
@ -1013,10 +1020,10 @@ Escape\-последовательности, генерируемые клав
Если переменная Если переменная
.B PAGER .B PAGER
не определена, вызывается встроенная программа. Если вместо F3 нажать не определена, вызывается встроенная программа. Если вместо F3 нажать
Shift\-F3, встроенная программа просмотра не выполняет предварительного F13, встроенная программа просмотра не выполняет предварительного
форматирования или обработки файла. форматирования или обработки файла.
.PP .PP
.B Просмотр вывода команды (Filtered View) (M\-!) .B Просмотр вывода команды (M\-!)
.PP .PP
По этой команде на экране появляется строка ввода, в которой вы можете По этой команде на экране появляется строка ввода, в которой вы можете
ввести любую команду с параметрами (по умолчанию предлагается ввести любую команду с параметрами (по умолчанию предлагается
@ -1038,7 +1045,7 @@ Shift\-F3, встроенная программа просмотра не вы
.I (use_internal_edit) .I (use_internal_edit)
в меню "Настройки / Конфигурация"). в меню "Настройки / Конфигурация").
.PP .PP
.B Копирование (F5) .B Копирование (F5, F15)
.PP .PP
Вызывается диалоговое окно, в котором предлагается скопировать Вызывается диалоговое окно, в котором предлагается скопировать
подсвеченный файл из каталога, отображаемого в активной панели (или подсвеченный файл из каталога, отображаемого в активной панели (или
@ -1078,14 +1085,19 @@ Shift\-F3, встроенная программа просмотра не вы
.PP .PP
Создает жесткую ссылку на текущий файл. Создает жесткую ссылку на текущий файл.
.PP .PP
.B Символич. ссылка (C\-x s) .B Абсолютная символическая ссылка (C\-x s)
.PP .PP
Создает символическую ссылку на текущий файл. Если вы не знаете, что Создает абсолютную символическую ссылку на текущий файл.
такое ссылки: создание ссылки в некотором смысле подобно копированию .PP
файла, но и исходное имя файла и ссылка указывают на один и тот же .B Относительная символическая ссылка (C\-x v)
реальный файл на диске. Поэтому, если вы, например, редактируете файл, .PP
то изменения будут появляться в обеих копиях. Синонимами термина Создает относительную символическую ссылку на текущий файл.
"ссылка" (link) являются термины алиас (alias) и ярлык (shortcut). .PP
Если вы не знаете, что такое ссылки: создание ссылки в некотором смысле
подобно копированию файла, но и исходное имя файла и ссылка указывают
на один и тот же реальный файл на диске. Поэтому, если вы, например,
редактируете файл, то изменения будут появляться в обеих копиях. Синонимами
термина "ссылка" (link) являются термины "алиас" (alias) и "ярлык" (shortcut).
.PP .PP
Жесткая ссылка выглядит как реальный файл. После создания жесткой ссылки Жесткая ссылка выглядит как реальный файл. После создания жесткой ссылки
невозможно различить, где исходный файл, а где ссылка. Если вы удаляете невозможно различить, где исходный файл, а где ссылка. Если вы удаляете
@ -1097,8 +1109,8 @@ Shift\-F3, встроенная программа просмотра не вы
.PP .PP
Символическая ссылка \- это ссылка на имя исходного файла. Если исходный Символическая ссылка \- это ссылка на имя исходного файла. Если исходный
файл удален, символическая ссылка становится бесполезной. Символическую файл удален, символическая ссылка становится бесполезной. Символическую
ссылку легко отличить от первоначального имени файла и программа ссылку легко отличить от первоначального имени файла, и программа
Midnight Commander указывает символические ссылки выводя знак "@" перед Midnight Commander указывает символические ссылки, выводя знак "@" перед
именем такой ссылки (кроме ссылок на каталоги, которые обозначаются именем такой ссылки (кроме ссылок на каталоги, которые обозначаются
знаком тильды "~"). Если на экран выводится строка мини\-статуса (опция знаком тильды "~"). Если на экран выводится строка мини\-статуса (опция
"Показывать мини\-статус" ("Show mini\-status") включена), то в ней "Показывать мини\-статус" ("Show mini\-status") включена), то в ней
@ -1106,13 +1118,32 @@ Midnight Commander указывает символические ссылки в
случаях, когда хотите избежать путаницы, связанной с применением жестких случаях, когда хотите избежать путаницы, связанной с применением жестких
ссылок. ссылок.
.PP .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) .B Владелец/группа (C\-x o)
.PP
Позволяет выполнить команду chown. Позволяет выполнить команду chown.
.PP .PP
.B Права (расширенные) .B Права (расширенные)
.PP
Позволяет изменить права доступа и владения файлом. Позволяет изменить права доступа и владения файлом.
.PP .PP
.B Переименование (F6) .B Переименование (F6, F16)
.PP .PP
Вызывается диалоговое окно, в котором предлагается перенести Вызывается диалоговое окно, в котором предлагается перенести
подсвеченный файл из каталога, отображаемого в активной панели (или подсвеченный файл из каталога, отображаемого в активной панели (или

View File

@ -247,6 +247,7 @@ CmdCompareDirs = d
CmdEditSymlink = ctrl-s CmdEditSymlink = ctrl-s
CmdLink = l CmdLink = l
CmdSymlink = s CmdSymlink = s
CmdRelativeSymlink = v
CmdInfo = i CmdInfo = i
CmdQuickView = q CmdQuickView = q
CmdExternalPanelize = exclamation CmdExternalPanelize = exclamation

View File

@ -251,6 +251,7 @@ CmdCompareDirs = d
CmdEditSymlink = ctrl-s CmdEditSymlink = ctrl-s
CmdLink = l CmdLink = l
CmdSymlink = s CmdSymlink = s
CmdRelativeSymlink = v
CmdInfo = i CmdInfo = i
CmdQuickView = q CmdQuickView = q
CmdExternalPanelize = exclamation CmdExternalPanelize = exclamation

View File

@ -1000,11 +1000,11 @@ view_other_cmd (void)
} }
static 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; char *dest = NULL, *src = NULL;
if (!symbolic_link) if (link_type == LINK_HARDLINK)
{ {
src = g_strdup_printf (_("Link %s to:"), str_trunc (fname, 46)); src = g_strdup_printf (_("Link %s to:"), str_trunc (fname, 46));
dest = input_expand_dialog (_(" Link "), src, MC_HISTORY_FM_LINK, ""); 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 *s;
char *d; 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); s = concat_dir_and_file (current_panel->cwd, fname);
if (get_other_type () == view_listing) if (get_other_type () == view_listing)
{
d = concat_dir_and_file (other_panel->cwd, fname); d = concat_dir_and_file (other_panel->cwd, fname);
}
else else
{
d = g_strdup (fname); d = g_strdup (fname);
}
if (link_type == LINK_SYMLINK_RELATIVE)
s = diff_two_paths (other_panel->cwd, s);
symlink_dialog (s, d, &dest, &src); symlink_dialog (s, d, &dest, &src);
g_free (d); g_free (d);
@ -1041,6 +1041,7 @@ do_link (int symbolic_link, const char *fname)
if (-1 == mc_symlink (dest, src)) if (-1 == mc_symlink (dest, src))
message (D_ERROR, MSG_ERROR, _(" symlink: %s "), unix_error_string (errno)); message (D_ERROR, MSG_ERROR, _(" symlink: %s "), unix_error_string (errno));
} }
update_panels (UP_OPTIMIZE, UP_KEEPSEL); update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen (); repaint_screen ();
@ -1050,21 +1051,12 @@ do_link (int symbolic_link, const char *fname)
} }
void 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 if (filename != NULL)
symlink_cmd (void) do_link (link_type, filename);
{
char *filename = NULL;
filename = selection (current_panel)->fname;
if (filename)
{
do_link (1, filename);
}
} }
void void

View File

@ -8,6 +8,13 @@
#ifndef MC_CMD_H #ifndef MC_CMD_H
#define 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 netlink_cmd (void);
void ftplink_cmd (void); void ftplink_cmd (void);
void fishlink_cmd (void); void fishlink_cmd (void);
@ -46,8 +53,7 @@ void compare_dirs_cmd (void);
void diff_view_cmd (void); void diff_view_cmd (void);
void history_cmd (void); void history_cmd (void);
void tree_cmd (void); void tree_cmd (void);
void link_cmd (void); void link_cmd (link_type_t link_type);
void symlink_cmd (void);
void edit_symlink_cmd (void); void edit_symlink_cmd (void);
void reverse_selection_cmd (void); void reverse_selection_cmd (void);
void unselect_cmd (void); void unselect_cmd (void);

View File

@ -379,6 +379,7 @@
#define CK_TogglePanelsSplit 7075 #define CK_TogglePanelsSplit 7075
#define CK_DiffViewCmd 7076 #define CK_DiffViewCmd 7076
#define CK_PanelOptionsBox 7077 #define CK_PanelOptionsBox 7077
#define CK_RelativeSymlinkCmd 7078
/* panels */ /* panels */
#define CK_PanelChdirOtherPanel 8001 #define CK_PanelChdirOtherPanel 8001

View File

@ -372,6 +372,7 @@ static name_keymap_t command_names[] = {
{ "CmdQuickChdir", CK_QuickChdirCmd }, { "CmdQuickChdir", CK_QuickChdirCmd },
{ "CmdQuickView", CK_QuickViewCmd }, { "CmdQuickView", CK_QuickViewCmd },
{ "CmdQuietQuit", CK_QuietQuitCmd }, { "CmdQuietQuit", CK_QuietQuitCmd },
{ "CmdRelativeSymlink", CK_RelativeSymlinkCmd },
{ "CmdRename", CK_RenameCmd }, { "CmdRename", CK_RenameCmd },
{ "CmdReread", CK_RereadCmd }, { "CmdReread", CK_RereadCmd },
{ "CmdReselectVfs", CK_ReselectVfs }, { "CmdReselectVfs", CK_ReselectVfs },
@ -958,6 +959,7 @@ const global_keymap_t default_main_x_map[] = {
{ XCTRL ('r'), CK_CopyOtherReadlink, "C-r" }, { XCTRL ('r'), CK_CopyOtherReadlink, "C-r" },
{ 'l', CK_LinkCmd, "l" }, { 'l', CK_LinkCmd, "l" },
{ 's', CK_SymlinkCmd, "s" }, { 's', CK_SymlinkCmd, "s" },
{ 'v', CK_RelativeSymlinkCmd, "v" },
{ XCTRL ('s'), CK_EditSymlinkCmd, "C-s" }, { XCTRL ('s'), CK_EditSymlinkCmd, "C-s" },
{ 'i', CK_InfoCmd, "i" }, { 'i', CK_InfoCmd, "i" },
{ 'q', CK_QuickViewCmd, "q" }, { 'q', CK_QuickViewCmd, "q" },

View File

@ -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 (_("&Copy"), CK_CopyCmd));
entries = g_list_append (entries, menu_entry_create (_("C&hmod"), CK_ChmodCmd)); 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 (_("&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 (_("Edit s&ymlink"), CK_EditSymlinkCmd));
entries = g_list_append (entries, menu_entry_create (_("Ch&own"), CK_ChownCmd)); entries = g_list_append (entries, menu_entry_create (_("Ch&own"), CK_ChownCmd));
entries = entries =
@ -1242,7 +1243,7 @@ midnight_execute_cmd (Widget * sender, unsigned long command)
learn_keys (); learn_keys ();
break; break;
case CK_LinkCmd: case CK_LinkCmd:
link_cmd (); link_cmd (LINK_HARDLINK);
break; break;
case CK_ListingCmd: case CK_ListingCmd:
listing_cmd (); listing_cmd ();
@ -1292,6 +1293,9 @@ midnight_execute_cmd (Widget * sender, unsigned long command)
case CK_QuitCmd: case CK_QuitCmd:
quit_cmd (); quit_cmd ();
break; break;
case CK_RelativeSymlinkCmd:
link_cmd (LINK_SYMLINK_RELATIVE);
break;
case CK_RenameCmd: case CK_RenameCmd:
rename_cmd (); rename_cmd ();
break; break;
@ -1336,7 +1340,7 @@ midnight_execute_cmd (Widget * sender, unsigned long command)
swap_cmd (); swap_cmd ();
break; break;
case CK_SymlinkCmd: case CK_SymlinkCmd:
symlink_cmd (); link_cmd (LINK_SYMLINK_ABSOLUTE);
break; break;
case CK_ToggleListingCmd: case CK_ToggleListingCmd:
toggle_listing_cmd (); toggle_listing_cmd ();