diff --git a/.gitignore b/.gitignore index 70aa86c..e69de29 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +0,0 @@ -*.meta diff --git a/Editor.meta b/Editor.meta new file mode 100644 index 0000000..bb5b1d7 --- /dev/null +++ b/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b9b0b14c91b041c4da81d8752603d9d0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/FindReferencesInProject2.cs b/Editor/FindReferencesInProject2.cs similarity index 78% rename from FindReferencesInProject2.cs rename to Editor/FindReferencesInProject2.cs index df5e5a3..94f8597 100644 --- a/FindReferencesInProject2.cs +++ b/Editor/FindReferencesInProject2.cs @@ -1,143 +1,172 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Threading; -using UnityEditor; -using UnityEngine; - -public static class FindReferencesInProject2 -{ - private const string MenuItemName = "Assets/Find References In Project %#&f"; - private const string MetaExtension = ".meta"; - - [MenuItem(MenuItemName, false, 25)] - public static void Find() - { - bool isMacOS = Application.platform == RuntimePlatform.OSXEditor; - int totalWaitMilliseconds = isMacOS ? 2 * 1000 : 300 * 1000; - int cpuCount = Environment.ProcessorCount; - string appDataPath = Application.dataPath; - - var selectedObject = Selection.activeObject; - string selectedAssetPath = AssetDatabase.GetAssetPath(selectedObject); - string selectedAssetGUID = AssetDatabase.AssetPathToGUID(selectedAssetPath); - string selectedAssetMetaPath = selectedAssetPath + MetaExtension; - - var references = new List(); - var output = new System.Text.StringBuilder(); - - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - var psi = new ProcessStartInfo(); - psi.WindowStyle = ProcessWindowStyle.Minimized; - - if (isMacOS) - { - psi.FileName = "/usr/bin/mdfind"; - psi.Arguments = string.Format("-onlyin {0} {1}", appDataPath, selectedAssetGUID); - } - else - { - psi.FileName = Path.Combine(Environment.CurrentDirectory, @"Tools\FindReferencesInProject2\rg.exe"); - psi.Arguments = string.Format("--case-sensitive --follow --files-with-matches --no-text --fixed-strings " + - "--ignore-file Assets/Editor/FindReferencesInProject2/ignore.txt " + - "--threads {0} --regexp {1} -- {2}", - cpuCount, selectedAssetGUID, appDataPath); - } - - psi.UseShellExecute = false; - psi.RedirectStandardOutput = true; - psi.RedirectStandardError = true; - - var process = new Process(); - process.StartInfo = psi; - - process.OutputDataReceived += (sender, e) => - { - if (string.IsNullOrEmpty(e.Data)) - return; - - string relativePath = e.Data.Replace(appDataPath, "Assets").Replace("\\", "/"); - - // skip the meta file of whatever we have selected - if (relativePath == selectedAssetMetaPath) - return; - - references.Add(relativePath); - }; - - process.ErrorDataReceived += (sender, e) => - { - if (string.IsNullOrEmpty(e.Data)) - return; - - output.AppendLine("Error: " + e.Data); - }; - - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - - while (!process.HasExited) - { - if (stopwatch.ElapsedMilliseconds < totalWaitMilliseconds) - { - float progress = (float)((double)stopwatch.ElapsedMilliseconds / totalWaitMilliseconds); - string info = string.Format("Finding {0}/{1}s {2:P2}", stopwatch.ElapsedMilliseconds / 1000, - totalWaitMilliseconds / 1000, progress); - bool canceled = EditorUtility.DisplayCancelableProgressBar("Find References in Project", info, progress); - - if (canceled) - { - process.Kill(); - break; - } - - Thread.Sleep(100); - } - else - { - process.Kill(); - break; - } - } - - foreach (string file in references) - { - string guid = AssetDatabase.AssetPathToGUID(file); - output.AppendLine(string.Format("{0} {1}", guid, file)); - - string assetPath = file; - if (file.EndsWith(MetaExtension)) - { - assetPath = file.Substring(0, file.Length - MetaExtension.Length); - } - - UnityEngine.Debug.Log(string.Format("{0}\n{1}", file, guid), AssetDatabase.LoadMainAssetAtPath(assetPath)); - } - - EditorUtility.ClearProgressBar(); - stopwatch.Stop(); - - string content = string.Format( - "{0} {1} found for object: \"{2}\" path: \"{3}\" guid: \"{4}\" total time: {5}s\n\n{6}", - references.Count, references.Count > 2 ? "references" : "reference", selectedObject.name, selectedAssetPath, - selectedAssetGUID, stopwatch.ElapsedMilliseconds / 1000d, output); - UnityEngine.Debug.LogWarning(content, selectedObject); - } - - [MenuItem(MenuItemName, true)] - private static bool FindValidate() - { - var obj = Selection.activeObject; - if (obj != null && AssetDatabase.Contains(obj)) - { - string path = AssetDatabase.GetAssetPath(obj); - return !AssetDatabase.IsValidFolder(path); - } - - return false; - } -} +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Runtime.CompilerServices; +using System.Threading; +using UnityEditor; +using UnityEngine; + +public static class FindReferencesInProject2 +{ + private const string MenuItemName = "Assets/Find References In Project %#&f"; + private const string MetaExtension = ".meta"; + + private static string InstallDirectory = "Assets/Editor/FindReferencesInProject2"; + + private static void UpdateInstallDirectory([CallerFilePath] string executingFilePath = "") + { + InstallDirectory = Path.GetDirectoryName(executingFilePath); + } + + [MenuItem(MenuItemName, false, 25)] + public static void Find() + { + UpdateInstallDirectory(); + + bool isMacOS = Application.platform == RuntimePlatform.OSXEditor; + int totalWaitMilliseconds = isMacOS ? 2 * 1000 : 300 * 1000; + int cpuCount = Environment.ProcessorCount; + string appDataPath = Application.dataPath; + + var selectedObject = Selection.activeObject; + string selectedAssetPath = AssetDatabase.GetAssetPath(selectedObject); + string selectedAssetGUID = AssetDatabase.AssetPathToGUID(selectedAssetPath); + string selectedAssetMetaPath = selectedAssetPath + MetaExtension; + + var references = new List(); + var output = new System.Text.StringBuilder(); + + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + var psi = new ProcessStartInfo(); + psi.WindowStyle = ProcessWindowStyle.Minimized; + + if (isMacOS) + { + psi.FileName = "/usr/bin/mdfind"; + psi.Arguments = string.Format("-onlyin {0} {1}", appDataPath, selectedAssetGUID); + } + else + { + var ignore_file = Path.Combine(InstallDirectory, "ignore.txt"); + var filepath = Path.Combine(Environment.CurrentDirectory, @"Tools\FindReferencesInProject2\rg.exe"); + if (!File.Exists(filepath)) + { + // Assume it's in our path. + filepath = "rg.exe"; + } + psi.FileName = filepath; + psi.Arguments = string.Format("--case-sensitive --follow --files-with-matches --no-text --fixed-strings " + + "--ignore-file {3} " + + "--threads {0} --regexp {1} -- {2}", + cpuCount, selectedAssetGUID, appDataPath, ignore_file); + } + + psi.UseShellExecute = false; + psi.RedirectStandardOutput = true; + psi.RedirectStandardError = true; + + var process = new Process(); + process.StartInfo = psi; + + process.OutputDataReceived += (sender, e) => + { + if (string.IsNullOrEmpty(e.Data)) + return; + + string relativePath = e.Data.Replace(appDataPath, "Assets").Replace("\\", "/"); + + // skip the meta file of whatever we have selected + if (relativePath == selectedAssetMetaPath) + return; + + references.Add(relativePath); + }; + + process.ErrorDataReceived += (sender, e) => + { + if (string.IsNullOrEmpty(e.Data)) + return; + + output.AppendLine("Error: " + e.Data); + }; + + try + { + process.Start(); + } + catch (SystemException) + { + if (!isMacOS) + { + var destination = Path.Combine(Environment.CurrentDirectory, @"Tools\FindReferencesInProject2"); + UnityEngine.Debug.LogError($"Couldn't find ripgrep. Download ripgrep from https://github.com/BurntSushi/ripgrep/releases/latest and extract rg.exe to {destination} or add it to your PATH."); + } + throw; + } + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + while (!process.HasExited) + { + if (stopwatch.ElapsedMilliseconds < totalWaitMilliseconds) + { + float progress = (float)((double)stopwatch.ElapsedMilliseconds / totalWaitMilliseconds); + string info = string.Format("Finding {0}/{1}s {2:P2}", stopwatch.ElapsedMilliseconds / 1000, + totalWaitMilliseconds / 1000, progress); + bool canceled = EditorUtility.DisplayCancelableProgressBar("Find References in Project", info, progress); + + if (canceled) + { + process.Kill(); + break; + } + + Thread.Sleep(100); + } + else + { + process.Kill(); + break; + } + } + + foreach (string file in references) + { + string guid = AssetDatabase.AssetPathToGUID(file); + output.AppendLine(string.Format("{0} {1}", guid, file)); + + string assetPath = file; + if (file.EndsWith(MetaExtension)) + { + assetPath = file.Substring(0, file.Length - MetaExtension.Length); + } + + UnityEngine.Debug.Log(string.Format("{0}\n{1}", file, guid), AssetDatabase.LoadMainAssetAtPath(assetPath)); + } + + EditorUtility.ClearProgressBar(); + stopwatch.Stop(); + + string content = string.Format( + "{0} {1} found for object: \"{2}\" path: \"{3}\" guid: \"{4}\" total time: {5}s\n\n{6}", + references.Count, references.Count > 2 ? "references" : "reference", selectedObject.name, selectedAssetPath, + selectedAssetGUID, stopwatch.ElapsedMilliseconds / 1000d, output); + UnityEngine.Debug.LogWarning(content, selectedObject); + } + + [MenuItem(MenuItemName, true)] + private static bool FindValidate() + { + var obj = Selection.activeObject; + if (obj != null && AssetDatabase.Contains(obj)) + { + string path = AssetDatabase.GetAssetPath(obj); + return !AssetDatabase.IsValidFolder(path); + } + + return false; + } +} diff --git a/Editor/FindReferencesInProject2.cs.meta b/Editor/FindReferencesInProject2.cs.meta new file mode 100644 index 0000000..439beff --- /dev/null +++ b/Editor/FindReferencesInProject2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28b93a2d809b7f0439ed1828f60ab705 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/findrefs.Editor.asmdef b/Editor/findrefs.Editor.asmdef new file mode 100644 index 0000000..612681d --- /dev/null +++ b/Editor/findrefs.Editor.asmdef @@ -0,0 +1,10 @@ +{ + "name": "findrefs.Editor", + "references": [ + ], + "optionalUnityReferences": [ + ], + "includePlatforms": [ + "Editor" + ] +} diff --git a/Editor/findrefs.Editor.asmdef.meta b/Editor/findrefs.Editor.asmdef.meta new file mode 100644 index 0000000..dcaa3ce --- /dev/null +++ b/Editor/findrefs.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: aad0dfb391736c1419e6998db4554f01 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ignore.txt b/Editor/ignore.txt similarity index 88% rename from ignore.txt rename to Editor/ignore.txt index 4b3c8dd..9079e55 100644 --- a/ignore.txt +++ b/Editor/ignore.txt @@ -1,72 +1,72 @@ -# binary files -*.FBX -*.TGA -*.a -*.aar -*.ab -*.bmp -*.bundle -*.bytes -*.chm -*.chw -*.cubemap -*.dds -*.dll -*.exe -*.fbx -*.gif -*.jpg -*.mdb -*.mel -*.mp3 -*.otf -*.pdf -*.png -*.psd -*.swatch -*.tga -*.tif -*.ttf -*.unitypackage -*.wav -*.xlsx -*.zip - -# scripts -*.cs -*.h -*.m -*.mm - -# miscellaneous -*.cginc -*.xml -*.txt -*.swatch -*.md -*.json -*.mdb -*.bat -*.sh -*.jar -*.keystore -*.url -*.html -*.md5 -*.plist -*.modulemap -*.entitlements -*.framework -*.properties -*.XML -*.shader -*.compute - -# all meta except which contains GUID -*.meta - -!*.FBX.meta -!*.fbx.meta -!*.otf.meta -!*.shader.meta -!*.ttf.meta +# binary files +*.FBX +*.TGA +*.a +*.aar +*.ab +*.bmp +*.bundle +*.bytes +*.chm +*.chw +*.cubemap +*.dds +*.dll +*.exe +*.fbx +*.gif +*.jpg +*.mdb +*.mel +*.mp3 +*.otf +*.pdf +*.png +*.psd +*.swatch +*.tga +*.tif +*.ttf +*.unitypackage +*.wav +*.xlsx +*.zip + +# scripts +*.cs +*.h +*.m +*.mm + +# miscellaneous +*.cginc +*.xml +*.txt +*.swatch +*.md +*.json +*.mdb +*.bat +*.sh +*.jar +*.keystore +*.url +*.html +*.md5 +*.plist +*.modulemap +*.entitlements +*.framework +*.properties +*.XML +*.shader +*.compute + +# all meta except which contains GUID +*.meta + +!*.FBX.meta +!*.fbx.meta +!*.otf.meta +!*.shader.meta +!*.ttf.meta diff --git a/Editor/ignore.txt.meta b/Editor/ignore.txt.meta new file mode 100644 index 0000000..4cf1dc8 --- /dev/null +++ b/Editor/ignore.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b5449731d8719ce459839efa75103af3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/LICENSE.meta b/LICENSE.meta new file mode 100644 index 0000000..69103dc --- /dev/null +++ b/LICENSE.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b6d9371dcdcc09f448196d6ff28c312c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md index 9b1fca3..d2f146d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Find asset references super fast in Unity project. Both on macOS and Windows. -![Snapshot](Snapshot.png) +![Snapshot](https://user-images.githubusercontent.com/43559/106349160-9af4c300-6280-11eb-88e9-23db004026f6.png) ## Usage @@ -30,17 +30,31 @@ So it would takes about 5 seconds to search ~700M and ~7000 files on SSD. ## Install -### macOS +Add this line to your Packages/manifest.json: + + "com.github.idbrii.unity-findrefs": "https://github.com/idbrii/unity-findrefs.git#latest-release", -1. Clone repository into `Assets/Editor` directory. +### macOS Job done! It just uses the `mdfind` built in macOS and has no other dependencies. ### Windows -1. Clone repository into `Assets/Editor` directory. -2. Download `ripgrep` from [Latest release · BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep/releases/latest) and extract `rg.exe` to `Tools\FindReferencesInProject2` directory. -3. Click `Unlock file` in `rg.exe` Properties, or you will find it takes too long time to start first time. +#### Scoop + +If you're using [scoop](https://scoop.sh/), install ripgrep: + +``` +scoop install ripgrep +``` + +rg.exe is now in your PATH and usable by unity-findrefs. + + +#### Manual + +1. Download `ripgrep` from [Latest release · BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep/releases/latest) and extract `rg.exe` to `Tools\FindReferencesInProject2` directory. +2. Click `Unlock file` in `rg.exe` Properties, or you will find it takes too long time to start first time. Note: It seems that `x86_64-pc-windows-msvc` has a smaller size in `ripgrep` release page. diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 0000000..1c1b6aa --- /dev/null +++ b/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c03ec6755814d544d873d404ad3afec4 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Snapshot.png b/Snapshot.png deleted file mode 100644 index 9bb5d88..0000000 Binary files a/Snapshot.png and /dev/null differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..b034a6a --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "com.github.idbrii.unity-findrefs", + "displayName": "findrefs", + "version": "2.0.0", + "unity": "2019.4", + "description": "Find references in your project", + "keywords": [ "editor", "reference", "search" ], + "category": "productivity", + "dependencies": {}, + "samples": [ + ] +} diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..bd3cc49 --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6fa60b0e4252a1d41ba841d6f0f1d0d0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: