{
   "labels" : [
      "code",
      "utility",
      "infrastructure",
      "reusable"
   ],
   "code" : "// Require files in your documents and they will be loaded\r\n// in if they are one of the search paths.\r\n// First looks relative to the current document then thought search paths in the order they are added.\r\n// Add search paths with the *add() method in your startup file. Will only keep one copy.\r\n// A Singleton (design pattern).\r\n\r\nRequire\r\n{\r\n\tclassvar instance;\r\n\tvar <>searchPaths;\r\n\r\n\t// We actually want to mimic syntax from other languages,\r\n\t// so because *new is the default function on classes we can use it like:\r\n\t// Require(\"MySynthDef\") and this will find the file and execute it.\r\n\t*new {\r\n\t\targ ... files;\r\n\t\t^Require.search(files)\r\n\t}\r\n\r\n\t*construct {\r\n\t\t^super.new.init()\r\n\t}\r\n\r\n\tinit {\r\n\t\t// Default path.\r\n\t\tsearchPaths = []\r\n\t}\r\n\r\n\t// Look for the file in all the searchPaths in order until we find one.\r\n\t// Will search for 'file' and 'file.scd'.\r\n\t*search {\r\n\t\t| files |\r\n\t\tvar me = thisProcess.nowExecutingPath,\r\n\t\t\ttrying,\r\n\t\t\trelative,\r\n\t\t\tpaths = Array.newClear()\r\n\t\t;\r\n\t\tif(me.isNil.not) {\r\n\t\t\trelative = PathName(me).pathOnly;\r\n\t\t\tpaths = paths ++ [relative];\r\n\t\t} {\r\n\t\t\t\"Current document has not path! Have you saved it?\".warn\r\n\t\t};\r\n\t\tpaths = paths ++ Require.get.searchPaths;\r\n\r\n\t\tif(files.isString) { files = [files] };\r\n\r\n\t\tfiles.do{ | file |\r\n\t\t\tpaths.do { | path |\r\n\t\t\t\ttrying = (path +/+ file);\r\n\t\t\t\tif(trying.pathMatch.isEmpty.not and:{trying != me}) {\r\n\t\t\t\t\t(\"Require loading: \" ++ trying).postln;\r\n\t\t\t\t\ttrying.load.postln;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t*get {\r\n\t\t^( instance ?? { instance = Require.construct })\r\n\t}\r\n\r\n\t*getSearchPaths {\r\n\t\t^Require.get.searchPaths;\r\n\t}\r\n\r\n\t// Add a search path\r\n\t*add {\r\n\t\t| path, recursive |\r\n\r\n\t\tvar path_list = [];\r\n\r\n\t\tif(path.isString.not) {\r\n\t\t\tpath = path.asString;\r\n\t\t};\r\n\t\tpath = path.standardizePath;\r\n\r\n\t\tif(Require.get.searchPaths.indexOfEqual(path).isNil) {\r\n\t\t\tif(path.pathMatch.isEmpty.not) {\r\n\t\t\t\tif(recursive) {\r\n\t\t\t\t\tpath_list = path_list ++ this.getSubFolders(PathName.new(path));\r\n\t\t\t\t};\r\n\t\t\t\tpath_list.do{ | path |\r\n\t\t\t\t\t(\"Require, adding path: \" ++ path.fullPath).postln;\r\n\t\t\t\t\tRequire.get.searchPaths = Require.get.searchPaths.add(path.fullPath);\r\n\t\t\t\t};\r\n\t\t\t\t^path_list\r\n\t\t\t} {\r\n\t\t\t\t(\"Require, path does not exist: \" ++ path).warn;\r\n\t\t\t}\r\n\t\t} {\r\n\t\t\t(\"Require, NOT adding path, already have it: \" ++ path).warn;\r\n\t\t}\r\n\t}\r\n\t// Get all the sub folders recursively\r\n\t// @param\tpath\tPathName object\r\n\t// @return\tan Array of PathName objects\r\n\t*getSubFolders {\r\n\t\t| path |\r\n\r\n\t\tvar result = [path];\r\n\r\n\t\tresult = result ++ path.folders.collect{ |p|\r\n\t\t\tthis.getSubFolders(p);\r\n\t\t};\r\n\t\t^result.flat\r\n\t}\r\n}",
   "is_private" : null,
   "id" : "1-50H",
   "author" : "whillas",
   "name" : "'Require' class for code importing",
   "description" : "Require files in your documents and they will be loaded in if they are one of the search paths.\r\nFirst looks relative to the current document then thought search paths in the order they are added.\r\nAdd search paths with the *add() method in your startup file. So for example you might have this in your startup.scd file:\r\n\r\n~mySC = \"/Users/bob/Dropbox/SuperCollider/MySC\";\r\nRequire.add(~mySC ++ \"/includes\", true);\r\n\r\nthen in any file you can include synthdefs or whatever you like from your /includes folder with\r\n\r\nRequire(\"myCoolSynth.scd\");\r\n\r\nor multiple files:\r\n\r\nRequire(\"player.scd\", \"delayeffect.scd\");",
   "ancestor_list" : []
}
