예제 #1
0
        public static IEnumerable <DirectoryEntry> EnumerateEntries(this IDirectory directory, string searchPattern, SearchOptions searchOptions)
        {
            bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive);
            bool recurse    = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories);

            IFileSystem fs = directory.ParentFileSystem;

            foreach (DirectoryEntry entry in directory.Read())
            {
                if (MatchesPattern(searchPattern, entry.Name, ignoreCase))
                {
                    yield return(entry);
                }

                if (entry.Type != DirectoryEntryType.Directory || !recurse)
                {
                    continue;
                }

                IDirectory subDir = fs.OpenDirectory(directory.FullPath + '/' + entry.Name, OpenDirectoryMode.All);

                foreach (DirectoryEntry subEntry in subDir.EnumerateEntries(searchPattern, searchOptions))
                {
                    yield return(subEntry);
                }
            }
        }
예제 #2
0
        private static Regex BuildExpression(string term, bool searchPrevious, SearchOptions searchOptions)
        {
            var regexOptions = RegexOptions.Compiled | RegexOptions.Singleline;

            if (!searchOptions.HasFlag(SearchOptions.MatchCase))
            {
                regexOptions |= RegexOptions.IgnoreCase;
            }

            if (!searchOptions.HasFlag(SearchOptions.Regex))
            {
                if (searchOptions.HasFlag(SearchOptions.Extended))
                {
                    term = TransformExtended(term);
                }

                term = Regex.Escape(term);
            }

            if (searchOptions.HasFlag(SearchOptions.WholeWord))
            {
                term = "\\b" + term + "\\b";
            }
            else if (searchOptions.HasFlag(SearchOptions.WordStart))
            {
                term = "\\b" + term;
            }

            term = searchPrevious ? $".*({term})" : $"({term})";

            return(new Regex(term, regexOptions));
        }
예제 #3
0
        public static IEnumerable <DirectoryEntry> EnumerateEntries(this FileSystemManager fs, string path, string searchPattern, SearchOptions searchOptions)
        {
            bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive);
            bool recurse    = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories);

            using (DirectoryHandle sourceHandle = fs.OpenDirectory(path, OpenDirectoryMode.All))
            {
                foreach (DirectoryEntry entry in fs.ReadDirectory(sourceHandle))
                {
                    if (PathTools.MatchesPattern(searchPattern, entry.Name, ignoreCase))
                    {
                        yield return(entry);
                    }

                    if (entry.Type != DirectoryEntryType.Directory || !recurse)
                    {
                        continue;
                    }

                    string subPath = PathTools.Normalize(PathTools.Combine(path, entry.Name));

                    IEnumerable <DirectoryEntry> subEntries = fs.EnumerateEntries(subPath, searchPattern, searchOptions);

                    foreach (DirectoryEntry subEntry in subEntries)
                    {
                        subEntry.FullPath = PathTools.Combine(path, subEntry.Name);
                        yield return(subEntry);
                    }
                }
            }
        }
예제 #4
0
        public static IEnumerable <DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path, string searchPattern, SearchOptions searchOptions)
        {
            bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive);
            bool recurse    = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories);

            fs.OpenDirectory(out DirectoryHandle sourceHandle, path.ToU8Span(), OpenDirectoryMode.All).ThrowIfFailure();

            try
            {
                while (true)
                {
                    DirectoryEntry dirEntry = default;

                    fs.ReadDirectory(out long entriesRead, SpanHelpers.AsSpan(ref dirEntry), sourceHandle);
                    if (entriesRead == 0)
                    {
                        break;
                    }

                    DirectoryEntryEx entry = FileSystemExtensions.GetDirectoryEntryEx(ref dirEntry, path);

                    if (PathTools.MatchesPattern(searchPattern, entry.Name, ignoreCase))
                    {
                        yield return(entry);
                    }

                    if (entry.Type != DirectoryEntryType.Directory || !recurse)
                    {
                        continue;
                    }

                    IEnumerable <DirectoryEntryEx> subEntries =
                        fs.EnumerateEntries(PathTools.Combine(path, entry.Name), searchPattern, searchOptions);

                    foreach (DirectoryEntryEx subEntry in subEntries)
                    {
                        yield return(subEntry);
                    }
                }
            }
            finally
            {
                if (sourceHandle.IsValid)
                {
                    fs.CloseDirectory(sourceHandle);
                }
            }
        }
