フォルダだけをコピーするAlfred Workflow

## はじめに

たとえばフォルダが10個あるとして、ふつうにコピーすると、10個のフォルダ＋フォルダの中身がコピーされます。そうではなくて、「10個のフォルダだけコピーして、中身はコピーしない」でほしかったので、ツールをつくりました。

おもちゃ箱にたとえると、おもちゃ（中身）はコピーせずに、おもちゃ箱だけコピーするということです。新しいおもちゃを手に入れても、使いやすいおもちゃ箱に、どんどん入れることができますね！

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/cd61a370-4bff-c5cd-9c11-5bbfd429ad05.gif)

フォルダのbefore/afterをツリー状に書くとこんな感じです。

```
─ 学び合い研究会#01                        ─ 学び合い研究会#02
├── 01_スライド（事前）                    ├── 01_スライド（事前）
│   ├── 00001ファイル .pdf                ├── 02_事前課題
│   ├── 00002ファイル .pptx        ->     ├── 03_小部屋スライド
│   ├── 00003ファイル .pptx               ├── 04_当日スライドとシート
│   ├── 00004ファイル .pptx               ├── 05_事後共有スライド
│   ├── 00005ファイル .xlsx               └── 06_アウトプット
│   ├── 00006ファイル .pdf
│   └── 00007ファイル .xlsx
├── 02_事前課題
│   ├── 00001ファイル .pdf
│   ├── 00002ファイル .pdf
│   ├── 00003ファイル .xlsx
│   ├── 00004ファイル .pptx
│   └── 00005ファイル .pptx
├── 03_小部屋スライド
│   ├── 00001ファイル .pptx
│   ├── 00002ファイル .pptx
│   ├── 00003ファイル .pptx
│   └── 00004ファイル .pptx
├── 04_当日スライドとシート
│   ├── 00001ファイル .pdf
│   ├── 00002ファイル .pptx
│   └── 00003ファイル .pptx
├── 05_事後共有スライド
│   ├── 00001ファイル .pptx
│   ├── 00002ファイル .pptx
│   ├── 00003ファイル .pptx
│   └── 00004ファイル .pptx
└── 06_アウトプット
    ├── 00001ファイル .xlsx
    └── 00002ファイル .xlsx
```

## 動作の概要

- Alfred Workflowで`duplicate folders`というコマンドを作りました
- コピー元をA、コピー先をBとします。
- Aでフォルダを選択し、コピーします
- Bのフォルダを選択した状態で、Alfredを起動します
- `du`ぐらいまで入力すると、`duplicate folders`が起動し、Bにフォルダをコピーします

## 仕組みの概要

![HF_SS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/65f0a09a-40f6-9c21-8e50-ddeead5d318a.png)

1. `duplicatefolders`というキーワードで起動します
1. 確認ダイアログ用の情報を取得します
1. 意図しないコピーを防ぐため、確認ダイアログを出します
1. AppleScriptで、コピー先（B）の絶対パスを取ります
1. Shell Scriptで、クリップボードからフォルダ名を取得し、フォルダを作成します

## 仕組みの詳細

### `duplicatefolders`というキーワードで起動します

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/f29cbb67-caa3-839f-df76-892dde540832.png" width=50%>

じっさいには`du`ぐらいで起動するようになります。

### 確認ダイアログ用の情報を取得します／確認ダイアログを出します

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/7fd4165c-29f9-d904-1cfa-a95d1b5b36e5.png" width=25%>

あまり重要ではないので詳細は割愛します。

### AppleScriptで、コピー先（B）の絶対パスを取ります

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/b6184dcd-19b7-570d-aa30-322cf5b47443.png" width=50%>

```applescript
on run
  tell application "Finder"
    set pathList to (quoted form of POSIX path of (folder of the front window as alias))
  end tell
  return pathList
end run
```

ハマったところは……

- `Run NSAppleScript`アクションではなく、`Run Script`アクションをつかい、Languageで`/usr/bin/osascript(AppleScript)`を選択すること
- `on run ... end run`と書くこと　←　ここがいちばんハマったかも
    - NSAppleScriptでは、`on alfred_script(q) ... end alfred_script`と書きます
- `return`で、標準出力（Alfred Workflowでは`output`）に情報を流せる


### Shell Scriptで、クリップボードからフォルダ名を取得し、フォルダを作成します

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/7f8f0583-97a9-95d4-0d48-fdab5639470f.png" width=50%>

```zsh
query="{query}"
cd ${query}
pbpaste | tr '\r' '\n' | xargs mkdir
```

ハマったところは……

- `with input as {query}`をつかう
    - `with input as agrv`でもイケルはずなんですが、`'`を上手く処理できませんでした
    - AppleScriptで取ってきたパスが、`'/Users/user01/Documents/学び合い研究会#01'`となっていて、うまく捌けなかったんですよね

## おわりに

### 環境

ここで書いていることは、下記のバージョンで実施しました。

- macOS Monterey 12.3.1
- MacBook Pro (14-inch, 2021)


### 参考リンク

■ AppleScript ■

鳶嶋工房 / AppleScript / 入門(Introduction)
http://tonbi.jp/AppleScript/Introduction/

How to show script results in Alfred's main window? - Workflow Help & Questions - Alfred App Community Forum
https://www.alfredforum.com/topic/9460-how-to-show-script-results-in-alfreds-main-window/

MacScripter / Using Applescript Dictionaries
https://macscripter.net/viewtopic.php?id=24777

■ Alfred Workflow ■

Alfred Workflow - How to pass variables from Applescript to Output.
https://rayshines.tistory.com/133


■ シェルスクリプト（tr, sed） ■

tr コマンド – 文字を変換または削除 | Linuxコマンド.NET
https://linuxcommand.net/tr/