Skip to content

Commit a8d4dcb

Browse files
committed
fix bug with directory search, improve dir search
1. Fix bug (introduced by previous commit) where searching the top directory only led to an uncaught error. 2. Do not trigger a directory search when opening a file in the same directory as the previously open file. 3. Require that the button to allow subdirectory search can only be checked if and only if the button to allow top directory search is also checked. 4. Always trigger a directory refresh when directory search when settings are changed.
1 parent dc5ae74 commit a8d4dcb

File tree

3 files changed

+61
-32
lines changed

3 files changed

+61
-32
lines changed

NppNavigateTo/Forms/FrmNavigateTo.cs

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,19 @@ partial class FrmNavigateTo : Form
5151

5252
public List<string> SelectedFiles { get; set; }
5353

54-
public string[] filesInCurrentDirectory { get; set; }
55-
56-
public bool shouldReloadFilesInDirectory { get; set; }
54+
public string currentDirectory { get; set; }
5755

58-
public long lastDirectoryReloadTimeTicks { get; set; }
56+
public string[] filesInCurrentDirectory { get; set; }
5957

6058
public bool isShuttingDown { get; set; }
6159

6260
public bool IsFuzzyResult { get; set; }
6361

64-
private Dictionary<string, DirectorySearchLevel> subDirSearchAllowances { get; set; }
62+
public bool shouldReloadFiles { get; set; }
63+
64+
private Dictionary<string, long> lastReloadTimes { get; set; }
65+
66+
private Dictionary<string, DirectorySearchLevel> searchLevelOverrides { get; set; }
6567

6668
/// <summary>
6769
/// if there are a lot of files in the current directory, displaying rows for them
@@ -74,11 +76,12 @@ public FrmNavigateTo(IScintillaGateway editor, INotepadPPGateway notepad)
7476
this.editor = editor;
7577
this.notepad = notepad;
7678
this.SelectedFiles = new List<string>();
79+
currentDirectory = null;
7780
filesInCurrentDirectory = null;
78-
shouldReloadFilesInDirectory = true;
79-
lastDirectoryReloadTimeTicks = 0;
81+
shouldReloadFiles = true;
8082
IsFuzzyResult = false;
81-
subDirSearchAllowances = new Dictionary<string, DirectorySearchLevel>();
83+
lastReloadTimes = new Dictionary<string, long>();
84+
searchLevelOverrides = new Dictionary<string, DirectorySearchLevel>();
8285
InitializeComponent();
8386
ReloadFileList();
8487
this.notepad.ReloadMenuItems();
@@ -94,10 +97,10 @@ private static bool MatchesAllWordsInFilter(string s, string[] words)
9497