예제 #5
0
        public void Find(string term, bool findPrevious, SearchOptions searchOptions)
        {
            if (Model.Document == null)
            {
                return;
            }
            var document        = Model.Document;
            var nothingSelected = document.Editor.SelectionStart == document.Editor.SelectionEnd;
            var offset          = findPrevious
                ? 0                                   // find from begin of file
                : nothingSelected                     // nothing selected
                    ? document.Editor.CurrentPosition // start from current position
                    : Math.Max(0, Math.Max(document.Editor.SelectionStart, document.Editor.SelectionEnd) + 1);
            var length = findPrevious
                ? nothingSelected
                    ? document.Editor.CurrentPosition
                    : Math.Min(document.Editor.SelectionStart, document.Editor.SelectionEnd) - 1
                : document.Editor.TextLength;

            if (searchOptions.HasFlag(SearchOptions.Retry))
            {
                offset = 0;
                length = document.Editor.TextLength;
            }

            FindAll(document.FullPath, offset, length, term, findPrevious, searchOptions, result =>
            {
                var firstResult = result.FirstOrDefault();
                if (firstResult == null)
                {
                    if (offset > 0 && !findPrevious && !searchOptions.HasFlag(SearchOptions.Retry))
                    {
                        Find(term, false, searchOptions | SearchOptions.Retry);
                    }
                    else
                    {
                        MessageBox.Show("Not found");
                    }
                }
                else
                {
                    document.Editor.GotoPosition(firstResult.Position);
                    document.Editor.SetSelection(firstResult.Position, firstResult.EndPosition);
                }
            });
        }
예제 #6
0
        public void SearchOptions_WhenSearchWithinSecondaryPhoneIsTrue_ReturnSearchOptionsWithFlagForSecondaryPhone()
        {
            const bool searchWithinSecondaryPhone  = true;
            IGetMatchingContactCollectionQuery sut = CreateSut(searchWithinSecondaryPhone: searchWithinSecondaryPhone);

            SearchOptions result = sut.SearchOptions;

            Assert.That(result.HasFlag(SearchOptions.SecondaryPhone), Is.True);
        }
예제 #7
0
        public void SearchOptions_WhenSearchWithinPrimaryPhoneIsFalse_ReturnSearchOptionsWithoutFlagForPrimaryPhone()
        {
            const bool searchWithinPrimaryPhone    = false;
            IGetMatchingContactCollectionQuery sut = CreateSut(searchWithinPrimaryPhone: searchWithinPrimaryPhone);

            SearchOptions result = sut.SearchOptions;

            Assert.That(result.HasFlag(SearchOptions.PrimaryPhone), Is.False);
        }
예제 #8
0
        public void SearchOptions_WhenSearchWithinMailAddressIsFalse_ReturnSearchOptionsWithoutFlagForMailAddress()
        {
            const bool searchWithinMailAddress     = false;
            IGetMatchingContactCollectionQuery sut = CreateSut(searchWithinMailAddress: searchWithinMailAddress);

            SearchOptions result = sut.SearchOptions;

            Assert.That(result.HasFlag(SearchOptions.MailAddress), Is.False);
        }
예제 #9
0
        public static EntityInfo[] Search(string text, SearchOptions options, EntityType?type = null)
        {
            Common.InitializeDB();

            List <EntityInfo> ret = new List <EntityInfo>();


            if (options.HasFlag(SearchOptions.Offline))
            {
                SearchOffline(ret, text, options.HasFlag(SearchOptions.ExactMatch), type);
            }
            if (options.HasFlag(SearchOptions.Online))
            {
                SearchOnline(ret, text, options.HasFlag(SearchOptions.ExactMatch), type);
            }

            return(ret.ToArray());
        }
