その前に、
ターミナルから特定のフォルダのファインダーを開く
こちらの記事にあるように、
$ open フォルダパス
ですね。これは有名なので、みなさんご存知かと思います。
次に、
ターミナルから指定したファイルをファインダーに表示
-R
オプションを指定します。
$ open -R ファイルパス
ところが、
複数のファイルを指定した場合は、それらすべてのファイルが選択された状態で表示して欲しいのですが、最後の1ファイルしか選択されていません。
しかも、複数のファイルを指定した場合、極端に動作が遅くなります。
そこで、同機能のコマンドを自作することにします。
コマンド自作
複数のファイルを指定した場合は、すべてのファイルが選択された状態で表示するコマンドを作成します。
使用するAPI
使用するAPIは、activateFileViewerSelecting(_:)
。
activateFileViewerSelecting(_:)
Activates the Finder, and opens one or more windows selecting the specified files.
これ、実現したいことが、まんま叶うAPIです。
ファインダーに表示したいファイルのURLを配列にして引数に渡すだけ。複数のファイルを指定できます。必要により、複数のFinderウインドウが開きます。
Swiftコード
自分はコマンド名をShowInFinder
としましたが、もっと短く全部小文字の方が使い易いと思います。
コードは以下の通り。
import System
import AppKit
let main: () = {
var urls = [URL]()
let currentDirectory = FilePath(FileManager.default.currentDirectoryPath)
for argv in CommandLine.arguments.dropFirst() {
let path = if argv.first! != "/" {
currentDirectory.appending(argv).string
} else {
argv
}
let url = URL(fileURLWithPath: path)
//print(url.path)
if FileManager.default.fileExists(atPath: url.path) {
urls.append(url)
} else {
let msg = "file \(argv) not found."
print(msg, to: &stderr)
}
}
guard urls.count > 0 else {
let commandPath = FilePath(stringLiteral: CommandLine.arguments.first!)
let commandName = commandPath.components.last!
let usage = """
\(commandName): arguments missing.
Usage: \(commandName) file1 [ file2 [ file3 ... ] ]
"""
print(usage, to: &stderr)
return
}
NSWorkspace.shared.activateFileViewerSelecting(urls)
}()
extension UnsafeMutablePointer: TextOutputStream where Pointee == FILE {
public mutating func write(_ string: String) {
guard let data = string.data(using: .utf8) else { return }
_ = data.withUnsafeBytes { bytes in
#if os(Linux)
Glibc.write(fileno(self), bytes.baseAddress!, data.count)
#else
Darwin.write(fileno(self), bytes.baseAddress!, data.count)
#endif
}
}
}
activateFileViewerSelecting(_:)
に渡すURLは、絶対パス(完全パス)である必要があるため、"/"
で始まっていないパスには、カレントディレクトリパスに連結しています。
存在しないパスは無視します。
最後のextension
は、print
でstderr
に出力するための汎用的なもので、本コマンドに直接は関係しません。
ビルド
次のコマンドでビルド(コンパイル&リンカ)します。
$ swiftc ShowInFinder.swift -o ShowInFinder
使い方
ビルドして出来たコマンドにpath
を通します。もしくはpath
の通っているフォルダにコピーします。
$ ShowInFinder
ShowInFinder: arguments missing.
Usage: ShowInFinder file1 [ file2 [ file3 ... ] ]
$ ShowInFinder hoge.png fuga.png
$ ShowInFinder *.png
環境
執筆時の環境は以下の通り
$ uname -a
Darwin Mac-mini.local 23.4.0 Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:06 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T8103 arm64
$ swiftc --version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0