かすみん日記

暇なときに何か喋ります

【正規表現】先読みと後読みの違いを表で理解する

正規表現の先読みと後読みの違いを表で整理する。

日本語で説明聞いてもよくわからないので、表から法則性を読み取る作戦に出る。

肯定の方だけ。

検索対象文字列は以下で固定とする。

hello_world!!
分類 正規表現 一致文字列 先・後読みで取得した「位置」に@ 挿入
肯定先読み .*(?=world) hello_ hello_@world!!
肯定先読み (?=world).* world!! hello_@world!!
肯定後読み .*(?<=world) hello_world hello_world@!!
肯定後読み (?<=world).* !! hello_world@!!
非捕獲式集合 .*(?:world) hello_world hello_world!!
非捕獲式集合 (?:world).* world!! hello_world!!

これで法則性が何となくわかるはず?

参考

表で整理するという発想を参考にした。

qiita.com

【vscode】アルファベットの大文字小文字を変換する正規表現

vscodeのcmd + F(win: ctrl + F)で出てくる検索・置換窓で使える正規表現について。 正規表現エンジンはJSのやつと同じらしいが詳しいことはよくわからない。

基本

大文字に変換する場合

  • 検索文字:(\w+)
  • 置換文字:\U$1

例:hello -> HELLO

小文字に変換する場合

  • 検索文字:(\w+)
  • 置換文字:\L$1

例:HELLO -> hello

その他応用

先頭文字だけ大文字にする

  • 検索文字:(\w)(\w+)
  • 置換文字:\L$1\U$2

例:hello -> Hello, crazyApple -> Crazyapple

先頭文字だけ大文字にして、以降はそのまま(キャメルケースをパスカルケースに変換)

  • 検索文字:(\w)(\w+)
  • 置換文字:\L$1$2

例:hello -> Hello, crazyApple -> CrazyApple

ps1とかperlみたいに先頭に$がついた変数だけを対象とするとき:

  • 検索文字:\$(\w)(\w+)
  • 置換文字:$$\L$1$2

例:$hello -> $Hello, $crazyApple -> $CrazyApple

検索文字列の方の大文字小文字判定

難しく考えなくていい。

大文字は[A-Z]で、小文字は[a-z]でマッチする。

vscodeなら「Aa」のアイコンをクリックにして大文字小文字の区別を有効にしていないと区別されないので注意。

以上!

【vscode】拡張機能PowerShellを入れると##入力で勝手になんか挿入されるのを無効にする【pwsh/PS1】

環境

内容

vscodeにて、拡張機能PowerShellをインストールした状態で、言語powershellのエディタで ## と入力すると、勝手になんか挿入される:

<#
.SYNOPSIS
Short description

.DESCRIPTION
Long description

.EXAMPLE
An example

.NOTES
General notes
#>

うざいので無効にする。

設定(cmd + ,)を開いて、helpCompletion などと検索。 設定項目「PowerShell: Help Completion」がヒットするはずなので、そのプルダウンから「Disable」を選択する。 以上!

※なんかワシが設定したときはすぐ反映されなかった。vscode再起動すると適用された。

setting.json を直接編集するのであれば以下を追加する:

  "powershell.helpCompletion": "Disabled",

余談1

以下でこれうざいとクレームが上がって、公式機能で有効無効設定可能になったらしい。

github.com

github.com

github.com

余談2:そもそも挿入されるこれは何

そもそも挿入される <# ... #> は一体何なのかというのは、以下サイトなどを参照。

miajimyu.com

本当の余談

前回最後に書いた記事が250日前らしい。 サボりすぎ!!!!!

自作したSafari拡張機能をAppStoreに公開せず使用する

概要

Chrome/Firefoxはググれば情報がたくさん出てくるが、Mac Safariについては全然情報がなかったのでメモ。

自作したSafari extensionをAppStoreに公開せず使用できるようになるまでの道順を以下に示す。

chrome拡張機能は作成済みとして、ストア公開とかはやらない前提。 あとiOSも対象外。Macのみ。

環境

手順

前提準備:chrome用の拡張機能を作成

準備済みの方はスキップして下さい。 そうでない方は、以下にサンプルを置いておくので、コピペしてファイルを用意して下さい。

まず、ディレクトリを作成。とりあえず名前はsample01/としておく。

mkdir sample01

エディタで開くなどして、以下の内容のファイル(2つ)を作成します。