예제 #10
0
        public static IEnumerable <DirectoryEntryEx> EnumerateEntries(this IFileSystem fileSystem, string path, string searchPattern, SearchOptions searchOptions)
        {
            bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive);
            bool recurse    = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories);

            IFileSystem fs = fileSystem;

            fileSystem.OpenDirectory(out IDirectory directory, path.ToU8Span(), OpenDirectoryMode.All).ThrowIfFailure();

            while (true)
            {
                DirectoryEntry dirEntry = default;

                directory.Read(out long entriesRead, SpanHelpers.AsSpan(ref dirEntry)).ThrowIfFailure();
                if (entriesRead == 0)
                {
                    break;
                }

                DirectoryEntryEx entry = GetDirectoryEntryEx(ref dirEntry, path);

                if (PathTools.MatchesPattern(searchPattern, entry.Name, ignoreCase))
                {
                    yield return(entry);
                }

                if (entry.Type != DirectoryEntryType.Directory || !recurse)
                {
                    continue;
                }

                IEnumerable <DirectoryEntryEx> subEntries =
                    fs.EnumerateEntries(PathTools.Combine(path, entry.Name), searchPattern,
                                        searchOptions);

                foreach (DirectoryEntryEx subEntry in subEntries)
                {
                    yield return(subEntry);
                }
            }
        }
예제 #11
0
        public static async Task <EntityInfo[]> Search(string text, SearchOptions options, CancellationToken cancellation_token, EntityType?type = null)
        {
            await Common.InitializeDBAsync();

            List <EntityInfo> ret = new List <EntityInfo>();

            try
            {
                if (options.HasFlag(SearchOptions.Offline))
                {
                    await SearchOffline(ret, text, options.HasFlag(SearchOptions.ExactMatch), cancellation_token, type);
                }
                if (options.HasFlag(SearchOptions.Online))
                {
                    await SearchOnline(ret, text, options.HasFlag(SearchOptions.ExactMatch), type);
                }

                return(ret.ToArray());
            }
            catch (OperationCanceledException)
            {
                return(null);
            }
        }
예제 #12
0
        public void FindAll(string fullPath, int offset, int length, string term, bool previous, SearchOptions searchOptions, Action <IEnumerable <AData.Location> > action)
        {
            var fileId = FileId(fullPath);

            void Ready(Document document)
            {
                if (offset == -1)
                {
                    offset = document.Editor.CurrentPosition;
                }

                if (length == -1)
                {
                    length = document.Editor.TextLength;
                }

                IEnumerable <Match> CollectMatches()
                {
                    var regex = BuildExpression(term, previous, searchOptions);
                    var match = regex.Match(document.Editor.GetTextRange(offset, length));

                    if (previous)
                    {
                        while (match.Success)
                        {
                            yield return(match);

                            var lastPosition = Math.Min(document.Editor.SelectionEnd, document.Editor.SelectionStart);

                            match = regex.Match(document.Editor.GetTextRange(offset, lastPosition - offset));
                        }
                    }
                    else
                    {
                        while (match.Success)
                        {
                            yield return(match);

                            match = match.NextMatch();
                        }
                    }
                }

                action(
                    CollectMatches()
                    .Select(x =>
                {
                    var group          = x.Groups[1];
                    var previewExpand  = 10;
                    var position       = offset + group.Index;
                    var line           = document.Editor.Lines[document.Editor.LineFromPosition(position)];
                    var column         = position - line.Position;
                    var startOfPreview = Math.Max(0, column - previewExpand);
                    var endOfPreview   = Math.Min(line.Length - 1, column + group.Length + previewExpand);
                    var previewText    = line.Text.Substring(startOfPreview, endOfPreview - startOfPreview).Trim('\r', '\n');

                    if (startOfPreview > 0)
                    {
                        previewText = "..." + previewText;
                    }

                    if (endOfPreview < line.Length - 1)
                    {
                        previewText += "...";
                    }

                    if (searchOptions.HasFlag(SearchOptions.Highlight))
                    {
                        document.Editor.IndicatorFillRange(position, group.Length);
                    }

                    return(new AData.Location(fileId, position)
                    {
                        TextLength = group.Length,
                        EndPosition = position + group.Length,
                        Line = line.Index,
                        Column = column,
                        // extract preview text and remove all new line chars
                        PreviewText = previewText
                    });
                }));
            }

            // load document from cache
            if (Model.Documents.TryGetValue(fullPath, out Document d))
            {
                Ready(d);
            }
            else
            {
                // load from file
                LoadDocument(fullPath).Ready.Then(x => Ready(x));
            }
        }
