mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX: Don't normalize path delimiters in parameters because params like "/h" won't work.
UPD: Support environment variables in commands.
This commit is contained in:
parent
759f26707d
commit
f52d52dffb
7 changed files with 87 additions and 60 deletions
|
|
@ -912,15 +912,7 @@ begin
|
|||
Cmd:= MainToolBar.GetButtonX(NumberOfButton, CmdX);
|
||||
Path:= MainToolBar.GetButtonX(NumberOfButton, PathX);
|
||||
Param:= QuoteStr(aFile.FullPath);
|
||||
if Actions.Execute(Cmd, Param) = uActs.cf_Error then
|
||||
begin
|
||||
Cmd:= mbExpandFileName(Cmd);
|
||||
Path:= ReplaceEnvVars(Path);
|
||||
ReplaceExtCommand(Path, FrameLeft, FrameRight, ActiveFrame);
|
||||
if Length(Path) <> 0 then
|
||||
mbSetCurrentDir(Path);
|
||||
ExecCmdFork(Format('"%s" %s', [Cmd, Param]));
|
||||
end;
|
||||
ExecCmd(Cmd, Param, Path);
|
||||
end;
|
||||
finally
|
||||
FreeAndNil(aFile);
|
||||
|
|
@ -2740,7 +2732,7 @@ begin
|
|||
if I >= 0 then
|
||||
begin
|
||||
sDir:= MainToolBar.GetButtonX(I, PathX);
|
||||
ReplaceExtCommand(sDir, FrameLeft, FrameRight, ActiveFrame);
|
||||
sDir:= PrepareParameter(sDir, FrameLeft, FrameRight, ActiveFrame, [ppoNormalizePathDelims]);
|
||||
tbChangeDir.Caption := 'CD ' + sDir;
|
||||
if sDir <> '' then
|
||||
tbChangeDir.Visible:= true;
|
||||
|
|
@ -3563,18 +3555,14 @@ end;
|
|||
|
||||
function TfrmMain.ExecCmd(Cmd: String; Param: String=''; StartPath: String=''): Boolean;
|
||||
begin
|
||||
Cmd := NormalizePathDelimiters(Cmd);
|
||||
Param := NormalizePathDelimiters(Param);
|
||||
Param := ReplaceEnvVars(Param);
|
||||
ReplaceExtCommand(Param, FrameLeft, FrameRight, ActiveFrame);
|
||||
Cmd := ReplaceEnvVars(Cmd); // For Command only replace environment variables.
|
||||
Param := PrepareParameter(Param, FrameLeft, FrameRight, ActiveFrame);
|
||||
|
||||
if Actions.Execute(Cmd, Param) <> uActs.cf_Error then
|
||||
Result:= True
|
||||
else
|
||||
begin
|
||||
StartPath := NormalizePathDelimiters(StartPath);
|
||||
StartPath := ReplaceEnvVars(StartPath);
|
||||
ReplaceExtCommand(StartPath, FrameLeft, FrameRight, ActiveFrame);
|
||||
StartPath := PrepareParameter(StartPath, FrameLeft, FrameRight, ActiveFrame, [ppoNormalizePathDelims]);
|
||||
|
||||
// Only add a space after command if there are parameters.
|
||||
if Length(Param) > 0 then
|
||||
|
|
@ -3966,7 +3954,7 @@ begin
|
|||
Exit;
|
||||
|
||||
sDir := MainToolBar.GetButtonX(I, PathX);
|
||||
ReplaceExtCommand(sDir, FrameLeft, FrameRight, ActiveFrame);
|
||||
sDir := PrepareParameter(sDir, FrameLeft, FrameRight, ActiveFrame, [ppoNormalizePathDelims]);
|
||||
Actions.cm_ChangeDir(sDir);
|
||||
end;
|
||||
|
||||
|
|
@ -4055,6 +4043,8 @@ begin
|
|||
end;
|
||||
edtCommand.DroppedDown:= False;
|
||||
|
||||
sCmd:= ReplaceEnvVars(sCmd);
|
||||
|
||||
if (fspDirectAccess in ActiveFrame.FileSource.GetProperties) then
|
||||
begin
|
||||
iIndex:= Pos('cd ', sCmd);
|
||||
|
|
@ -4694,4 +4684,4 @@ begin
|
|||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
*)
|
||||
ReplaceExtCommand(sOpenCmd, aFile, aFileView.CurrentPath);
|
||||
sOpenCmd := PrepareParameter(sOpenCmd, aFile);
|
||||
if ProcessExtCommand(sOpenCmd, aFileView.CurrentPath) then
|
||||
Exit;
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -581,6 +581,7 @@ begin
|
|||
|
||||
SplitCmdLine(sCmdLine, sFileName, sParams);
|
||||
DCDebug('File: ' + sFileName + ' Params: ' + sParams + ' WorkDir: ' + wWorkDir);
|
||||
sFileName:= NormalizePathDelimiters(sFileName);
|
||||
wFileName:= UTF8Decode(sFileName);
|
||||
wParams:= UTF8Decode(sParams);
|
||||
Result := (ShellExecuteW(0, 'open', PWChar(wFileName), PWChar(wParams), PWChar(wWorkDir), SW_SHOW) > 32);
|
||||
|
|
@ -1874,4 +1875,4 @@ begin
|
|||
{$ENDIF}
|
||||
end;
|
||||
|
||||
end.
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ begin
|
|||
sAct:= sl.Names[I];
|
||||
if (SysUtils.CompareText('OPEN', sAct) = 0) or (SysUtils.CompareText('VIEW', sAct) = 0) or (SysUtils.CompareText('EDIT', sAct) = 0) then Continue;
|
||||
sCmd:= sl.ValueFromIndex[I];
|
||||
ReplaceExtCommand(sCmd, aFile, aFile.Path);
|
||||
sCmd:= PrepareParameter(sCmd, aFile);
|
||||
mi:= TMenuItem.Create(miActions);
|
||||
mi.Caption:= sAct;
|
||||
mi.Hint:= sCmd;
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ begin
|
|||
else
|
||||
begin
|
||||
sCmd:= Copy(sCmd, Pos('=', sCmd) + 1, Length(sCmd));
|
||||
ReplaceExtCommand(sCmd, aFile, aFile.Path);
|
||||
sCmd:= PrepareParameter(sCmd, aFile);
|
||||
try
|
||||
with frmMain.ActiveFrame do
|
||||
begin
|
||||
|
|
@ -509,4 +509,4 @@ begin
|
|||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1407,7 +1407,7 @@ begin
|
|||
|
||||
if (sViewCmd<>'') then
|
||||
begin
|
||||
ReplaceExtCommand(sViewCmd, aFile);
|
||||
sViewCmd := PrepareParameter(sViewCmd, aFile);
|
||||
ProcessExtCommand(sViewCmd, ActiveFrame.CurrentPath);
|
||||
// TODO:
|
||||
// If TempFileSource is used, create a wait thread that will
|
||||
|
|
@ -1531,7 +1531,7 @@ begin
|
|||
|
||||
if (sEditCmd <> '') then
|
||||
begin
|
||||
ReplaceExtCommand(sEditCmd, aFile);
|
||||
sEditCmd := PrepareParameter(sEditCmd, aFile);
|
||||
ProcessExtCommand(sEditCmd, aFile.Path);
|
||||
end
|
||||
else
|
||||
|
|
@ -2989,4 +2989,4 @@ begin
|
|||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,12 +29,29 @@ interface
|
|||
uses
|
||||
Classes, SysUtils, uFile, uFileView;
|
||||
|
||||
procedure ReplaceExtCommand(var sCmd: String;
|
||||
leftPanel: TFileView;
|
||||
rightPanel: TFileView;
|
||||
activePanel: TFileView); overload;
|
||||
type
|
||||
TPrepareParameterOption = (ppoNormalizePathDelims);
|
||||
TPrepareParameterOptions = set of TPrepareParameterOption;
|
||||
|
||||
procedure ReplaceExtCommand(var sCmd:String; aFile: TFile; ActiveDir: String=''); overload;
|
||||
function PrepareParameter(sParam: String;
|
||||
leftPanel: TFileView;
|
||||
rightPanel: TFileView;
|
||||
activePanel: TFileView;
|
||||
options: TPrepareParameterOptions = []): String; overload;
|
||||
function PrepareParameter(sParam: String;
|
||||
aFile: TFile;
|
||||
options: TPrepareParameterOptions = []): String; overload;
|
||||
{en
|
||||
Replace variable parameters that depend on files in panels.
|
||||
}
|
||||
function ReplaceVarParams(sSourceStr: String;
|
||||
leftPanel: TFileView;
|
||||
rightPanel: TFileView;
|
||||
activePanel: TFileView): String; overload;
|
||||
{en
|
||||
Replace variable parameters that depend on the file in active dir.
|
||||
}
|
||||
function ReplaceVarParams(sSourceStr: String; aFile: TFile): String; overload;
|
||||
function ProcessExtCommand(sCmd:String; ActiveDir: String): Boolean;
|
||||
function ShellExecuteEx(sCmd, sFileName, sActiveDir: String): Boolean;
|
||||
|
||||
|
|
@ -44,6 +61,30 @@ uses
|
|||
Process, UTF8Process, uDCUtils, uShowForm, uGlobs, uOSUtils,
|
||||
uFileSystemFileSource;
|
||||
|
||||
function PrepareParameter(sParam: String;
|
||||
leftPanel: TFileView;
|
||||
rightPanel: TFileView;
|
||||
activePanel: TFileView;
|
||||
options: TPrepareParameterOptions = []): String;
|
||||
begin
|
||||
Result := sParam;
|
||||
if ppoNormalizePathDelims in Options then
|
||||
Result := NormalizePathDelimiters(Result);
|
||||
Result := ReplaceEnvVars(Result);
|
||||
Result := ReplaceVarParams(Result, leftPanel, rightPanel, activePanel);
|
||||
Result := Trim(Result);
|
||||
end;
|
||||
|
||||
function PrepareParameter(sParam: String; aFile: TFile; options: TPrepareParameterOptions = []): String;
|
||||
begin
|
||||
Result := sParam;
|
||||
if ppoNormalizePathDelims in Options then
|
||||
Result := NormalizePathDelimiters(Result);
|
||||
Result := ReplaceEnvVars(Result);
|
||||
Result := ReplaceVarParams(Result, aFile);
|
||||
Result := Trim(Result);
|
||||
end;
|
||||
|
||||
(*
|
||||
Functions (without parameters they give output for all selected files):
|
||||
%f - only filename
|
||||
|
|
@ -86,10 +127,10 @@ uses
|
|||
- if only 1 file selected : -first <file_1>
|
||||
- if 2 (or more) files selected: -first <file_1> -second <file_2>
|
||||
*)
|
||||
procedure ReplaceExtCommand(var sCmd: String;
|
||||
leftPanel: TFileView;
|
||||
rightPanel: TFileView;
|
||||
activePanel: TFileView);
|
||||
function ReplaceVarParams(sSourceStr: String;
|
||||
leftPanel: TFileView;
|
||||
rightPanel: TFileView;
|
||||
activePanel: TFileView): String;
|
||||
type
|
||||
TFunctType = (ftNone, ftName, ftDir, ftPath, ftSingleDir);
|
||||
TStatePos = (spNone, spPercent, spFunction, spPrefix, spPostfix,
|
||||
|
|
@ -170,7 +211,7 @@ var
|
|||
begin
|
||||
// Copy [parseStartIndex .. limit - 1].
|
||||
if limit > parseStartIndex then
|
||||
sOutput := sOutput + Copy(sCmd, parseStartIndex, limit - parseStartIndex);
|
||||
sOutput := sOutput + Copy(sSourceStr, parseStartIndex, limit - parseStartIndex);
|
||||
parseStartIndex := index;
|
||||
end;
|
||||
|
||||
|
|
@ -213,7 +254,7 @@ var
|
|||
state.pos := spComplete
|
||||
else
|
||||
begin
|
||||
state.sFileIndex := state.sFileIndex + sCmd[index];
|
||||
state.sFileIndex := state.sFileIndex + sSourceStr[index];
|
||||
state.pos := spIndex;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -251,18 +292,18 @@ begin
|
|||
|
||||
ResetState(state);
|
||||
|
||||
while index <= Length(sCmd) do
|
||||
while index <= Length(sSourceStr) do
|
||||
begin
|
||||
case state.pos of
|
||||
spNone:
|
||||
if sCmd[index] = '%' then
|
||||
if sSourceStr[index] = '%' then
|
||||
begin
|
||||
state.pos := spPercent;
|
||||
state.functStartIndex := index;
|
||||
end;
|
||||
|
||||
spPercent:
|
||||
case sCmd[index] of
|
||||
case sSourceStr[index] of
|
||||
'f':
|
||||
begin
|
||||
state.funct := ftName;
|
||||
|
|
@ -288,7 +329,7 @@ begin
|
|||
end;
|
||||
|
||||
spFunction:
|
||||
case sCmd[index] of
|
||||
case sSourceStr[index] of
|
||||
'l':
|
||||
begin
|
||||
state.files := leftFiles;
|
||||
|
|
@ -328,7 +369,7 @@ begin
|
|||
end;
|
||||
|
||||
spSide:
|
||||
case sCmd[index] of
|
||||
case sSourceStr[index] of
|
||||
'0'..'9':
|
||||
ProcessNumber;
|
||||
'{':
|
||||
|
|
@ -338,7 +379,7 @@ begin
|
|||
end;
|
||||
|
||||
spIndex:
|
||||
case sCmd[index] of
|
||||
case sSourceStr[index] of
|
||||
'0'..'9':
|
||||
ProcessNumber;
|
||||
'{':
|
||||
|
|
@ -348,7 +389,7 @@ begin
|
|||
end;
|
||||
|
||||
spPrefix, spPostfix:
|
||||
case sCmd[index] of
|
||||
case sSourceStr[index] of
|
||||
'}':
|
||||
begin
|
||||
if state.pos = spPostfix then
|
||||
|
|
@ -363,15 +404,15 @@ begin
|
|||
begin
|
||||
case state.pos of
|
||||
spPrefix:
|
||||
state.prefix := state.prefix + sCmd[index];
|
||||
state.prefix := state.prefix + sSourceStr[index];
|
||||
spPostfix:
|
||||
state.postfix := state.postfix + sCmd[index];
|
||||
state.postfix := state.postfix + sSourceStr[index];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
spGotPrefix:
|
||||
case sCmd[index] of
|
||||
case sSourceStr[index] of
|
||||
'{':
|
||||
ProcessOpenBracket;
|
||||
else
|
||||
|
|
@ -392,7 +433,7 @@ begin
|
|||
else
|
||||
AddParsedText(index);
|
||||
|
||||
sCmd := sOutput;
|
||||
Result := sOutput;
|
||||
|
||||
finally
|
||||
if Assigned(leftFiles) then
|
||||
|
|
@ -402,16 +443,11 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure ReplaceExtCommand(var sCmd:String; aFile: TFile; ActiveDir: String);
|
||||
function ReplaceVarParams(sSourceStr: String; aFile: TFile): String;
|
||||
begin
|
||||
with aFile do
|
||||
begin
|
||||
sCmd:= GetCmdDirFromEnvVar(sCmd);
|
||||
sCmd:= StringReplace(sCmd,'%f',QuoteStr(Name),[rfReplaceAll]);
|
||||
sCmd:= StringReplace(sCmd,'%d',QuoteStr(Path),[rfReplaceAll]);
|
||||
sCmd:= StringReplace(sCmd,'%p',QuoteStr(Path + Name),[rfReplaceAll]);
|
||||
sCmd:= Trim(sCmd);
|
||||
end;
|
||||
Result := StringReplace(sSourceStr,'%f',QuoteStr(aFile.Name),[rfReplaceAll]);
|
||||
Result := StringReplace(Result ,'%d',QuoteStr(aFile.Path),[rfReplaceAll]);
|
||||
Result := StringReplace(Result ,'%p',QuoteStr(aFile.FullPath),[rfReplaceAll]);
|
||||
end;
|
||||
|
||||
function ProcessExtCommand(sCmd:String; ActiveDir: String): Boolean;
|
||||
|
|
@ -487,7 +523,7 @@ begin
|
|||
sCommand:= gExts.GetExtActionCmd(aFile, sCmd);
|
||||
if sCommand <> '' then
|
||||
begin
|
||||
ReplaceExtCommand(sCommand, aFile, sActiveDir);
|
||||
sCommand := PrepareParameter(sCommand, aFile);
|
||||
Result:= ProcessExtCommand(sCommand, sActiveDir);
|
||||
end;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue