public static CompletionDataList GetPathCompletion(Project proj, string pattern,
                                                           FilePath fromFile,
                                                           Func <ProjectFile, string> pathFunc)
        {
            var list = new CompletionDataList();

            var regex = new Regex("^" +
                                  Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".").Replace("\\|", "$|^") + "$",
                                  RegexOptions.Compiled);

            var dir = fromFile.ParentDirectory.ToString();

            foreach (var pf in proj.Files)
            {
                string pathStr = pf.FilePath.ToString();
                if (pf.Subtype == Subtype.Directory || !pathStr.StartsWith(dir))
                {
                    continue;
                }

                int split = pathStr.LastIndexOf(System.IO.Path.DirectorySeparatorChar);
                if (split != dir.Length)
                {
                    continue;
                }

                if (regex.IsMatch(pf.FilePath.FileName.ToString()))
                {
                    list.Add(new FileCompletionData(pf, pathFunc));
                }
            }

            list.Sort();
            list.IsSorted = true;
            list.Add(new FilePickerCompletionData(proj, pattern, pathFunc));
            return(list);
        }
        public override Task <ICompletionDataList> HandleCodeCompletionAsync(CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken))
        {
            var project = (CProject)DocumentContext.Project;

            if (project == null || !project.HasLibClang)
            {
                return(Task.FromResult((ICompletionDataList)null));
            }

            return(Task.Run(() => {
                var completionChar = triggerInfo.TriggerCharacter ?? ' ';
                ICompletionDataList list = new CompletionDataList();
                if (ShouldCompleteOn(completionChar))
                {
                    unsavedFiles = project.UnsavedFiles.Get();
                    bool fieldOrMethodMode = completionChar == '.' || completionChar == '>' ? true : false;
                    IntPtr pResults = project.ClangManager.CodeComplete(completionContext, unsavedFiles.ToArray(), DocumentContext.Name);
                    if (pResults.ToInt64() != 0)
                    {
                        CXCodeCompleteResults results = Marshal.PtrToStructure <CXCodeCompleteResults> (pResults);
                        for (int i = 0; i < results.NumResults; i++)
                        {
                            IntPtr iteratingPointer = results.Results + i * Marshal.SizeOf <CXCompletionResult> ();
                            CXCompletionResult resultItem = Marshal.PtrToStructure <CXCompletionResult> (iteratingPointer);
                            foreach (var cd in GetCompletionUnits(resultItem, operatorFilter, fieldOrMethodMode))
                            {
                                list.Add(cd);
                            }
                        }
                    }
                    clang.disposeCodeCompleteResults(pResults);
                }
                previous = completionChar;
                list.Sort((x, y) => x.CompareTo(y));
                return list;
            }, token));
        }