9598
string[] SearchCurrentDirectory(DirectorySearchLevel searchLevel, long nextTimeToRefresh, string currentDirectory)
9699
{
97-
if (searchLevel == DirectorySearchLevel.None)
100+
if (searchLevel < DirectorySearchLevel.TopDirOnly)
98101
return new string[0];
99-
if (shouldReloadFilesInDirectory ||
100-
filesInCurrentDirectory == null ||
102+
string[] currentFiles = null;
103+
if (filesInCurrentDirectory == null ||
101104
DateTime.UtcNow.Ticks >= nextTimeToRefresh)
102105
{
103106
// only load the files in current directory as needed
@@ -109,7 +112,7 @@ string[] SearchCurrentDirectory(DirectorySearchLevel searchLevel, long nextTimeT
109112
? "directory tree"
110113
: "top directory";
111114
DirectorySearchLevel newSearchLevel = searchLevel;
112-
string[] currentFiles = Directory.EnumerateFiles(currentDirectory, "*.*", searchOption)
115+
currentFiles = Directory.EnumerateFiles(currentDirectory, "*.*", searchOption)
113116
.CheckWhen(
114117
x => ++fileCount >= minDirTreeSizeToWarn,
115118
() =>
@@ -139,11 +142,13 @@ string[] SearchCurrentDirectory(DirectorySearchLevel searchLevel, long nextTimeT
139142
else
140143
newSearchLevel = DirectorySearchLevel.TopDirOnlyAndDontAsk;
141144
}
145+
searchLevelOverrides[currentDirectory] = newSearchLevel;
142146
return stopIteration;
143147
}
144148
)
145149
.ToArray();
146-
subDirSearchAllowances[currentDirectory] = newSearchLevel;
150+
shouldReloadFiles = false;
151+
lastReloadTimes[currentDirectory] = DateTime.UtcNow.Ticks;
147152
if (newSearchLevel < searchLevel)
148153
{
149154
// the user didn't want to search as many files as their previous option implied
@@ -155,6 +160,7 @@ string[] SearchCurrentDirectory(DirectorySearchLevel searchLevel, long nextTimeT
155160
}
156161
return currentFiles;
157162
}
163+
// no refresh, just use old files
158164
return filesInCurrentDirectory ?? new string[0];
159165
}
160166

@@ -164,17 +170,27 @@ void FilterCurrentDirectory(Func<string, bool> filterFunc)
164170
if (string.IsNullOrWhiteSpace(currentDirectory))
165171
return;
166172
bool userWantsSearchSubdirs = FrmSettings.Settings.GetBoolSetting(Settings.searchInSubDirs);
167-
long nextTimeToRefresh = lastDirectoryReloadTimeTicks +
168-
10_000_000 * FrmSettings.Settings.GetIntSetting(Settings.secondsBetweenDirectoryScans); // 10 million ticks/sec
169-
DirectorySearchLevel searchLevel = subDirSearchAllowances.TryGetValue(currentDirectory, out var oldAllowSearch)
170-
? oldAllowSearch
171-
: userWantsSearchSubdirs
172-
? DirectorySearchLevel.RecurseSubdirs
173-
: DirectorySearchLevel.None;
173+
DirectorySearchLevel searchLevel = userWantsSearchSubdirs
174+
? DirectorySearchLevel.RecurseSubdirs
175+
: DirectorySearchLevel.TopDirOnly;
176+
long nextTimeToRefresh = 0;
177+
if (!shouldReloadFiles &&
178+
lastReloadTimes.TryGetValue(currentDirectory, out long nextRefresh))
179+
nextTimeToRefresh = nextRefresh;
180+
DirectorySearchLevel searchLevelOverride = searchLevel;
181+
if (searchLevelOverrides.TryGetValue(currentDirectory, out var searchOverride))
182+
searchLevelOverride = searchOverride;
183+
if (searchLevelOverride != searchLevel)
184+
{
185+
// if the user had previously chosen to do less searching in this directory
186+
// than the global settings, follow that local override
187+
if (searchLevel == DirectorySearchLevel.RecurseSubdirs
188+
|| (searchLevelOverride <= DirectorySearchLevel.TopDirOnlyAndDontAsk))
189+
{
190+
searchLevel = searchLevelOverride;
191+
}
192+
}
174193
filesInCurrentDirectory = SearchCurrentDirectory(searchLevel, nextTimeToRefresh, currentDirectory);
175-
searchLevel = subDirSearchAllowances[currentDirectory];
176-
shouldReloadFilesInDirectory = false;
177-
lastDirectoryReloadTimeTicks = DateTime.UtcNow.Ticks;
178194
foreach (var filePath in filesInCurrentDirectory
179195
.AsParallel().Where(filterFunc)
180196
.ToList())
@@ -221,7 +237,7 @@ public void FilterDataGrid(string filter)
221237
}
222238
else
223239
{
224-
var words = filter.Split(' ').Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();
240+
var words = filter.Split(' ').Where(x => !string.IsNullOrWhiteSpace(x)).ToHashSet().ToArray();
225241
Func<string, bool> filterFunc;
226242
if (words.Length == 0)
227243
filterFunc = x => true;
@@ -285,7 +301,7 @@ public void FilterDataGrid(string filter)
285301
private void searchInTabs(string filter)
286302
{
287303
//Normal index of search
288-
var words = filter.Split(' ').Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();
304+
var words = filter.Split(' ').Where(x => !string.IsNullOrWhiteSpace(x)).ToHashSet().ToArray();
289305
Func<string, bool> filterFunc = x => MatchesAllWordsInFilter(x, words);
290306
if (FrmSettings.Settings.GetBoolSetting(Settings.preferFilenameResults))
291307
{

NppNavigateTo/Forms/FrmSettings.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,22 @@ private void numericUpDown1_ValueChanged(object sender, EventArgs e)
9999

100100
private void checkBox1_CheckedChanged(object sender, EventArgs e)
101101
{
102+
if (Main.frmNavigateTo != null)
103+
Main.frmNavigateTo.shouldReloadFiles = true;
104+
bool isChecked = checkBoxSearchInFolder.Checked;
105+
if (!isChecked)
106+
checkBoxSearchInSubDirs.Checked = false;
102107
Settings.SetBoolSetting(Settings.searchInCurrentFolder, checkBoxSearchInFolder.Checked);
103108
}
104109

105110
private void checkBox1_CheckedChanged_1(object sender, EventArgs e)
106111
{
107-
Settings.SetBoolSetting(Settings.searchInSubDirs, checkBoxSearchInSubDirs.Checked);
112+
if (Main.frmNavigateTo != null)
113+
Main.frmNavigateTo.shouldReloadFiles = true;
114+
bool isChecked = checkBoxSearchInSubDirs.Checked;
115+
if (isChecked)
116+
checkBoxSearchInFolder.Checked = true;
117+
Settings.SetBoolSetting(Settings.searchInSubDirs, isChecked);
108118
}
109119

110120
private void buttonHighlightColor_Click(object sender, EventArgs e)

NppNavigateTo/NppNavigateTo.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ public static void OnNotification(ScNotification notification)
6565
// this makes the editor track the current instance.
6666
NavigateTo.Plugin.Namespace.Main.editor = new ScintillaGateway(PluginBase.GetCurrentScintilla());
6767
var frmNavigateTo = NavigateTo.Plugin.Namespace.Main.frmNavigateTo;
68-
if (frmNavigateTo == null || NavigateTo.Plugin.Namespace.Main.isShuttingDown)
69-
// a bunch of NPPN_BUFFERACTIVATED events fire when Notepad++ is shutting down
70-
// which will lead to this being called repeatedly
71-
return;
72-
frmNavigateTo.shouldReloadFilesInDirectory = notification.Header.Code == (uint)NppMsg.NPPN_BUFFERACTIVATED;
73-
if (!frmNavigateTo.Visible)
68+
if (frmNavigateTo == null || !frmNavigateTo.Visible
69+
|| NavigateTo.Plugin.Namespace.Main.isShuttingDown)
70+
// DO NOT reload file list if:
71+
// 1. Notepad++ is shutting down
72+
// 2. NavigateTo form doesn't exist or is not visible
7473
return;
74+
// reload the file list whenever you open a file in a different directory
75+
if (frmNavigateTo.currentDirectory == null ||
76+
frmNavigateTo.currentDirectory != NavigateTo.Plugin.Namespace.Main.notepad.GetCurrentFileDirectory())
77+
frmNavigateTo.shouldReloadFiles = true;
7578
frmNavigateTo.ReloadFileList();
7679
frmNavigateTo.FilterDataGrid("");
7780
break;

0 commit comments

Comments
 (0)