Quickly search in files

Hi there,

is there a way to quickly search file contents without having to use the find panel? I. e. a custom search box in the toolbar, which searches the content of all files the current folder for the specified expression.

Thanks,
W@ng

The search field (top-right by default) does just that, via Windows Search. Unless told otherwise, it will search both names and contents.

Thanks, Leo.

But only if the location is indexed and if the extensions are registered for the search handler, as far as I know. DOpus search panel on the other hand can search all files, independent of the file type and independent if it is indexed or not.

Is there a way to achieve that?

Add a button/hotkey which runs Find * IN {sourcepath} CONTAINING {dlgstring|Enter search string}.

1 Like

Jon's button above may be more what you want, but note that Windows Search can also search the contents of non-indexed files (it's just slower if they aren't indexed).

I think the search field in Explorer defaults to not searching non-indexed contents unless explicitly told to, while the one in Opus always searches contents unless explicitly told not to. (The difference is really because Microsoft did not document the way to do what Explorer does, but in this case it's probably something you want.)

What happens when the search field is used is largely down to Windows Search, however (we just pass it the search string, then get back the results), so it could change with different Windows versions. Best to do a test to make sure it behaves as you want, if you're thinking of using the search field.

Jon's command, on the other hand, only uses internal Opus functionality, so it will always behave predictably and may be preferable.

Thanks Jon and Leo,

the button Jon recommended does the job perfectly.

W@ng

...one more thing: If I use the search field in Opus and search file contents for a string (in this case "write-log"), nothing is displayed while with the same search string the Explorer finds a couple of files (see image).

Did I forget to set an option in Opus?


Thanks,
W@ng

Jon... I created this button but if I try to cancel the search, Opus doesn't respond when I click "Abort". Had to kill with Task Manager.


I'm not sure what's going on there. We pass the query string to Windows Search, then display the results it gives back, and the rest is pretty much up to it.

Looking at the files and where they contain the search term might reveal a detail that explains things.

See if it only happens when searching particular files or types of files. It could be that a 3rd party search filter is being called for them, and it is taking forever to return (possibly stuck in a loop) which would block the operation from finishing or being stopped.

I do not have any 3rd party search filter that I know of. I have tried various folder content with the same results. I did notice that I can exit Opus and after about 5-7 seconds the window will close. Just something to ponder... not really a major problem I guess.

Sorry to bring up this old topic again. I'm still working with Jon's button but I would like to slightly modify it. Currently, the button searches all files within {sourcepath} for contents I enter in the dialog box. How do I have to modify the button so that only files currently displayed in the folder are searched? So I could quickly add a FAYT filter to the current folder, hit the button and search the content of all files displayed with the filter set.

Thanks,
W@ng

This seems to work, at least with simple wildcards used for the filename filter, and partial matching enabled for the filter bar (results may be inconsistent if it is disabled):

function OnClick(clickData)
{
	var cmd = clickData.func.command;
	cmd.deselect = false;

	var pattern = "*";
	var regex = false;

	var qf = clickData.func.sourcetab.quickfilter;
	if (!qf.disable && qf.filter != "")
	{
		pattern = qf.filter;
		regex = qf.regex;
	}

	if (regex)
	{
		dlg.Request('Cannot currently be used in regex mode.', 'OK', 'Search file content');
		return;
	}

	var dlg = clickData.func.Dlg();
	var containing = dlg.GetString('Enter search string:', '', 0, 'OK|Cancel', 'Search file content');
	if (typeof containing != "string" || containing == "") return;

	if (containing.indexOf('"') != -1)
	{
		dlg.Request('Search string cannot include double-quotes (").', 'OK', 'Search file content');
		return;
	}

	var cmdLine = 'Find NAME="' + (regex?'regex:':'') + pattern + '" IN="'
		+ clickData.func.sourcetab.path + '" CONTAINING="' + containing + '"';

	DOpus.Output(cmdLine);
	cmd.RunCommand(cmdLine);
}

Script above edited slightly to block being used when the filterbar is in regex mode, as the Find command NAME argument only allows regex when doing a duplicate find (at least at the moment -- Edit: That will work in 12.10, after which the check can be removed from the script).

One again: Perfect! Thanks a lot, Leo.

One last thing: Can I modify Jon's command (Find * IN {sourcepath} CONTAINING {dlgstring|Enter search string}) so that it searches in selected files only? I tried to replace {sourcepath} with {allfiles} but somehow this doesn't make sense I guess. The dialog pops up for every selected file then.

Thanks,
W@ng

There isn't currently an easy way to feed the Find tool a list of files (rather than folders) to search. You'd need to build a filter for that, which scripts can't currently do (although it's planned for one day). (A script could build a filter by generating the XML config file, I guess, but I don't think that's a great idea for this type of thing.)

A script could do the search itself, opening the files and looking inside them itself instead of running the Find command, but that would completely change the script and be a lot more work.

Edit: Jon had the idea that it could also be done by adding the files to a collection and then searching within that using the Find command.

Thanks Leo, no problem. The script you gave me does the job quite well. By the way: Is it planned to support powershell as scritping language? Or is that out of scope?

I don't think PowerShell is suited to the kind of things Opus uses scripting for. It's not really a replacement for JavaScript (or VBScript); it's something else, at least as I understand it.

Updated script that supports the filter being in regular expressions mode, or having partial matching turned off.

This requires Opus 12.9.2 beta or above.

function OnClick(clickData)
{
	var cmd = clickData.func.command;
	cmd.deselect = false;

	var pattern = "*";
	var regex = false;
	var partial = false;

	var qf = clickData.func.sourcetab.quickfilter;
	if (!qf.disable && qf.filter != "")
	{
		pattern = qf.filter;
		regex = qf.regex;
		partial = qf.partial;
	}

	var minVer = "12.9.2";
	if ((regex || !partial) && !DOpus.version.AtLeast(minVer))
	{
		dlg.Request("Opus " + minVer + " or above is required.", "OK", "Search file content");
		return;
	}

	var dlg = clickData.func.Dlg();
	var containing = dlg.GetString('Enter search string:', '', 0, 'OK|Cancel', 'Search file content');
	if (typeof containing != "string" || containing == "") return;

	if (containing.indexOf('"') != -1)
	{
		dlg.Request('Search string cannot include double-quotes (").', 'OK', 'Search file content');
		return;
	}

	var cmdLine = 'Find NAME="' + (regex?'regex:':'') + pattern + '" '
		+ (partial?'':'NOPARTIAL ')
		+ 'IN="' + clickData.func.sourcetab.path
		+ '" CONTAINING="' + containing + '"';

	cmd.RunCommand(cmdLine);
}
1 Like

Thanks for the script. It was useful for me to find a specific resolution template for my AIDA64 external sensor panel.