1(* 2This Source Code Form is subject to the terms of the Mozilla Public 3License, v. 2.0. If a copy of the MPL was not distributed with this 4file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 6Copyright (c) Alexey Torgashin 7*) 8{$ifdef nn}begin end;{$endif} 9 10procedure TfmMain.DoLoadCommandLineBaseOptions(out AWindowPos: string; 11 out AAllowSessionLoad, AAllowSessionSave: TAppAllowSomething; 12 out AFileFolderCount: integer); 13// Function handles these options: -v -h -w -el -ns 14// Option -n is handled via var proc_globdata.AppAlwaysNewInstance 15var 16 SParam: string; 17 i: integer; 18begin 19 AWindowPos:= ''; 20 AAllowSessionLoad:= aalsEnable; 21 AAllowSessionSave:= aalsEnable; 22 AFileFolderCount:= 0; 23 24 for i:= 1 to ParamCount do 25 begin 26 SParam:= ParamStr(i); 27 if not SBeginsWith(SParam, '-') then 28 begin 29 if AAllowSessionLoad=aalsEnable then 30 AAllowSessionLoad:= aalsNotGood; //block loading last session if any filenames present 31 Inc(AFileFolderCount); 32 Continue; 33 end; 34 35 if (SParam='--version') or (SParam='-v') then 36 begin 37 MsgStdout('CudaText '+cAppExeVersion, true); 38 Halt; 39 end; 40 41 if (SParam='--help') or (SParam='-h') then 42 begin 43 MsgStdout(msgCommandLineHelp, true); 44 Halt; 45 end; 46 47 if SBeginsWith(SParam, '-w=') then 48 begin 49 AWindowPos:= Copy(SParam, 4, MaxInt); 50 Continue; 51 end; 52 53 if (SParam='-el') then 54 begin 55 MsgStdout(AppEncodingListAsString, true); 56 Halt; 57 end; 58 59 if (SParam='-ns') then 60 begin 61 AAllowSessionLoad:= aalsDisable; 62 AAllowSessionSave:= aalsDisable; 63 Continue; 64 end; 65 66 if (SParam='-nsl') then 67 begin 68 AAllowSessionLoad:= aalsDisable; 69 Continue; 70 end; 71 72 if (SParam='-nss') then 73 begin 74 AAllowSessionSave:= aalsDisable; 75 Continue; 76 end; 77 end; 78end; 79 80 81function _GetStdin: string; 82var 83 s: string; 84begin 85 Result:= ''; 86 Reset(Input); 87 while not EOF(Input) do 88 begin 89 ReadLn(Input, s); 90 Result+= s+#10; 91 end; 92end; 93 94procedure _AppFindFilesByMask(List: TStringList; AMask: string); 95var 96 Dir: string; 97begin 98 Dir:= GetCurrentDirUTF8; 99 100 //support full dir path 101 if IsOsFullPath(AMask) then 102 begin 103 Dir:= ExtractFileDir(AMask); 104 AMask:= ExtractFileName(AMask); 105 end 106 else 107 //support relative dir path 108 if Pos(DirectorySeparator, AMask)>0 then 109 begin 110 Dir+= DirectorySeparator+ExtractFileDir(AMask); 111 AMask:= ExtractFileName(AMask); 112 end; 113 114 FindAllFiles(List, Dir, AMask, false{SubDirs}); 115end; 116 117procedure TfmMain.DoLoadCommandParams(const AParams: array of string; AOpenOptions: string); 118// Function handles passed file names, folder names, and such params as -r -nh -z -e, 119// while others params are handled in DoLoadCommandLineBaseOptions 120var 121 Frame: TEditorFrame; 122 SParam: string; 123 CliModule: string; 124 CliParams: TAppStringArray; 125 NLine, NColumn, i: integer; 126 bReadOnly: boolean; 127 bAllowCreate: boolean; 128 sEncoding, sCli: string; 129 SepCli: TATStringSeparator; 130 List: TStringList; 131begin 132 bReadOnly:= false; 133 bAllowCreate:= true; 134 sEncoding:= ''; 135 136 for i:= 0 to Length(AParams)-1 do 137 begin 138 SParam:= AParams[i]; 139 if SParam='' then 140 Continue; 141 142 //remove " quotes, CudaText issue #3726 143 SParam:= SParam.DeQuotedString('"'); 144 145 if SParam='-r' then 146 begin 147 bReadOnly:= true; 148 Continue; 149 end; 150 151 if SParam='-nh' then 152 begin 153 AOpenOptions+= '/nohistory'; 154 Continue; 155 end; 156 157 if SParam='-nn' then 158 begin 159 bAllowCreate:= false; 160 Continue; 161 end; 162 163 if SBeginsWith(SParam, '-z=') then 164 begin 165 // '-z=text' must give '/view-text' 166 AOpenOptions+= '/view-'+Copy(SParam, 4, MaxInt); 167 Continue; 168 end; 169 170 if SBeginsWith(SParam, '-e=') then 171 begin 172 sEncoding:= AppEncodingShortnameToFullname( Copy(SParam, 4, MaxInt) ); 173 Continue; 174 end; 175 176 if SBeginsWith(SParam, '-p=') then 177 begin 178 SepCli.Init(Copy(SParam, 4, MaxInt), '#'); 179 SepCli.GetItemStr(CliModule); 180 SetLength(CliParams, 0); 181 while SepCli.GetItemStr(sCli) do 182 begin 183 SetLength(CliParams, Length(CliParams)+1); 184 CliParams[High(CliParams)]:= sCli; 185 end; 186 DoApplyCli(CliModule, CliParams); 187 Continue; 188 end; 189 190 {$ifdef unix} 191 if SParam='-i' then 192 begin 193 Frame:= Frames[0]; 194 if not Frame.IsEmpty then 195 Frame:= DoFileOpen('', '', nil, '/nohistory'); 196 if Assigned(Frame) then 197 begin 198 Frame.TabCaption:= '(stdin)'; 199 Frame.Ed1.Strings.LoadFromString(_GetStdin); 200 //Frame.Ed1.Modified:= false; 201 end; 202 Continue; 203 end; 204 {$endif} 205 206 (* 207 {$ifdef darwin} 208 //macOS gives param -psn** for debugger 209 if SBeginsWith(SParam, '-psn') then 210 Continue; 211 {$endif} 212 *) 213 214 //skip all other keys, to not see them as filenames 215 if SBeginsWith(SParam, '-') then 216 Continue; 217 218 SParam:= AppExpandFilename(SParam); 219 220 //here we assume that SParam is filename/dirname/filemask 221 if not IsOsFullPath(SParam) then 222 SParam:= GetCurrentDirUTF8+DirectorySeparator+SParam; 223 224 SParseFilenameWithTwoNumbers(SParam, NLine, NColumn); 225 226 //if folder, open it in ProjManager 227 if DirectoryExistsUTF8(SParam) then 228 begin 229 DoFolderOpen(SParam, False, cInvokeAppInternal); 230 end 231 else 232 if FileExists(SParam) then 233 begin 234 Frame:= DoFileOpen(SParam, '', nil, AOpenOptions); 235 if Assigned(Frame) then 236 begin 237 if sEncoding<>'' then 238 SetFrameEncoding(Frame.Ed1, sEncoding, true); 239 240 if (NLine>0) then 241 Frame.DoGotoPos(Frame.Ed1, NColumn-1, NLine-1); 242 243 if bReadOnly then 244 Frame.ReadOnly[Frame.Ed1]:= true; 245 end; 246 end 247 else 248 //file mask with '*' char? 249 if Pos('*', SParam)>0 then 250 begin 251 List:= TStringList.Create; 252 try 253 _AppFindFilesByMask(List, SParam); 254 for SParam in List do 255 begin 256 Frame:= DoFileOpen(SParam, '', nil, AOpenOptions); 257 if Assigned(Frame) then 258 begin 259 if sEncoding<>'' then 260 SetFrameEncoding(Frame.Ed1, sEncoding, true); 261 262 if bReadOnly then 263 Frame.ReadOnly[Frame.Ed1]:= true; 264 end; 265 end; 266 finally 267 FreeAndNil(List); 268 end; 269 end 270 else 271 //file not exists? suggest to create it 272 if bAllowCreate and AppFileExtentionCreatable(SParam) then 273 if MsgBox(Format(msgConfirmCreateNewFile, [SParam]), 274 MB_OKCANCEL or MB_ICONQUESTION) = ID_OK then 275 if AppCreateFile(SParam) then 276 begin 277 Frame:= DoFileOpen(SParam, '', nil, AOpenOptions); 278 if Assigned(Frame) then 279 begin 280 if sEncoding<>'' then 281 SetFrameEncoding(Frame.Ed1, sEncoding, true); 282 end; 283 end; 284 end; 285 286 //if session file was opened, we must update caption 287 UpdateCaption; 288end; 289 290 291{$ifdef windows} 292procedure TfmMain.SecondInstance(const Msg: TBytes); 293var 294 Sep: TATStringSeparator; 295 Params: array of string; 296 S: string; 297begin 298 if not IsAllowedToOpenFileNow then Exit; 299 300 SetLength(Params, 0); 301 S:= ''; 302 303 Sep.Init(UTF8Encode(TEncoding.UTF8.GetString(Msg)), '|'); 304 while Sep.GetItemStr(S) do 305 begin 306 SetLength(Params, Length(Params)+1); 307 Params[Length(Params)-1]:= S; 308 end; 309 310 DoLoadCommandParams(Params, ''); 311 312 if WindowState = wsMinimized then 313 begin 314 Application.Restore; 315 Application.ProcessMessages; 316 end; 317end; 318{$endif} 319 320 321procedure TfmMain.UniqInstanceOtherInstance(Sender: TObject; 322 ParamCount: Integer; const Parameters: array of String); 323begin 324 if not IsAllowedToOpenFileNow then exit; 325 326 DoLoadCommandParams(Parameters, ''); 327 328 if WindowState=wsMinimized then 329 begin 330 Application.Restore; 331 Application.ProcessMessages; 332 end; 333 334 {$ifdef windows} 335 // Those two calls below conflicts with Windows SwitchToThisWindow API call 336 // so they are left for other platforms 337 {$else} 338 Application.BringToFront; 339 DoFocusWindow(Handle); 340 {$ifend} 341end; 342 343procedure TfmMain.DoLoadCommandLine; 344const 345 cOptionPassive = '/passive /nonear'; 346 cOptionActive = '/nonear'; 347var 348 Params: array of string; 349 Options: string; 350 i: integer; 351begin 352 DoLoadCommandParams(FFileNamesDroppedInitially, cOptionPassive); 353 354 //if passed single file, must activate it, else not 355 if ParamCount<2 then 356 Options:= cOptionActive 357 else 358 Options:= cOptionPassive; 359 360 SetLength(Params, ParamCount); 361 for i:= 1 to Length(Params) do 362 Params[i-1]:= ParamStrUTF8(i); 363 364 DoLoadCommandParams(Params, Options); 365end; 366 367procedure TfmMain.DoLoadCommandLine_FromString(const AText: string); 368var 369 StrArray: TStringArray; 370begin 371 if Trim(AText)='' then exit; 372 StrArray:= AText.Split(' ', '"', '"', TStringSplitOptions.ExcludeEmpty); 373 DoLoadCommandParams(StrArray, ''); 374end; 375 376