Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 0e12072

Browse files
committed
Merge pull request #5477 from cosmosgenius/5237-findinfiles-noresult
Fix for issue #5237 - Find in Files - No response for no result found
2 parents 20a234a + f044910 commit 0e12072

File tree

1 file changed

+158
-125
lines changed

1 file changed

+158
-125
lines changed

src/search/FindInFiles.js

Lines changed: 158 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,20 @@ define(function (require, exports, module) {
106106
$searchContent,
107107
$selectedRow;
108108

109-
109+
/** @type {FindInFilesDialog} dialog having the modalbar for search */
110+
var dialog = null;
111+
110112
/**
111113
* @private
112114
* Returns a regular expression from the given query and shows an error in the modal-bar if it was invalid
113115
* @param {string} query The query from the modal-bar input
114116
* @return {RegExp}
115117
*/
116118
function _getQueryRegExp(query) {
119+
if (!query) {
120+
return null;
121+
}
122+
117123
// Clear any pending RegEx error message
118124
$(".modal-bar .message").css("display", "inline-block");
119125
$(".modal-bar .error").css("display", "none");
@@ -162,83 +168,7 @@ define(function (require, exports, module) {
162168
return Strings.FIND_IN_FILES_NO_SCOPE;
163169
}
164170
}
165-
166-
167-
// This dialog class was mostly copied from QuickOpen. We should have a common dialog
168-
// class that everyone can use.
169-
170-
/**
171-
* FindInFilesDialog class
172-
* @constructor
173-
*/
174-
function FindInFilesDialog() {
175-
this.closed = false;
176-
this.result = null; // $.Deferred
177-
}
178171

179-
/**
180-
* Closes the search dialog and resolves the promise that showDialog returned
181-
*/
182-
FindInFilesDialog.prototype._close = function (value) {
183-
if (this.closed) {
184-
return;
185-
}
186-
187-
this.closed = true;
188-
this.modalBar.close();
189-
EditorManager.focusEditor();
190-
this.result.resolve(value);
191-
};
192-
193-
/**
194-
* Shows the search dialog
195-
* @param {string=} initialString Default text to prepopulate the search field with
196-
* @param {Entry=} scope Search scope, or null to search whole project
197-
* @returns {$.Promise} that is resolved with the string to search for
198-
*/
199-
FindInFilesDialog.prototype.showDialog = function (initialString, scope) {
200-
// Note the prefix label is a simple "Find:" - the "in ..." part comes after the text field
201-
var templateVars = {
202-
value: initialString || "",
203-
label: _labelForScope(scope)
204-
},
205-
dialogHTML = Mustache.render(searchDialogTemplate, $.extend(templateVars, Strings)),
206-
that = this;
207-
208-
this.result = new $.Deferred();
209-
this.modalBar = new ModalBar(dialogHTML, false);
210-
var $searchField = $("input#searchInput");
211-
212-
$searchField.get(0).select();
213-
$searchField
214-
.bind("keydown", function (event) {
215-
if (event.keyCode === KeyEvent.DOM_VK_RETURN || event.keyCode === KeyEvent.DOM_VK_ESCAPE) { // Enter/Return key or Esc key
216-
event.stopPropagation();
217-
event.preventDefault();
218-
219-
var query = $searchField.val();
220-
221-
if (event.keyCode === KeyEvent.DOM_VK_ESCAPE) {
222-
query = null;
223-
}
224-
225-
that._close(query);
226-
}
227-
})
228-
.bind("input", function (event) {
229-
// Check the query expression on every input event. This way the user is alerted
230-
// to any RegEx syntax errors immediately.
231-
_getQueryRegExp($searchField.val());
232-
})
233-
.blur(function () {
234-
that._close(null);
235-
})
236-
.focus();
237-
238-
return this.result.promise();
239-
};
240-
241-
242172
/**
243173
* @private
244174
* Hides the Search Results Panel
@@ -541,9 +471,23 @@ define(function (require, exports, module) {
541471
$selectedRow = null;
542472
}
543473
searchResultsPanel.show();
544-
474+
475+
if (dialog) {
476+
dialog._close();
477+
dialog = null;
478+
}
545479
} else {
480+
546481
_hideSearchResults();
482+
483+
if (dialog) {
484+
dialog.getDialogTextField().addClass("no-results")
485+
.removeAttr("disabled")
486+
.get(0).select();
487+
488+
$(".modal-bar .message").css("display", "none");
489+
$(".modal-bar .error").css("display", "inline-block").html(Strings.FIND_NO_RESULTS);
490+
}
547491
}
548492
}
549493

@@ -706,8 +650,141 @@ define(function (require, exports, module) {
706650
}
707651
}
708652

653+
/**
654+
* @private
655+
* Executes the Find in Files search inside the 'currentScope'
656+
* @param {string} query String to be searched
657+
*/
658+
function _doSearch(query) {
659+
currentQuery = query;
660+
currentQueryExpr = _getQueryRegExp(query);
661+
662+
if (!currentQueryExpr) {
663+
StatusBar.hideBusyIndicator();
664+
dialog._close();
665+
dialog = null;
666+
return;
667+
}
668+
FileIndexManager.getFileInfoList("all")
669+
.done(function (fileListResult) {
670+
Async.doInParallel(fileListResult, function (fileInfo) {
671+
var result = new $.Deferred();
672+
673+
if (!_inScope(fileInfo, currentScope)) {
674+
result.resolve();
675+
} else {
676+
// Search one file
677+
DocumentManager.getDocumentForPath(fileInfo.fullPath)
678+
.done(function (doc) {
679+
_addSearchMatches(fileInfo.fullPath, doc.getText(), currentQueryExpr);
680+
result.resolve();
681+
})
682+
.fail(function (error) {
683+
// Error reading this file. This is most likely because the file isn't a text file.
684+
// Resolve here so we move on to the next file.
685+
result.resolve();
686+
});
687+
}
688+
return result.promise();
689+
})
690+
.done(function () {
691+
// Done searching all files: show results
692+
_showSearchResults();
693+
StatusBar.hideBusyIndicator();
694+
$(DocumentModule).on("documentChange.findInFiles", _documentChangeHandler);
695+
})
696+
.fail(function () {
697+
console.log("find in files failed.");
698+
StatusBar.hideBusyIndicator();
699+
});
700+
});
701+
}
702+
703+
704+
// This dialog class was mostly copied from QuickOpen. We should have a common dialog
705+
// class that everyone can use.
706+
707+
/**
708+
* FindInFilesDialog class
709+
* @constructor
710+
*/
711+
function FindInFilesDialog() {
712+
this.closed = false;
713+
}
714+
715+
/**
716+
* Returns the input text field of the modalbar in the dialog
717+
* @return jQuery Object pointing to input text field
718+
*/
719+
FindInFilesDialog.prototype.getDialogTextField = function () {
720+
return $("input[type='text']", this.modalBar.getRoot());
721+
};
709722

710723

724+
/**
725+
* Closes the search dialog and resolves the promise that showDialog returned
726+
*/
727+
FindInFilesDialog.prototype._close = function (value) {
728+
if (this.closed) {
729+
return;
730+
}
731+
732+
this.closed = true;
733+
this.modalBar.close();
734+
EditorManager.focusEditor();
735+
};
736+
737+
/**
738+
* Shows the search dialog
739+
* @param {string=} initialString Default text to prepopulate the search field with
740+
* @param {Entry=} scope Search scope, or null to search whole project
741+
* @returns {$.Promise} that is resolved with the string to search for
742+
*/
743+
FindInFilesDialog.prototype.showDialog = function (initialString, scope) {
744+
// Note the prefix label is a simple "Find:" - the "in ..." part comes after the text field
745+
var templateVars = {
746+
value: initialString || "",
747+
label: _labelForScope(scope)
748+
},
749+
dialogHTML = Mustache.render(searchDialogTemplate, $.extend(templateVars, Strings)),
750+
that = this;
751+
752+
this.modalBar = new ModalBar(dialogHTML, false);
753+
var $searchField = $("input#searchInput");
754+
755+
$searchField.get(0).select();
756+
$searchField
757+
.bind("keydown", function (event) {
758+
if (event.keyCode === KeyEvent.DOM_VK_RETURN || event.keyCode === KeyEvent.DOM_VK_ESCAPE) { // Enter/Return key or Esc key
759+
event.stopPropagation();
760+
event.preventDefault();
761+
762+
var query = $searchField.val();
763+
764+
if (event.keyCode === KeyEvent.DOM_VK_ESCAPE) {
765+
that._close(null);
766+
} else if (event.keyCode === KeyEvent.DOM_VK_RETURN) {
767+
StatusBar.showBusyIndicator(true);
768+
that.getDialogTextField().attr("disabled", "disabled");
769+
_doSearch(query);
770+
}
771+
}
772+
})
773+
.bind("input", function (event) {
774+
// Check the query expression on every input event. This way the user is alerted
775+
// to any RegEx syntax errors immediately.
776+
_getQueryRegExp($searchField.val());
777+
that.getDialogTextField().removeClass("no-results");
778+
})
779+
.blur(function () {
780+
if (that.getDialogTextField().attr("disabled")) {
781+
return;
782+
}
783+
that._close(null);
784+
})
785+
.focus();
786+
};
787+
711788
/**
712789
* @private
713790
* Displays a non-modal embedded dialog above the code mirror editor that allows the user to do
@@ -724,61 +801,17 @@ define(function (require, exports, module) {
724801

725802
// Default to searching for the current selection
726803
var currentEditor = EditorManager.getActiveEditor(),
727-
initialString = currentEditor && currentEditor.getSelectedText(),
728-
dialog = new FindInFilesDialog();
804+
initialString = currentEditor && currentEditor.getSelectedText();
729805

806+
dialog = new FindInFilesDialog();
730807
searchResults = {};
731808
currentStart = 0;
732809
currentQuery = "";
733810
currentQueryExpr = null;
734811
currentScope = scope;
735812
maxHitsFoundInFile = false;
736813

737-
dialog.showDialog(initialString, scope)
738-
.done(function (query) {
739-
if (query) {
740-
currentQuery = query;
741-
currentQueryExpr = _getQueryRegExp(query);
742-
743-
if (!currentQueryExpr) {
744-
return;
745-
}
746-
StatusBar.showBusyIndicator(true);
747-
FileIndexManager.getFileInfoList("all")
748-
.done(function (fileListResult) {
749-
Async.doInParallel(fileListResult, function (fileInfo) {
750-
var result = new $.Deferred();
751-
752-
if (!_inScope(fileInfo, scope)) {
753-
result.resolve();
754-
} else {
755-
// Search one file
756-
DocumentManager.getDocumentForPath(fileInfo.fullPath)
757-
.done(function (doc) {
758-
_addSearchMatches(fileInfo.fullPath, doc.getText(), currentQueryExpr);
759-
result.resolve();
760-
})
761-
.fail(function (error) {
762-
// Error reading this file. This is most likely because the file isn't a text file.
763-
// Resolve here so we move on to the next file.
764-
result.resolve();
765-
});
766-
}
767-
return result.promise();
768-
})
769-
.done(function () {
770-
// Done searching all files: show results
771-
_showSearchResults();
772-
StatusBar.hideBusyIndicator();
773-
$(DocumentModule).on("documentChange.findInFiles", _documentChangeHandler);
774-
})
775-
.fail(function () {
776-
console.log("find in files failed.");
777-
StatusBar.hideBusyIndicator();
778-
});
779-
});
780-
}
781-
});
814+
dialog.showDialog(initialString, scope);
782815
}
783816

784817
/**

0 commit comments

Comments
 (0)