예제 #13
0
            void MatchAll(bool replace = false)
            {
                var searcher = new FileSearchManagement(this);

                if (SearchOptions.HasFlag(SearchFlags.Upward))
                {
                    searcher.SearchOptions ^= SearchFlags.Upward; // "Search upward" isn't necessary in bulk mode, and could cause subtle bugs.
                }
                searcher.ResetSearch(false);

                var    matches  = new LinkedList <SearchResult>();
                string haystack = null;

                while ((haystack = searcher.NextMatch(haystack)) != null)
                {
                    if (replace)
                    {
                        var ed = WorkbenchLogic.Instance.OpenFile(searcher.currentFile, searcher.currentOffset) as EditorDocument;
                        ed.Editor.Document.Replace(searcher.currentOffset, TranslatedSearchStr.Length, TranslatedReplaceStr);
                        haystack = ed.Editor.Document.Text;
                    }

                    int lineEnd = 0;
                    int line    = 0;
                    int column  = 0;
                    while (lineEnd < haystack.Length)
                    {
                        if (haystack[lineEnd] == '\n')
                        {
                            ++line;

                            if (lineEnd >= searcher.currentOffset)
                            {
                                break;
                            }

                            column = 0;
                        }

                        ++lineEnd;
                        ++column;
                    }
                    int    lineStart = lineEnd - column;
                    string context   = haystack.Substring(lineStart, column).Trim();
                    column = searcher.currentOffset - lineStart;

                    matches.AddLast(new SearchResult
                    {
                        File        = searcher.currentFile,
                        Offset      = searcher.currentOffset,
                        Line        = line,
                        Column      = column,
                        CodeSnippet = context
                    });
                }

                var pan = IDEManager.Instance.MainWindow.SearchResultPanel;

                pan.SearchString = replace? TranslatedReplaceStr : TranslatedSearchStr;
                pan.Results      = matches;
                pan.Show();
            }
예제 #14
0
            string NextMatch(string haystack = null)
            {
                if (currentFile == null)
                {
                    haystack = null;
                    if (!NextFile())
                    {
                        return(null);
                    }
                }

                while (currentFile != null)
                {
                    if (haystack == null)
                    {
                        // Use the working copy if the file is already open.
                        foreach (var ed in IDEManager.Instance.Editors)
                        {
                            if (!ed.AbsoluteFilePath.Equals(currentFile))
                            {
                                continue;
                            }

                            haystack = (ed as EditorDocument).Editor.Text;
                        }
                        // Otherwise load the file from disk.
                        if (haystack == null)
                        {
                            if (!File.Exists(currentFile))
                            {
                                continue; // Nothing to see here; try the next file.
                            }
                            haystack = File.ReadAllText(currentFile);
                        }
                    }

Search:
                    StringComparison compMode = SearchOptions.HasFlag(SearchFlags.CaseSensitive) ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase;
                    int  matchX = -1;
                    bool found;
                    if (SearchOptions.HasFlag(SearchFlags.Upward))
                    {
                        if (currentOffset == -1)
                        {
                            currentOffset = haystack.Length;
                        }
                        currentOffset--;
                        if (currentOffset >= 0)
                        {
                            matchX = haystack.LastIndexOf(TranslatedSearchStr, currentOffset, compMode);
                        }

                        found = (matchX != -1 && matchX > stopOffset);
                    }
                    else
                    {
                        currentOffset++;
                        if (currentOffset < haystack.Length)
                        {
                            matchX = haystack.IndexOf(TranslatedSearchStr, currentOffset, compMode);
                        }

                        found = (matchX != -1 && (stopOffset == -1 || matchX < stopOffset));
                    }

                    if (found)
                    {
                        currentOffset = matchX;
                        if (SearchOptions.HasFlag(SearchFlags.FullWord))
                        {
                            if ((currentOffset > 0 && IsIdentifierChar(haystack[currentOffset - 1])) ||
                                (currentOffset < (haystack.Length - 1) && IsIdentifierChar(haystack[currentOffset + 1])))
                            {
                                goto Search;
                            }
                        }

                        somethingFound = true;
                        return(haystack);
                    }

                    if (startOffset != -1 && SearchOptions.HasFlag(SearchFlags.Wrap))
                    {
                        stopOffset    = startOffset;
                        currentOffset = -1;
                        startOffset   = -1;
                        goto Search;
                    }

                    if (!NextFile())
                    {
                        return(null);
                    }
                    haystack = null;
                }

                return(null);
            }