【vscode】文字列やコメント内でスニペットを有効にする
【vscode】マークダウンのコードブロックにファイル名を表示する
Visual Studio CodeのMarkdownのプレビュー機能にて、コードブロック(code block)にファイル名を表示するには、以下の拡張機能を導入します:
使い方
マークアップの方法は、以下のように、言語名のあとにコロン:
で区切ってファイル名を書きます:
~~~css:./hoge/style.css body { color: #abc; } ~~~
※はてなブログだと、コードブロックの中でバッククォート`
を3つ書くことができなかったので、代わりにチルダ~
で書いています。
ちなみに、コードブロックにはバッククォートが一般的ですが、代わりにチルダも使えます。
これは余談ですが。
上記の拡張機能の標準スタイルでは、以下のようにプレビューされます(右側)。
言語名指定なしだとうまくプレビューされないので、シンタックスハイライトが不要の場合は適当にtxt
とかを指定しておきましょう。
余談
なお、上で少し書いた通り、コードブロックのマークアップにはバッククォート`
の代わりにチルダ~
を用いることもできます。
そのおかげで、上の画像の4つめのコードブロックの例のように、ファイル名(パス)に~
を含めると、エディタ中のシンタックスハイライト(syntax highlighting)が乱れます。
該当行のトークンを表示していますが、期待通りになっていないのがわかります。
ちなみに、スコープインスペクタを表示するには、cmd + P
(ctrl + P
on windows)で表示される検索窓にDeveloper: Inspect Editor Tokens and Scopes
と入力すれば見つけられます。
標準ではキーバインドは用意されていません。
参考。
実際、vscode標準搭載(built-in)のmarkdownのsyntax設定のソースを見てみると、コードブロック開始は以下のような正規表現でキャプチャされています:
"fenced_code_block_css": { "begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(css|css.erb)((\\s+|:|,|\\{|\\?)[^`~]*)?$)",
ファイル名にマッチングする箇所は[^`~]*
となっているので、`
と~
は含められないことがわかります。
このソースは以下のリポジトリで見ることができます:
もう少し余談
vscode自体がJavaScriptで作られているので、vscodeで使われているmarkdownパーサももちろんJS製です。 つまり、markdown-itですね。
はじめに紹介した「Markdown Named CodeBlocks」はvscodeの拡張機能ですが、やっていることとしてはmarkdown-it用に作られた拡張機能をvscodeでも使うように指定しているだけです。
vscode拡張機能「Markdown Named CodeBlocks」のリポジトリ:
この箇所にマッチングパターンが書いてありますね。
以下、抜粋して少し修正したものです:
const match = arr[0].match(/^([^:\n]+)?(:([^:\n]*))?([^:\n]*)?$/); data.langName = match[1] || ""; data.fileName = match[3] || "";
最後の余談
以下のドキュメントによれば、vscodeのmarkdown拡張機能を作るには、markdown-itの拡張機能を持ってくるだけでいいそうですね。
まあ、自分で何か作るとなったら、この記事で何度も紹介している「Markdown Named CodeBlocks」のソースを参考にするといいかもですね。
以上です。
【Chrome】リーダーモードを使う
Safariのように、Chromeでもリーダーモードを使えるようにします。
むしろChrome以外のブラウザ(Safari、Firefox、Edge)では標準で使えます。
Chromeがだけそうでないのは、Googleが広告企業だからでしょうか?
環境
% date 2022年 8月26日 金曜日 22時52分12秒 JST
Chromeのバージョン:
104.0.5112.101(Official Build) (x86_64)
方法
アドレスバー(URLが表示されている場所)にchrome://flags
と入力し、エンターを押下します。
すると隠し設定?のページが表示されるので、Enable Reader Mode
と検索します。
「Enable Reader Mode」の項目が表示されますので、右のボタンみたいなプルダウンから「Enabled」を選択します。
設定を変更すると、ウインドウ下部に「Relaunch」ボタンが表示されるので、クリックしてChromeを再起動します。
その後、何かしらの記事サイト(例えばこのブログ)をChromeで開くと、アドレスバーの右側にリーダーモードのアイコンが表示されるので、クリックすればリーダーモードで表示してくれます。
以上。
あとがき
chromeのリーダーモードだと、はてなブログですらまともに表示されないね(埋め込みリンクとか)。
safariの方がきれいにちゃんと表示される。
ウインドウズだとSafariが使えないので毎日が苦しい。
firefoxに乗り換えようかな
参考
【SVN】無視リストとバージョン管理外
TortoiseSVNクライアントで「無視リスト」と「バージョン管理外」のフィルターがあるので、何が違うのかと思った。
無視リストは、svnの設定ファイルやフォルダのプロパティで無視するように指定されたファイルやフォルダのこと。
バージョン管理外は、まだ一度もコミットされていない、つまり新規作成したファイルやフォルダのこと。
無視リスト
ローカル設定(常に無視するパターンのリスト)
svnの設定は、%APPDATA%\Subversion\
にあるconfig
という名前のファイルに記載されている。
%APPDATA%
はC:\Users\%username%\AppData\Roaming
の意味なので、そのままエクスプローラのパス窓に貼り付けてOK。
配置場所からもわかるように、この設定はローカルにしか適用されない。
また、逆に言えばローカル環境全体に適用されるので、チェックアウトしているプロジェクトごとに設定を変更したりすることはできない。
無視リストに追加したいファイルやフォルダは、config
ファイルの[miscellany]
の下にあるglobal-ignores
に指定する:
[miscellany] global-ignores = .DS_Store *.dll *.exe bin .git .vscode
名前の指定には、以下のワイルドカードが使える:
*
:0文字以上の任意の文字列にマッチ?
:任意の1文字にマッチ[...]
:鍵括弧で囲まれた文字のうちの1文字にマッチ。ハイフン-
で範囲も表現できる([AGm-p]
はA, G, m, n, o, p
にマッチ)。
複数項目は半角スペース or 改行で区切る。
なので、1行で書かなくてもいい:
global-ignores = .DS_Store *.dll *.exe bin .git .vscode
残念ながら、パスは含めることはできない:
global-ignores = log/*.txt src/bin # NG
あと、#
から行末まではコメントとして扱われる。
フォルダのプロパティ
svn管理下のフォルダのプロパティには「Subversion」タブが追加されているので、そこでsvn:ignore
プロパティに無視したいファイルを指定する。
例えばsrc
フォルダのsvn:ignore
に*.exe
が指定されていると、src
フォルダ以下のexe
ファイルだけが無視される。
このとき、他のディレクトリ、例えばbuildTool
フォルダ以下のexe
ファイルは無視されない。
ただし、この設定はフォルダのプロパティを書き換えるので、その修正をコミットする必要があるため、 ローカル(自分)だけじゃなくプロジェクトをチェックアウトした人全員に影響が及ぶ。
プロパティの更新だけをコミットすることもできるらしい:
バージョン管理外
バージョン管理外のファイルやフォルダは、まだ一度もコミットされていないものというだけ。
つまり、新規作成したファイルは管理下に置かれていないので、コミットする際はバージョン管理外を非表示にするフィルターを外してチェックするのを忘れずに。
なお、すでにバージョン管理下に置かれているファイルは、後から追加した無視リストにマッチしても、途中からバージョン管理外になったりしないので注意。
後から管理対象から外したい場合は、下記記事を参照(TortoiseSVN):
後書き
Gitって便利ですよね(こなみ)
お仕事ではウインドウズだしSVNだしで毎日がつらたにえんです。
無視リストにパス指定できないのはgmすぎる...
TortoiseSVNもクソ使いにくいし(GitHub Desktopと比べて)
でもSVNはバイナリファイル(画像やエクセルとか)の管理に自信があるようなので、それはGitよりいいところですかね(そもそも論は置いといて)。
まあ、ローカルではGitも併用してるんですけどね。機能単位じゃなくて作業単位でコミットしたいよね。
参考
node.jsでMySQLを使うときは、hostにはlocalhostじゃなくて127.0.0.1を指定する【MySQL 8】
環境
% sw_vers ProductName: macOS ProductVersion: 12.4 BuildVersion: 21F79 % node -v v18.4.0 % mysql --version mysql Ver 8.0.30 for macos12.4 on x86_64 (Homebrew) % brew -v 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)
概要
MySQLの設定ファイルmy.cnf
に以下の記載
bind-address = 127.0.0.1
がある場合に、node(のmysql2
パッケージ)でhost
にlocalhost
を指定して接続しようとすると失敗します。
なので、localhost
ではなく、直接127.0.0.1
を指定します。
const mysql = require('mysql2'); const connection = mysql.createConnection({ host: '127.0.0.1', // localhostだとダメ user: 'root', database: 'hoge' });
調べたこと
特にHomebrewでMySQLをインストールした人がこの問題に直面しているかと思います。
HomebrewでMySQLをインストールすると、自動で設定ファイルmy.cnf
が作成されます:
% cat /usr/local/etc/my.cnf # Default Homebrew MySQL server config [mysqld] # Only allow connections from localhost bind-address = 127.0.0.1 mysqlx-bind-address = 127.0.0.1
コメント文からもわかるように、bind-address
にIPアドレスを指定すると、そのアドレス以外からのアクセスを禁止します。
基本的に、127.0.0.1
にはlocalhost
というホスト名が設定されています:
% cat /etc/hosts ## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost
なので、上記のようにbind-address
の設定がされていても、localhost
からでもアクセスできるはずです。
実際、ターミナルからであれば、localhost
でログインできます:
% mysql.server start Starting MySQL .. SUCCESS! % mysql -u root -h localhost Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 14 Server version: 8.0.30 Homebrew 略 mysql>
ところが、nodeの方では、ホスト名にlocalhost
を指定してMySQLに接続しようとすると失敗します。
下記内容のファイルをtest.js
という名前で保存:
const mysql = require('mysql2'); const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: '' }); connection.query( 'SELECT 1 + 1', function(err, results) { console.log(results); } ); connection.end();
実行してみると、エラーが出る:
% node test.js undefined node:events:515 throw er; // Unhandled 'error' event ^ Error: connect ECONNREFUSED ::1:3306 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1237:16) Emitted 'error' event on Connection instance at: at Connection._notifyError (/Users/hoge/test/node_modules/mysql2/lib/connection.js:236:12) at Connection._handleFatalError (/Users/hoge/test/node_modules/mysql2/lib/connection.js:167:10) at Connection._handleNetworkError (/Users/hoge/test/node_modules/mysql2/lib/connection.js:180:10) at Socket.emit (node:events:537:28) at emitErrorNT (node:internal/streams/destroy:151:8) at emitErrorCloseNT (node:internal/streams/destroy:116:3) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) { errno: -61, code: 'ECONNREFUSED', syscall: 'connect', address: '::1', port: 3306, fatal: true } Node.js v18.4.0
上記コードのlocalhost
部分を127.0.0.1
に置き換えます:
// host: 'localhost', host: '127.0.0.1',
再度実行してみると、ちゃんとクエリが実行されました:
% node test.js [ { '1 + 1': 2 } ]
これは奇妙ですね。mysql2
パッケージがブラックボックスなのでこれ以上何とも言えません。
node + MySQLの解説記事を見ていると、ほとんどの記事でhost: 'localhost'
と書いています。
おそらく、それでクエリ実行できているのは、my.cnf
にbind-address
の記載がないからでしょう。
あるいはバージョンの違いでしょうか。そこまでは調べられていません。
とにかく、HomebrewでMySQLをインストールするとmy.cnf
にbind-address
の設定が自動で作成されてしまいますので、その設定をコメントアウトするか、host
に直接127.0.0.1
を指定するかのいずれかの対応が必要になります。
以上。
補足
"mysql2"パッケージ
nodeでMySQL接続するためのパッケージですが、mysql
ではなくmysql2
を使っているのは、前者がMySQL 8系に非対応だからです。
私はそもそも初心者で何も知らないのですが、mysql2
はmysql
と同じように使えるらしいです(メソッド名とかが同じ?)。
my.cnfの場所
my.cnf
が配置されうる場所は以下のようにして調べられるらしいです:
% mysql --help | grep "/my.cnf" /etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf
HomebrewでMySQLをインストールしたときに作成されるのは/usr/local/etc/my.cnf
のみです。
他の3つもcat
してみましたが、いずれもファイルが存在していませんでした。
なお、既に/usr/local/etc/my.cnf
が存在している状態で、brew install mysql
したときは、/usr/local/etc/my.cnf
に変更は加わりません。
なので昔にMySQLの環境を作っていた人は、Homebrewからインストールし直しても上記問題には気がつかなかったかも知れません。
ちなみに、brew uninstall mysql
してもこの設定ファイルは消去されないので、いらなくなったら手動で削除して下さい:
rm /usr/local/etc/my.cnf
参考
MySQL 8系ではmysql
ではなくmysql2
を使わないとダメだと気付かせてくれたサイト
mysql2
パッケージ
同様のエラーに対し試行錯誤している記事。これ読んで下さい
インストールしたMySQLを完全に消したい記事。いつか必要になるかも
おすすめクリップボード管理ツール「Clibor」
フロントエンドで完結するテンプレートエンジンを作った?【JavaScript】
テンプレート言語は便利だけど、いちいちサーバーでレンダリングしないと使えないのがアレ。
もちろん、サーバー側で動的にHTMLを作るからこそ意味があるのだが、APIでデータ(今日の天気とか?)を取ってきて表示をif文で分岐させる、みたいな使い方ならフロント側だけで十分だなと思った。
というわけで、フロントエンドで完結するテンプレートエンジンを作った。
と言っても、変数定義と変数展開の機能しか実装していないので、ただのおもちゃです。 if文も無いよ。
フロントではJavaScriptしか動かないので、それで作りました。
使い方
nyaa.js
を読み込む:
<script src="./nyaa.js"></script>
読み込んだHTML内で、変数の定義と展開ができる:
<!-- 変数定義 --> {% assign nyaa = にゃあ! %} <!-- 変数展開 --> {{ nyaa }}
その他の機能は皆無です。
例
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="./nyaa.js"></script> <title>テストにゃ</title> </head> <body> {% assign hello = 'こんちわ!' %} {% assign good_night = "おやすみ" %} {% assign url = https://google.com %} {% assign nyaa = にゃあ %} <h1>テスト</h1> <p>ほげ</p> <p>にゃあ</p> <p>{{ hello }}</p> <p>{{ hello }}で始まり{{ good_night }}で終わる。</p> <p>{{ good }}</p> <p><a href="{{ url }}">Google</a>です。</p> </body> </html>