Spotlight doesn’t index playground contents. This is a source of endless frustration to me and today I finally had enough. I wrote this. It performs a spotlight search for playground bundles and then manually greps their contents for search phrases. Let me know if anyone finds it useful. And please file a radar. I don’t want mine to be lonely.
I also set up a bunch of smart folders to help me find things.
The first two list all playgrounds and all swift files on my Mac. The second two show any playgrounds and swift files I’ve opened today. There isn’t overlap because swift files within playgrounds aren’t indexed.
Create smart folders by opening a Finder window. Type Command-F. Enter search criteria and then click Save.
Today’s two main.swift files are from this morning’s “eval” example and this evening’s “pggrep”. None of my work on playgrounds today shows up in the search.
Compare with the “Today’s Playgrounds” results:
3 Comments
I am also surprised you can’t quicklook a playground file. I am so used to navigating through the finder and hitting space on source files, it was quite jarring to just see only a large playground icon.
No idea how to use it… plus it’s not been updated for Swift 2.0
#!/usr/bin/env swift
//
// main.swift
// pggrep
//
// Created by Erica Sadun on 6/17/15.
// Copyright © 2015 Erica Sadun. All rights reserved.
//
import Foundation
// mdfind ‘kMDItemDisplayName == *.playground’
func PlaygroundList() -> [String] {
let task = NSTask()
task.launchPath = “/usr/bin/mdfind”
task.arguments = [“kMDItemDisplayName == *.playground”]
let pipe = NSPipe()
task.standardOutput = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
guard var s = NSString(data: data, encoding: NSUTF8StringEncoding) else {return []}
s = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
return s.componentsSeparatedByString(“\n”)
}
func SwiftList() -> [String] {
let task = NSTask()
task.launchPath = “/usr/bin/mdfind”
task.arguments = [“kMDItemDisplayName == *.swift”]
let pipe = NSPipe()
task.standardOutput = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
guard var s = NSString(data: data, encoding: NSUTF8StringEncoding) else {return []}
s = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
return s.componentsSeparatedByString(“\n”)
}
func PerformQuery(query : String, path: String) -> NSString {
let task = NSTask()
task.launchPath = “/usr/bin/grep”
task.arguments = [“-R”, query, path]
let pipe = NSPipe()
task.standardOutput = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
guard var s = NSString(data: data, encoding: NSUTF8StringEncoding) else {return “”}
s = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
return s
}
func grep(query: String) {
print(“Searching for \(query)”)
// Iterate through each playground
let pgPaths = PlaygroundList()
for path in pgPaths {
// Fetch results
let s = PerformQuery(query, path: path)
if s.length == 0 {continue}
// Defer printing playground info until a match is found
var isFirst = true
// Decompose the grep results into lines
let array = s.componentsSeparatedByString(“\n”)
for line in array {
// Ignore any “Binary” files
if line.hasPrefix(“Binary”) {continue}
// Split the rest into fileName:match
let splits = line.characters.split {$0 == Character(“:”)}.map{String($0)}
let range = path.startIndex..<path.endIndex
var fname: String = splits[0] // NSString(string: splits[0]).lastPathComponent
fname.removeRange(range)
if !fname.hasSuffix("swift") {continue}
if splits.count < 2 {continue}
// If this is a first match, show the playground info
if isFirst {
let playgroundName = NSString(string: NSString(string: path).lastPathComponent).stringByDeletingPathExtension
print(String(count:playgroundName.characters.count, repeatedValue:Character("-")))
print(playgroundName)
print(String(count:playgroundName.characters.count, repeatedValue:Character("-")))
let pathIncludingPlaygroundName = NSString(string:path).stringByDeletingPathExtension
print(pathIncludingPlaygroundName)
isFirst = false
}
// Print the file name and the match
let rest = splits[1]
let pathIncludingPageName = NSString(string:fname).stringByDeletingPathExtension
print(" \(pathIncludingPageName): \(rest)")
}
// Leave spaces between playground results
if !isFirst {print("")}
}
}
var args = Process.arguments.dropFirst()
if args.count == 0 {
print("Must suply query")
exit(-1)
}