manifest.json:

{
  "name": "サンプル01",
  "description": "Safari拡張機能のテストです",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
      "default_popup": "popup.html"
  },
  "icons": {
    "128": "icon.png"
  }
}

popup.html:

<p>Sample 01</p>

あと、必須ではないですが、後にエラーメッセージが出て少し気になるので、アイコンも用意しておきます。 以下の画像をDLでいいので、icon.pngという名前でsample01/に配置します。

icon.png

以上で準備完了。

chrome拡張機能Safari用にconvert

chrome拡張機能のソースが入っているディレクトリをsample01/として話を進める。

まず、xcodeを持ってない方はインストールして下さい(確か標準でインストール済みではなかったはず)。

xcodeに付いてくる以下のコマンドで、拡張機能chrome用 -> safari用にconvertします。

xcrun safari-web-extension-converter sample01

以下のようなメッセージが出力され、xcodeが起動したら成功。

 % xcrun safari-web-extension-converter ./sample01
Xcode Project Location: /Users/<ユーザ名>/〜〜〜
App Name: サンプル01
App Bundle Identifier: com.yourCompany.-----01
Platform: All
Language: Swift

アイコンがないとエラーメッセージも出ますが、無視して進めても問題ないです。

xcodeが起動せず、なんか長文のエラーメッセージが出た人は、下記コマンドでxcodeをアップデート。

xcodebuild -runFirstLaunch

それでも解決しない場合はググって下さい。

成功した人は以下のようにxcodeが起動しているはず。

また、sample01/と同じ階層に、manifest.jsonnameで指定した名前サンプル01ディレクトリが作成されている。 その中にあるサンプル01.xcodeprojをFinderからダブルクリックしてもxcodeを開けます。

拡張機能に署名

この手順はスキップ可能です。 しかし、署名を行わないと、Safariを再起動するたび拡張機能を再インストールしなければならないので面倒です。

先ほど開いたxcodeにて、左のサイドバーの一番上になるアプリ名サンプル01をクリックします。

そして、中央上部の「Signing & Capabilities」タブを選択します。

中央の左側「TARGETS」で「サンプル01 (macOS)」を選択し、中央の「Signing」>「Team」のプルダウンで「<名前> (Personal Team)」を選択します。 これは自分が持っているApple IDのことです(多分)。

「TARGETS」の「サンプル01 Extension (macOS)」でも同じく「Team」を変更します。

署名の作業は以上で終了です。

拡張機能のビルド&実行

Xcodeのウインドウ上部のメニューバーにて、Schemeを「サンプル01 (macOS)」に切り替えます。 「Product」>「Scheme」からも変更可能。

あとは、メニューバーの「▶」アイコンを押下するか、「Product」>「Run」にてアプリを実行します。

「Build Succeeded」と表示されれば成功です。

Safari拡張機能の方ではなくて、アプリの方のウインドウが表示されますが、こっちはcmd + Qで終了してOKです。

Xcodeの方ももう使わないのでcmd + Qで終了してOKです。

Safari拡張機能を使う。

Safariを開いて、cmd + ,押下するか「Safari」>「環境設定...」を開きます。 環境設定の「拡張機能」タブを開くと、先ほど作成した拡張機能が表示されているので、チェックを付けて有効にします。

そうすれば、Safari上部のメニューバーに描く超勤追うのアイコンが表示されるはずです。 なければ「ツールバーをカスタマイズ」から追加する。

最後に、拡張機能アイコンをクリックしてpupup.htmlの内容が表示されたら成功です。

また、Safariを再起動しても拡張機能がインストールされたままになっていることも確認して下さい。

以上です。お疲れさまでした。

補足

署名しない場合

拡張機能に署名がない場合は、そのままではSafariにインストールできません。

「開発」>「未署名の拡張機能を許可」で許可して下さい。

ただ、Safariを再起動するたびにのこ許可のチェックは外れるので、署名なし拡張機能を継続的に使うのはかなり面倒です。

拡張機能のアンインストール

ビルドで作られたアプリは以下にあるようなので、アプリごと削除。

~/Library/Developer/Xcode/DerivedData

DerivedDataの削除についての記事:

dev.classmethod.jp

参考

xcodeでの署名: anond.hatelabo.jp

chrome用からSafari用へのconvertコマンド: applech2.com

古い: qiita.com

