// History // 20190205 v2.0 Front end to everything.exe and es.exe // 20190205 v2.0 Replacement for $es. See https://resource.dopus.com/t/fast-search-with-everything/21974 // 20190205 v2.0 Incorporates ET, ES and CLIPTOCOL commands into a single wrapper // 20190206 v2.1 Use clipboard for ES searches in order to deal with non-ASCII results // 20190206 v2.1 because ES output redirected to a file does not handle non-ASCII file names properly // 20190207 v2.1a Revert to v2.0 base // 20190207 v2.0a Use UTF8 flag on import of text file exported by ES which us UTF8 without a BOM // 20190207 v2.0a See https://www.voidtools.com/forum/viewtopic.php?f=5&t=7473 // 20190207 v2.0a Add matchdiacritics configuration option // 20190209 v2.2 Add esplus and cliptocolplus commands to append to target // 20190221 v2.3 Fix handling of HERE button to avoid adding double backslash to root paths // 20190222 v2.4 Add config option for choice of Anywhere, Below, Here as default //-- Add string trim() method String.prototype.trim = function(s){s=s||"\\s";return this.replace(new RegExp("^("+s+"){1,}\|("+s+"){1,}$","g"),"");} //-- Global Variables var me = { name:"ets", version:"2.4 (February 22nd, 2019)", desc:"Front end to everything.exe and es.exe", copyright:"(c) 2019 Aussie", template:"", minver:"12", et:"et", es:"es", esplus:"esplus", cliptocol:"cliptocol", cliptocolplus:"cliptocolplus", cmdname:"" } var d, dbg, dlg, fsu; var colname = me.name; var colspec = "coll://"+colname; var colcmd = "/home\\dopusrt.exe /col "; var colimp = colcmd+"import /create /utf8 "; var etspec, etargs = " -newwindow -s "; var esspec, esargs = " -dm -size -full-path-and-name -sort-date-modified -export-txt "; var tmp, ForReading = 1, ForWriting = 2, ForAppending = 8; var ms = 250; // Delay in millisecs var waitcount = 12; // Max number of times to apply the delay var doprompt; function OnInit(initData) { initData.name = me.name; initData.version = me.version; initData.desc = me.desc; initData.copyright = me.copyright; initData.default_enable = true; var cmd1 = initData.AddCommand(); cmd1.name = me.et; cmd1.method = "et"; cmd1.desc = "Simple front end to everything.exe"; var cmd2 = initData.AddCommand(); cmd2.name = me.es; cmd2.method = "es"; cmd2.desc = "Create an Opus collection using ES (Everything Search) output"; var cmd3 = initData.AddCommand(); cmd3.name = me.esplus; cmd3.method = "esplus"; cmd3.desc = "Append to an Opus collection using ES (Everything Search) output"; var cmd4 = initData.AddCommand(); cmd4.name = me.cliptocol; cmd4.method = "cliptocol"; cmd4.desc = "Create an Opus collection from filespecs on the clipboard"; var cmd5 = initData.AddCommand(); cmd5.name = me.cliptocolplus; cmd5.method = "cliptocolplus"; cmd5.desc = "Append to an Opus collection from filespecs on the clipboard"; initData.config_desc = DOpus.create.map(); initData.config.dbg = false; initData.config_desc("dbg") = 'Control whether trace information is writen to "Other" log.'; initData.config.lookin = DOpus.create.vector("/programfiles\\everything","/programfilesx86\\everything"); initData.config_desc("lookin") = "Where to look for everything.exe and es.exe."; initData.config.colname = colname; initData.config_desc("colname") = 'Target collection name.'; initData.config.esprompt = true; initData.config_desc("esprompt") = 'True = prompt if no args and no qualifier, False = the reverse.'; initData.config.etprompt = false; initData.config_desc("etprompt") = 'True = prompt if no args and no qualifier, False = the reverse.'; initData.config.deflookfor = "dm:last30secs"; initData.config_desc("deflookfor") = "Default search term if none provided"; initData.config.matchdiacritics = false; initData.config_desc("matchdiacritics") = "Control exact matching of diacritical characters."; initData.config.defbutton = 1; initData.config_desc("defbutton") = "Default button number when Below (2) and Here (3) are available ."; } //-- Main command code function cliptocol(ScriptCommandData, append){ me.cmdname = (append==true) ? me.cliptocolplus : me.cliptocol; if (!commoninit(ScriptCommandData)) return; var cliptext = DOpus.getclip("text"); var a = cliptext.split(/\r\n/g); if (fsu.newpath(a[0]).drive==0){ dlg.request("No valid text found on the clipboard","OK","[cliptocol]"); return; } if (!commoninit(ScriptCommandData, me.cliptocol)) return; var fso = new ActiveXObject("Scripting.FileSystemObject"); var fil = fso.OpenTextFile(tmp,ForWriting,true); fil.WriteLine(cliptext); // Create a temp file from clipboard text (if there is any) fil.close(); if (append!=true) exec(colimp+"/clear "+maybe_quote(colname)+" "+tmp); // Replace else exec(colimp+maybe_quote(colname)+" "+tmp); // Append exec('Go "'+colspec+'" NEWTAB=findexisting'); commonterm(); } function cliptocolplus(ScriptCommandData){ cliptocol(ScriptCommandData, true); } function es(ScriptCommandData, append){ me.cmdname = (append==true) ? me.esplus : me.es; if (!commoninit(ScriptCommandData)) return; var argstring = maybeprompt(me.argstring); if (dbg) DOpus.output("es argstring = " + argstring); if (argstring=="") return; argstring = resolvealiases(argstring); argstring = argstring.replace(/\|/g,'^|'); argstring = argstring.replace(/\/g,'^>'); var cmdstr = 'cmd.exe /s /c ""'+esspec+'" '+argstring+esargs+tmp+'"'; // Build an es command exec(cmdstr,true); // Create a temp text file containing es search results if (!waitforit(tmp)) return; if (append!=true) exec(colimp+"/clear "+maybe_quote(colname)+" "+tmp); // Replace else exec(colimp+maybe_quote(colname)+" "+tmp); // Append exec('Go "'+colspec+'" NEWTAB=findexisting'); commonterm(); } function esplus(ScriptCommandData){ es(ScriptCommandData, true); } function et(ScriptCommandData){ me.cmdname = me.et; if (!commoninit(ScriptCommandData)) return; var argstring = maybeprompt(me.argstring); if (argstring=="") return; if (dbg) DOpus.output("et argstring = " + argstring); argstring = resolvealiases(argstring); // e.g. /programfiles ==> "C:\Program Files" argstring = argstring.replace(/"/g, '"""'); // e.g. ==> """C:\Program Files""" var cmdstr = 'cmd.exe /s /c ""'+etspec+'"'+etargs+' "'+argstring+'"'; exec(cmdstr,true); commonterm(); } //-- Functions called from main script code function commoninit(ScriptCommandData){ d = ScriptCommandData; dlg = d.func.dlg; fsu = DOpus.FSUtil; // Debug ? dbg = Script.config.dbg; // Who am I? if (dbg) DOpus.output(me.name+" ("+me.cmdname+") version " + me.version + " starting.."); // Check minimum version requirements if (!DOpus.version.AtLeast(me.minver)){ dlg.request(me.name+" requires DOpus version " + me.minver + " or later","OK","["+me.name+"]"); return false; } // Process args // Force a space before | to deal with (e.g.) path:/alias1|path:/alias2 me.argstring = d.cmdline.slice(me.cmdname.length).trim().replace(/\|/g,' |'); if (dbg) DOpus.output("me.argstring = "+me.argstring); if (Script.config.matchdiacritics) esargs = " -a"+esargs; // Initialise variables colname = Script.config.colname; doprompt = (me.cmdname==me.et) ? Script.config.etprompt : Script.config.esprompt; // Check for everything.exe availability etspec = findexe("everything"); if (etspec==""){ dlg.request("everything.exe not found","OK"); return false; } if (dbg) DOpus.output("etspec = " + etspec); // Make sure everything.exe is running var str = "everything.exe"; if (DOpus.Create.Sysinfo.FindProcess(str)==0) exec(etspec+" -first-instance -startup"); if (me.cmdname==me.et) return true; // No need to check for es.exe // Check for es.exe availability esspec = findexe("es"); if (esspec==""){ dlg.request("es.exe not found","OK"); return false; } if (dbg) DOpus.output("esspec = " + esspec); // Define target file for es.exe or text ex the clipboard tmp = maybe_quote(fsu.resolve("/temp\\"+colname+".out")); // Erase any existing temp file exec("Delete QUIET NORECYCLE FILE="+tmp); return true; } function commonterm(){ if (dbg) DOpus.output(me.name+" ("+me.cmdname+") version " + me.version + " exiting normally.."); } function exec(cmdstr,hide){ var cmd = DOpus.Create.Command; if (dbg) DOpus.output("cmdstr = " + cmdstr); if (hide) cmd.addline("@runmode:hide"); cmd.addline(cmdstr); cmd.run; } function findexe(name){ // Attempt to locate an executable (e.g. findexe("es") to locate es.exe) var fn = String(name).trim()+".exe"; var path = (DOpus.vars.exists("xx-"+fn)) ? DOpus.vars.get("xx-"+fn) : ""; if (fsu.exists(path+"/"+fn)) return path+"/"+fn; var lookin = (typeof Script.config.lookin =="undefined") ? DOpus.create.vector() : Script.config.lookin; for (var i = 0; i < lookin.count; i++){ path = fsu.resolve(lookin(i)); if (fsu.exists(path+"/"+fn)){ DOpus.vars.set("xx-"+fn, String(path)); DOpus.vars("xx-"+fn).persist = true; return path+"/"+fn; } } dlg.request(fn+" not found","OK","["+me.name+"]"); return ""; } function maybeprompt(str){ doprompt = (d.func.qualifiers=="none") ? doprompt : !doprompt; var promptstr = String(str).trim(); if ((doprompt==false) && (promptstr!="")) return promptstr; if (promptstr==""){ if (d.func.sourcetab.selected.count==1){ // Set default search term based on first selected item, if possible promptstr = (d.func.sourcetab.selected(0).ext=="") ? "" : ".*"; promptstr = "wfn:"+maybe_quote(d.func.sourcetab.selected(0).name_stem_m+promptstr); } else{ promptstr = Script.config.deflookfor; if (promptstr=="") promptstr = "dm:last20secs"; } } var path = String(d.func.sourcetab.path); if (dbg) DOpus.output("path = " + path); var hereok = (path.toLowerCase().indexOf("coll:")!=0); hereok = (hereok) && (path.toLowerCase().indexOf("::")!=0); hereok = (hereok) && (path.toLowerCase().indexOf("\\\\localhost")!=0); dlg.title = "["+me.cmdname+"]"; dlg.message = "Enter search term(s)"; dlg.defvalue = promptstr; dlg.max = 0; dlg.select = true; dlg.buttons = "Anywhere|"; if (hereok){ dlg.buttons = dlg.buttons+"Below|Here|"; var defbutton = Script.config.defbutton; if ((defbutton==2) || (defbutton==3)) dlg.defid = defbutton; } dlg.buttons = dlg.buttons+"Cancel"; dlg.show; if (dlg.result==0) return ""; // Force a space before | to deal with (e.g.) path:/alias1|path:/alias2 var fixstr = dlg.input.trim().replace(/\|/g,' |'); if (dlg.result==3) return fixstr+" parent:"+maybe_quote(path); if (dlg.result==2) return fixstr+" path:"+maybe_quote(path); else return fixstr; } function maybe_quote(str){ // Avoid unnecessary use of quotes and always force to string type return (String(str).indexOf(" ")<0) ? String(str) : '"'+String(str)+'"'; } function resolvealiases(str){ // Resolve alias(es) (e.g. /temp, /scripts) and always force to string type var resolved = String(str); var n = resolved.indexOf("/"); if (n<0) return resolved; var pfx = resolved.slice(0,n); var alias = resolved.slice(n); var i = alias.indexOf(" "); if (i<0) i = alias.indexOf('\\'); if (i<0) i = alias.indexOf('"'); if (i<0) var sfx = ""; else{ var sfx = alias.slice(i); alias = alias.slice(0,i); } // See https://resource.dopus.com/t/temp-alias-produces-short-form-name/31304 var path = fsu.newPath(fsu.resolve(alias)).longpath; path = pfx+path+sfx; // Keep resolving until all aliases are processed return (path==resolved) ? resolved : resolvealiases(path); } function waitforit(fn){ // Wait for a new file (fn) to be completely written var i = 0; while (i++