📁

Material Icon なフォルダを作成するコマンドを作った

2022/06/24に公開

デスクトップに配置されたimagesフォルダのアイコンデザインを変更したかったので、Material Icon Theme が効いたフォルダを作成できるコマンドを作りました。
ファイルは用途が少なそうなので、フォルダだけを実装します。

https://github.com/ogty/iconic-commands

目次

  • アイコンをダウンロードする
  • フォルダのアイコンをコマンドで変更する
  • svg ファイルを png ファイルに変換する
  • フォルダ名に応じてアイコンを変更する
  • JSON データを作成する
    • 変換データを作成する
  • 新規フォルダ作成時に適応されるようにする
    • フォルダ構成
  • 最後に

アイコンをダウンロードする

https://github.com/PKief/vscode-material-icon-theme

使用させていただくアイコンデータはMaterial Icon Themeです。
Code > Download ZIPからダウンロードし解凍しておきます。

フォルダのアイコンをコマンドで変更する

ファイル・フォルダのアイコンを変更できるコマンドにfileiconがあるので、npmを使ってfileiconをグローバルにインストールします。

通常の変更方法:Macでファイルやフォルダのアイコンを変更する

$ npm install -g fileicon

フォルダのアイコンを変更したい場合は以下のコマンドで変更できます。
また、-qオプションを付けることでサイレントモードで実行できます。

$ fileicon -q set <folder> <icon>

アイコンの変更に使用できるファイル形式 ↓

  • jpeg
  • tiff
  • png
  • gif
  • jp2
  • pict
  • bmp
  • qtif
  • psd
  • sgi
  • tga

svg ファイルを png ファイルに変換する

ダウンロードしたアイコンのデータは svg 形式で、fileiconのコマンドに対応していません。そのため、png に変換します。
デフォルト?でqmanageというコマンドがあるみたいですが、解像度が低く、透過してあるデータでも背景ありにされるため、代わりにlibrsvgを使います。

$ brew install librsvg

使い方 ↓

$ rsvg-convert -h 32 <svg-file> > <png-file>

例えばfolder.svgファイルがあり、これをfolder.pngに変換する場合は以下のコマンドを実行します。

$ rsvg-convert -h 120 folder.svg > folder.png

-hオプションの値が小さいと解像度が低くなるので丁度良さそうな120を設定しました。

フォルダ名に応じてアイコンを変更する

Material Icon Theme や、その他のアイコンを変更する拡張機能では、拡張子やフォルダ名に応じて、デザインが変更されています。

アイコンの適応方法は
vscode-material-icon-theme/src/icons/folderIcons.ts
folderIconsを使えばいけそうです。

folderIcons.tsから以下のような、keyに指定のフォルダ名、valueにアイコンファイル名となっているデータが欲しい。

[
  "src": "folder-src",
  "srcs": "folder-src",
  "source": "folder-src",
  "sources": "folder-src"
]

JSONデータを作成する

変換データを作成する

folderIcons.tsから先ほどのような JSON データを作成します。
コードの一部は以下のようになっています。

export const folderIcons: FolderTheme[] = [
  {
    name: 'specific',
    defaultIcon: { name: 'folder' },
    rootFolder: { name: 'folder-root' },
    icons: [
      {
        name: 'folder-src',
        folderNames: ['src', 'srcs', 'source', 'sources', 'code'],
      },
      {
        name: 'folder-dist',
        folderNames: ['dist', 'out', 'build', 'release', 'bin'],
      },

      // ...
  }
]

folderIconsを読み込み JSON データを作成するコードを書いていきます。

型を消したときにエラーになる箇所は削除します。

  • enabledFor: [IconPack.Ngrx]
  • enabledFor: [IconPack.Redux]
  • enabledFor: [IconPack.React, IconPack.Redux]
  • enabledFor: [IconPack.Vuex]
  • enabledFor: [IconPack.Vuex, IconPack.Vue]

修正したファイルはfolderIconsData.tsとして保存しています。

folderIconDataCreator.ts
import { folderIcons } from './folderIconsData';

console.log(folderIcons.length); // 3

配列数は3ですが1, 2のインデックスはデフォルトアイコンなどの、不要なデータなので使用しません。

コード ↓

import { folderIcons } from './folderIconsData';

const icons = folderIcons[0].icons;
const result = {};

if (icons) {
    const icontLength = icons.length;
    
    for (let i = 0; i < icontLength; i += 1) {
      const icon = icons[i];
      const iconName = icon.name;
      const folderNames = icon.folderNames;
      const folderNameLength = folderNames.length;

      for (let j = 0; j < folderNameLength; j += 1) {
        const folderName = folderNames[j];
        result[folderName] = iconName;
      }
    }

    console.dir(result, {'maxArrayLength': null});
}

これを実行して、少し修正すると以下のようなデータが得られます。

{
  "src": "folder-src",
  "srcs": "folder-src",
  "source": "folder-src",
  "sources": "folder-src",
  "code": "folder-src",
  "dist": "folder-dist",
  "out": "folder-dist",
  "build": "folder-dist",
  "release": "folder-dist",
  ...
}

新規フォルダ作成時に適応されるようにする

mkdirコマンドをラップする独自コマンドを作成します。
コマンド名はMaterial Icon mkdirの略でmimkdirとします。
ホームディレクトリ直下にmimkdirフォルダを作成します。
注意点として、コマンドラインから作成したフィルダしかアイコンの変更をカバーできません。

$ cd ~/
$ mkdir mimkdir
$ cd mimkdir

フォルダ構成

mimkdir
├── images
├── icons
│   └── *.svg
├── data
│   ├── fileIcons.json
│   └── folderIcons.json
└── mimdir

ダウンロードしてきた svg データを png に変換するのが面倒だったので、
都度 png に変換したものをimagesに保存して使うようにします。

JSON データから特定のvalueを取得するためにawkファイルを作成します。

main.awk
BEGIN {
    FS = ":";
}

{
    key = gensub("\"", "", "g", $1);
    key = gensub(/\s/, "", "g", key);

    if (target == key) {
        value = gensub("\"", "", "g", $2);
        value = gensub(",", "", "g", value);
        value = gensub(/\s/, "", "g", value);
        print(value);
    }
}

.zshrcファイルに<username>を自分のユーザー名に書き換えたものを追記します。

.zshrc
export PATH="$PATH:/Users/<username>/mimkdir"

追記できたら以下のコマンドを実行します。

$ source .zshrc

次にコマンドファイルを作成します。
フォルダ名が特別な意味を持たない場合は通常のmkdirコマンドを実行するようにします。

mimkdir
icon=$(cat ~/mimkdir/data/folderIcons.json | awk -f ~/mimkdir/main.awk -v target="$1")

if [ -z $icon ]; then
    mkdir ./$1
else 
    eval "rsvg-convert -h 120 ~/mimkdir/icons/$icon.svg > ~/mimkdir/images/$icon.png"
    mkdir ./$1 && fileicon -q set ./$1 ~/mimkdir/images/$icon.png
fi

mimkdirファイルにパーミッションを設定します。

ちなみにMacのTerminalでsudo実行時にタッチIDを使用する方法

$ sudo chmod 755 mimkdir

これで作成できたので、実行してみます。

$ mimkdir images

mimkdir sample

最後に

かなり見やすくなりました。
Chrome の拡張機能には Github のアイコンを変更してくれる拡張機能もあるみたいです。

https://chrome.google.com/webstore/detail/material-icons-for-github/bggfcpfjbdkhfhfmkjpbhnkhnpjjeomc/related

Discussion