【Chrome拡張機能】特定のURLの時だけpopup表示の代わりにonClickedイベントを発生させる

実現したいこと

ツールバー拡張機能アイコンをクリックしたとき、特定のURLのときだけポップアップを表示し、それ以外のURLではポップアップを表示する代わりにaction.onClicked.addListenerを設定したい。

環境

内容

以下の例では、ツールバー拡張機能アイコンをクリックしたとき、開いている(activeな)タブのURLがhttps://www.google.com/〜のときはpopup.htmlを表示し、それ以外のURLのときはポップアップは表示せず、その代わりに新規タブでhttps://www.google.comを開くような拡張機能を作ります。

用意するファイルは以下の3つ:

  • manifest.json
  • popup.html
  • background.js

それぞれの中身は以下の通りです。

manifest.json:

{
  "name": "てすと",
  "description": "てすとです。",
  "version": "1.0",
  "manifest_version": 3,
  "permissions": ["activeTab", "tabs"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  }
}

マニフェストバージョンが3なのと、permissionstabsも必要なことに注意してください。
(失敗談:permissionstabsを指定していないと、tab.urlでURLが取得できなかった)

あと、backgroundがこの書き方だと、そのままではfirefoxに流用できないっぽいです(参考)。

popup.html:

<p>今期の覇権はU149</p>

ポッポアップの表示の確認だけなので、中身はなんでもいいです。好きな俳句を書いてください。

background.js:

chrome.tabs.onActivated.addListener( function(activeInfo){
  chrome.tabs.get(activeInfo.tabId, function(tab){
    setAction(tab.url);
  });
});

chrome.tabs.onUpdated.addListener((tabId, change, tab) => {
  if (tab.active && change.url) {
    setAction(change.url);
  }
});

function setAction(url) {
  // console.log(url);
  const pattern = /^https:\/\/www.google.com/;
  if (pattern.test(url)) {
    chrome.action.setPopup({ popup: "./popup.html"})
    chrome.action.onClicked.removeListener(openGoogle);
  } else {
    chrome.action.setPopup({ popup: "" });
    chrome.action.onClicked.addListener(openGoogle);
  }
}

function openGoogle(tab) {
  const newURL = 'https://www.google.com';
  chrome.tabs.create({ url: newURL });
}

ここにガッツリ処理を書いていますね。ざっくり解説します。

tabs.onActivatedは、アクティブなタブを切り替えたときに発生するイベントです。 tabs.onUpdatedの方は、タブの情報に変更があったとき(画面遷移やリロードなど)に発生するイベントです。 これらのイベントが発生したときに、アクティブなタブのurlを取得して、それを引数として関数setActionを呼んでいます。

setActionでは、アクティブなタブのURLがGoogleかどうかを見分けて、ツールバー拡張機能アイコンをクリックしたときの処理を付け替えています。 アクティブなタブのURLがGoogleのとき(if文のtrueの処理)、ポップアップに./popup.htmlを設定しています。 これはmanifestのdefault_popupに指定したものと同じです。 またこのとき、クリックイベントのリスナーopenGoogleを削除しています。

アクティブなタブのURLがGoogleでないとき(if文のfalseの処理)は、上記の逆の処理を行なっています。 action.setPopup({ popup: "" })でポップアップのhtmlを空白で上書き(削除)しています。 そうすることで、拡張機能のアイコンをクリックしても、ポップアップは表示されなくなります。 また、action.onClicked.addListener(openGoogle)にて、アイコンをクリックしたときに関数openGoogleが呼ばれるようにリスナーを設定しています。 関数openGoogleは、URLがhttps://www.google.comの新しいタブを作成(してアクティブに)する処理となっています。

説明は以上です。 あとは適当に応用していただければと思います。

参考

developer.mozilla.org

developer.mozilla.org

developer.mozilla.org

stackoverflow.com

stackoverflow.com

github.com

【Homebrew】Error: You have not agreed to the Xcode license.

久しぶりにbrewコマンドを打ったら以下のエラーが出た:

Error: You have not agreed to the Xcode license. Please resolve this by running:
  sudo xcodebuild -license accept

Xcodeのライセンスに同意しろとのこと。

環境

  • MacOS Monterey 12.5.1
  • Homebrew 3.5.9
% brew --version 
Homebrew 3.5.9
Homebrew/homebrew-core (git revision 27007d7668a; last commit 2022-08-20)
Homebrew/homebrew-cask (git revision d2da3c1a45; last commit 2022-08-20)

対応

ググったら他にも遭遇している人がたくさん居るようだった。 まあ、Xcodeのライセンスに同意すればいいとのこと。

エラーメッセージにあるように、以下コマンドを実行した:

sudo xcodebuild -license accept

これでもう初めに書いたエラーは出なくなった。

【Mac】特定のアプリのみFnキーを標準のFnキーとして使用する【Karabiner】

vscodeでのみ、fnキーで装飾しないでもそのままF5とかF12とかを使えるようにしたい。

Mac OSだと基本的にファンクションキーは使わないが、vscodeマイクロソフト製なので、、

環境

目的

Mac OSのシステム環境設定では、以下のように設定しています:

  • 基本的にfnキーは画面の輝度調整や音量コントロールのために使用する
  • 本来?のファンクションキーとしての動作は、fnキーと同時押しで有効にする

でも、一部アプリではファンクションキーに本来の力を取り戻して欲しいんじゃ!

Karabiner先輩「呼んだ?」

Karabinerの設定

仕様

とりあえず例として、vscodeというアプリがアクティブの時のみ、以下の動作をするような設定を作りました。

  • F1〜F12キー単体押しで、標準のファンクションキーの動作をする
  • F1〜F12キーをfnキーと同時に押したときは、輝度や音量調整などの動作をする

あと、システム環境設定のチェックありなしに関わらずこの動作します。 チェックしてても動作は反転しないです。 反転の挙動がお望みなら、設定ファイルの方でうまいこと逆の動作になるように修正して下さい。

設定の適用の仕方

作った設定のソースコードは長いので記事の最後に貼っています。

このソースコードを、以下ディレクトリに適当な名前で保存します。拡張子は .json にして下さい。

~/.config/karabiner/assets/complex_modifications/

設定ファイルを配置できたら、Karabiner-Elementsアプリの「Complex Modification」タブを開いて「Add rule」ボタンを押します。

そうしたらさっき追加した設定が表示されているので、「Enable」ボタンを押します。

以上で適用完了です。テストして下さい。

ソースコード

ソース中の com.microsoft.VSCode の部分を書き換えれば任意のアプリのみ適用するようにできます。 カンマ区切りで複数アプリも指定できます。

"bundle_identifiers": ["com.microsoft.VSCode", "com.apple.Safari"]

アプリのbundle identifiers(識別名的なやつ)は、Karabiner-EventViewerアプリで調べられます。


以下が設定のソースコードです。長いので改行ためらっていてキモいかもですが自分で整形して下さい。

{
    "title": "vscode用",
    "rules": [
        {
            "description": "vscode:fnキーを標準のfnキーとして使う(F1〜F12)",
            "manipulators": [
                {
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f1"},
                    "to":  [{"key_code": "f1"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f2"},
                    "to":  [{"key_code": "f2"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f3"},
                    "to":  [{"key_code": "f3"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f4"},
                    "to":  [{"key_code": "f4"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f5"},
                    "to":  [{"key_code": "f5"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f6"},
                    "to":  [{"key_code": "f6"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f7"},
                    "to":  [{"key_code": "f7"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f8"},
                    "to":  [{"key_code": "f8"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f9"},
                    "to":  [{"key_code": "f9"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f10"},
                    "to":  [{"key_code": "f10"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f11"},
                    "to":  [{"key_code": "f11"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f12"},
                    "to":  [{"key_code": "f12"}]
                },

                {
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f1", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "display_brightness_decrement"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f2", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "display_brightness_increment"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f3", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"key_code": "mission_control"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f4", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"key_code": "launchpad"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f5", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"key_code": "illumination_decrement"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f6", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"key_code": "illumination_increment"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f7", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "rewind"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f8", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "play_or_pause"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f9", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "fast_forward"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f10", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "mute"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f11", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "volume_decrement"}]
                },{
                    "type": "basic",
                    "conditions": [{"bundle_identifiers": ["com.microsoft.VSCode"], "type": "frontmost_application_if"}],
                    "from": {"key_code": "f12", "modifiers": {"mandatory": ["fn"]}},
                    "to":  [{"consumer_key_code": "volume_increment"}]
                }
            ]
        }
    ]
}

以上。

参考

公式ドキュメント:

karabiner-elements.pqrs.org

とにかく日本語:

qiita.com