# About me tkancfというユーザ名で登録していることが多いです。 よく使ってるアイコン↓ ![tkancf](https://i.gyazo.com/a667d153340afb4c24ad28cb4805ca0a.png) ## 趣味 - プログラミング - コーヒー - Magic: The Gathering - 漫画 ## 仕事 - 2018/07 - 2022/07 - MSPの会社でクラウドインフラのエンジニア(運用・保守) - 2022/08 - 現在 - 上記エンジニアチームのプレイングマネージャー # 2022年の振り返り 年始すぐに書こうと思っていたのに大分経ってしまいましたが、今書かないと時期を逃しそうなので慌てて書きます。 ## 2022年の振り返り 主なイベントとしては - 5月から同棲 - 8月から仕事でマネージャー業をやることに - 11月に入籍 という感じに人生的に大きなイベントが複雑あった年でした。 妻と結婚しようと決めてから、諸々一気に進めたので後半は特に忙しい一年になりました。 ### 良かったこと #### 自炊をするようになった 一人暮らしと比較して、ちゃんと料理するようになりました。 誰かに食べてもらえると、モチベーションが違いますね。 #### 節約するようになった あまり計画的なお金の使い方はせずに、余った金を適当に貯めるみたいな生活をしていたんですが、結婚を期に資産管理をちゃんとするようにしました。 衝動買いの頻度を減らせたことが一番家計に効いてます。 #### 結婚できた ちょっと前までは結婚なんて考えられないような状況だったので、自分でもびっくりです。 末永く仲良くやっていきたいですね。 [https://twitter.com/tkancf/status/1594873686888222721?s=20&t=v_Ll0h92NT6eogk0Wr4JKA:embed] ### Motto #### インプット量 生活習慣などがガラッと変わったのもあり、インプットの時間をあまり取れなかったのが反省点です。 今の生活サイクルに慣れた部分はかなりあるので、少しづつ増やしていこうと思っています。 #### 仕事への取り組み もうちょっと色々できたな〜と思う部分はあるので、要改善ですね。 これについては、会社での目標をたててるのでそれを頑張る方針でやっていきます。 #### 技術的なアウトプット 雑記はいくつか書いたんですが、技術ブログをあまり書けませんでした。 来年はもう少しかきたいです。 ## 2023年の目標 - 貯金する - 大きめの買い物があるので、それを除いてもプラスになるようにする - 本を読む - 最近読めてなくて、溜まってるので月に1冊は読む - ブログを継続して書く - 技術ブログを優先的に書きます 以上、こんな感じで今年もがんばります。 # 2023年の振り返り ![Title Image](https://i.gyazo.com/c1486102d84730f1d1a744ac70455841.png) 年末なので、今年1年を振り返ってみます。٩( ᐛ )و ## 作ったもの・書いたもの等 ### ブログ 今年は下記20件のブログを書きました。今年の4月にブログをはてなブログから、Astro + Cloudflare Pagesに移行してから、ブログを書く頻度が上がりました。去年は年間10件に満たなかったので、今年の20件は大幅な増加です。 増えた理由としては、普段のメモの取り方を変えたこと、Twitterをほぼやめたことでブログについて考える頻度を増やせたのかなと思っています。 - [Self-hosted LiveSyncとFly.ioを使って、Obsidianのメモを無料で同期する](https://tkancf.com/blog/sync-obsidian-notes-free-self-hosted-livesync-flyio/) - [CloudFlare PagesでホストしているAstro.jsブログでリダイレクトする方法](https://tkancf.com/blog/setting-up-redirects-astro-cloudflare-pages/) - [VimのCTRL-K を理解する](https://tkancf.com/blog/understanding-vim-ctrl-k-space/) - [ISUCON13に参加しました。最終スコアは8654でした](https://tkancf.com/blog/isucon13/) - [tofu65キーボードを買いました](https://tkancf.com/blog/tofu65-keyboard-review/) - [SvelteKitでカードゲームのプロキシメーカーを作りました](https://tkancf.com/blog/created-a-card-game-proxy-maker-with-sveltekit/) - [GitHub Mobile + GitHub issueでメモが良い感じ](https://tkancf.com/blog/github-mobile-and-issue-as-memo/) - [$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) を理解する](https://tkancf.com/blog/understanding-bash-source/) - [iTerm2でベルの音を止める](https://tkancf.com/blog/mute-iterm2-bell/) - [Astroのバージョンをv2からv3に上げました](https://tkancf.com/blog/update-astro-v2-to-v3/) - [GitHub ActionsでPulumiをCI/CDしてみた](https://tkancf.com/blog/trying-cicd-with-pulumi-using-github-actions/) - [Pulumi+GoでCloudflareのDNS既存リソースをインポートして管理してみた](https://tkancf.com/blog/managing-and-importing-existing-cloudflare-dns-resources-pulumi-go/) - [cdコマンドを拡張したzoxideコマンドが便利](https://tkancf.com/blog/zoxide-a-convenient-extension-of-the-cd-command/) - [CloudFlare Workers、Cloudflare D1、HonoでLINE botを作りました](https://tkancf.com/blog/creating-line-bot-with-cloudflare-workers-d1-and-hono/) - [『SOFT SKILLS ソフトウェア開発者の人生マニュアル』を読み返しました](https://tkancf.com/blog/reading-soft-skills-the-software-developers-life-manual/) - [Raycast のクリップボードヒストリーは Command+.で結合できる](https://tkancf.com/blog/raycast-clipboard-history-merge-with-cmd-period/) - [Commandキーをtmuxのプレフィックスキーとして使う方法 on Iterm2](https://tkancf.com/blog/command-as-tmux-prefix-key/) - [AstroとCloudflare Pagesでブログを作成しました](https://tkancf.com/blog/astro-and-cloudflare-pages-blog-creation/) - [ブログをAstroへ以降しました](https://tkancf.com/blog/first-post/) - [過去に別のブログで書いた技術記事まとめ](https://tkancf.com/blog/past-technical-articles-collection/) ### GitHub GitHubは例年特に何もしていないのでまっさらなんですが、今年は以前のブログで触れた通り、ブログの記事管理をAstroに変更したり、Cloudflare WorkersでLINE botの作成などを行いそれなりに草が生えました。 下記が2022年の草 ![GitHub Contribution 2022](https://i.gyazo.com/7da2fbabdbcf2d5857bb12f1d8d7cd47.png) そして、これが今年(2023年)の草です。 ![GitHub Contribution 2023](https://i.gyazo.com/17f0aeabdd6fc5068352a875e307647e.png) 4月にブログを移行してからしばらくは、ブログの記事を書くためにコミットできていましたが、5〜10月にほぼ何もできませんでした。 10月中頃に結婚式が終わって一段落して以降の10月末頃から、またコミットできるようになりました。来年は年間通してコミットし続けられると良いですね。 ### 作ったもの 以下プライベートで作っていたものです。 - カードゲームのプロキシメーカー - SvelteKit + Cloudflare Pages - 個人的に欲しい機能を満たすものが無かったので自作しました - ブログも書きました: [SvelteKitでカードゲームのプロキシメーカーを作りました](https://tkancf.com/blog/created-a-card-game-proxy-maker-with-sveltekit/) - LINE bot - Cloudflare Workers + Cloudflare D1 + Hono - Cloudflare Workersのお試し兼、妻とのやり取りで普通に欲しかったので作りました。今も少しずつ改良しながら便利に使っています - ブログも書きました: [CloudFlare Workers、Cloudflare D1、HonoでLINE botを作りました](https://tkancf.com/blog/creating-line-bot-with-cloudflare-workers-d1-and-hono/) - MoneyForwardのデータをもとに、色々とグラフを作成して表示するためのツール - Go + Google Spreadsheet + Google Sites - MoneyForwardのデータをGoogle Spreadsheetにエクスポートして、Google Sitesで表示するためのツール - 毎月1回、家計簿の振り返りを行っていますが、MoneyForwardプレミアムのグラフだけだと、振り返りに必要な情報が足りないので作りました - Google Sitesは簡単にアクセス権限を設定できるし、Google Spreadsheetのグラフを並べたページを作成出来るので便利ですね - ISUCON用便利スクリプト - ISUCONのために作ったスクリプト郡 - [tkancf/isucon-tools](https://github.com/tkancf/isucon-tools) - ISUCON13では勉強不足を感じたので、次回に向けて引き続き育てていきたいです 全体的に自分の欲求を満たすために作ったものが多いですね。 今は副業もしておらず、仕事でプログラミングする機会もほぼ無いのでプライベートで手を動かしていないと何も出来なくなりそうで恐怖しています。引き続き精進していきたいです。 ## 仕事 2022年の8月から仕事でマネージャー業をやることになり、1年と少し経過しました。 業務内容としてはチームメンバーのマネジメントが職務の中心で、ピープルマネジメントが軸になっています。 1on1、評価、採用、目標設定、キャリアパス、チームビルディング、チームの課題の発見・整理・解決が良くある業務です。 エンジニアリングマネージャーという区分が一番近いのかなと思っています。 プレイヤーをやっていた時と比べると、時間の区切り方が細かくなっておりバタバタしていると感じていましたが、流石に1年経つと慣れてきました。 プレイヤーとしての時間区切りが数時間単位だったのに対して、マネージャーとしての時間区切りは15分から1時間を単位にして会議・1on1・タスクを切り替えていくので、時間の区切り方が細かくなっていると感じています。 採用面接など、まだ慣れない部分もあって、チームメンバーから偶に忙しそうと言われることがあるのが反省点なので、余裕があるように振る舞いたいですね。 最近、[『エンジニアリングマネージャーのしごと ―チームが必要とするマネージャーになる方法』](https://amzn.to/47ncyHk)という本を読んでいて、自分のやっていることが本に書いてあることと似ているなと思いました。まだ読んでいる途中ですが、読み終わったらブログにまとめたいと思います。 ## プライベート ### イベント 大きなイベントとしては、今年は結婚式を挙げました。妻と二人で相談しつつ準備を進め、無事に挙げることが出来ました。 式の2, 3ヶ月前になると、やらなければいけないタスクが多くて大変でしたが、挙げて良かったなと思っています。 手書きが必要なタスクを苦手としているんですが、所々それらのタスクが必要で消耗しました。 結婚式の準備に力を取られすぎて、月に一度妻とやっている1on1を少しサボってしまったので、来年は忘れずにやりたいです。 ### 生活 結婚式以外だと、今年は例年と比較して体調を崩すことが多かったです。リモートワークになってから、ベースの体力がなくなっている自覚はあるので筋トレで体力を増やしたいです。 今年は普段のメモ環境構築の検討・変更を繰り返していました。 11月頃にObsidianに落ち着いたんですが、直近2ヶ月ぐらいは良い感じのリズムを作れているので、引き続きやり方を改善しつつ、アウトプットに繋げていけると良いなと思っています。 ## 2024年について 下記はやりたいなと思っています。 - ISUCON14に向けての準備 - ISUCON13では勉強不足を感じたので、単純に練習量を増やしていきたいです - ブログを継続して書く - 今年は20件書けたので、来年はそれ以上に書けるようにしたいです - マネジメント関連の本を読む - 今は『エンジニアリングマネージャーのしごと ―チームが必要とするマネージャーになる方法』を読んでいますが、他にも気になる本はいくつかあるので読んでいきたいです 今年も1年お世話になりました。来年もよろしくお願いします。٩( ᐛ )و # 個人メモ用のサイトを作ってみた メモ用のツールとしてObsidianとかNotionとか流行ってる中、何が良いのか試しつつメモの管理手法について調べてました。 PKM(Personal Knowledge Management)といって結構色々と手法があるようで、有名なものにZettelkasten、LYT、エバーグリーンノートなんかがあるようです。 一通り有名どころの手法を知ったので、それを活かしつつ公開できるサイトがあると良いな〜と思ったのでこのブログとは別で用意してみました。 作ったサイトは TKM というサイトになってます。 2024-08-05追記: ブログとうまく使い分けられなかったので公開やめました。 HonoのSSGを利用してCloudflareで公開たんですが、ほぼ本ブログのコード使い回しなので制作時間は1時間未満とかです。 Backlinksという、ページ末尾にそのページへリンクされているページの一覧を表示するようにした点だけがこだわりポイントです。 現状は作ったばかりなので数十程度のメモしか置けてないですが、ちょっとずつ育てていけたら面白いかなと思ってます。 ちなみにメモツールは結局Neovimになってます。(Vimのない生活にはどうやっても馴染めなかったよ...) [epwalsh/obsidian.nvim](https://github.com/epwalsh/obsidian.nvim) というプラグインがObsidianのようにメモを作れるNeovimのプラグインになっており、ObsidianもVimも好きな私にはめちゃくちゃフィットしました。おすすめです。 自分のメモの作り方に合うようにちょっとしたプラグインも書いてみたりしました。 久々にVimの設定いじったので満足です。しばらくこの環境で遊んでみようと思います。 # 2024年の振り返り もう2月なんですが、振り返ります。 ## 作ったもの・書いたもの等 [はてなブックマークからOmnivoreに移行するためのツールを作ったり](https://zenn.dev/tkancf/articles/c323bf1c64eafb)、[ブログをAstroからHonoのSSGに移行したり](blog/blog-migration-astro-to-hono.md)と色々やれてました。 5月中頃に妻の妊娠が分かり、それ以降バタバタしていたら何もできなくなってしまったのが残念ですが、12月に無事に産まれたのでもう少し育児が落ち着いたら色々と再開したいと思います。 ### GitHub 下記が2023年の草 ![GitHub Contribution 2023](https://gyazo.com/1cbdc29b57b91024b1ff8b1fc21d465e.jpeg) そして、これが今年(2024年)の草です。 ![GitHub Contribution 2024](https://gyazo.com/0dfc2849822cb089a26558e46083ecd2.jpeg) 前半に頑張りを感じますが、後半の失速具合がすごいですね。 ## 仕事 子供が生まれたら育休に入りたいということで引き継ぎをする必要があり、12月前は過去最高に忙しかったです。 育休に入るのとあわせて、現チームのマネージャーを引き継いで異動希望を出していた別部署への移籍もすることになったので、てんやわんやでした。 久々にマネージャー職から離れて、手を動かす仕事の比率が増えそうなので、気合い入れてやっていこうと思います。 ## プライベート ### イベント 大きなイベントとして、今年は12月に子供が産まれました。 色々と分からんことだらけで困ったりしてますが、会社も快く育休取らせてくれたりと環境には恵まれていると思ってるので頑張りたいですね。 最初の1ヶ月はドッタンバッタン大騒ぎって気持ちでしたが、2ヶ月過ぎてから少し落ち着いてきた気がします。 子育て、なんとなく障害対応に似てる気がするのでバタバタしてるときは、やばいアラート発生したな!って思いながら対応してます。 初めて💩が膝に飛んだときのCRITICALアラート感すごかったです。(今は慣れました。) ### 生活 仕事の残業時間が多い月が増えていた事もあってスーパーの惣菜で終わりみたいな日が多めでした。 12月以降はほぼ毎日自炊出来てるのでいい感じです。クラシルのYouTubeは神。 あともうちょっとだけ、運動量増やしたいです。 概ね健康に生きれたので、継続したいですね。 ### 趣味 Magic: The Gatheringをしてました。 ついにレガシーに手を出してしまい、緑ポストと青単デルバーを組んでしまいました。 いつかデュアランドに手を出してしまいそうで怖いですよ。 2025年はもっとリミテッドやりたいな〜と思っています。 ## 2025年の目標 下記はやりたいなと思っています。 - ブログ書く量を増やす - 子育て頑張る - 筋トレを継続してやる 引き続きよろしくお願いします。 # blink.nvimでobsidian.nvimの補完を利用する方法 obsidian.nvimではリンク先ファイルの補完にnvim-cmpの補完ソースを提供していて、それ以外の保管ソースは用意されていません。 ただ、blink.nvimでは、`saghen/blink.compat`を利用する事でnvim-cmp補完ソースを使えるので、obsidian.nvimの補完が使えます。 どう設定すれば良いかわからず、しばらく試行錯誤したのでメモとして置いておきます。 ## 設定例 最終的に下記設定にすれば、いい感じになります。 ```lua return { { 'saghen/blink.cmp', version = false, dependencies = { { "rafamadriz/friendly-snippets" }, { "saghen/blink.compat", lazy = true, version = false }, { "https://github.com/epwalsh/obsidian.nvim" }, }, ---@module 'blink.cmp' ---@type blink.cmp.Config opts = { -- 'default' for mappings similar to built-in completion -- 'super-tab' for mappings similar to vscode (tab to accept, arrow keys to navigate) -- 'enter' for mappings similar to 'super-tab' but with 'enter' to accept -- See the full "keymap" documentation for information on defining your own keymap. keymap = { preset = 'super-tab' }, completion = { list = { selection = { preselect = false, auto_insert = false } } }, appearance = { -- Sets the fallback highlight groups to nvim-cmp's highlight groups -- Useful for when your theme doesn't support blink.cmp -- Will be removed in a future release use_nvim_cmp_as_default = true, -- Set to 'mono' for 'Nerd Font Mono' or 'normal' for 'Nerd Font' -- Adjusts spacing to ensure icons are aligned nerd_font_variant = 'mono' }, -- Default list of enabled providers defined so that you can extend it -- elsewhere in your config, without redefining it, due to `opts_extend` sources = { default = { "obsidian", "obsidian_new", "obsidian_tags", "lsp", "path", "snippets", "buffer" }, providers = { obsidian = { name = "obsidian", module = "blink.compat.source", }, obsidian_new = { name = "obsidian_new", module = "blink.compat.source", }, obsidian_tags = { name = "obsidian_tags", module = "blink.compat.source", }, }, }, }, opts_extend = { "sources.default" } } } ``` `saghen/blink.compat` をdependenciesに入れて、sourcesのprovidersにobsidianのソースを定義、それをsources.defaultに入れてあげればOKでした。 [obsidian.nvimのこのIssue](https://github.com/epwalsh/obsidian.nvim/issues/770)にQ&Aと関連する修正commitが入っています。 ## 試行錯誤メモ - [blink.nvimでobsidian.nvimの補完を利用する](https://note.tkancf.com/20250110153217) ## 参考資料 - [Support blink.nvim Autocomplete · Issue #770 · epwalsh/obsidian.nvim](https://github.com/epwalsh/obsidian.nvim/issues/770) - [dotfiles/.config/nvim/lua/plugins/blink.lua at edae7c4933300faf024b6cf6585085351840bba1 · rbmarliere/dotfiles](https://github.com/rbmarliere/dotfiles/blob/edae7c4933300faf024b6cf6585085351840bba1/.config/nvim/lua/plugins/blink.lua) # snacks.nvimを試したらいい感じ 便利なNeovimプラグインの詰め合わせセット的なプラグインのsnacks.nvimを試しました。 詰め合わせセットですが、部分的に導入することが可能なので「何を入れたのかよく分からなくてモヤモヤする」みたいな状況になりづらくなっています。 各プラグインの完成度がとても高く便利なのでかなりおすすめです。 私は個人的にpickerとScratch bufferで心を掴まれました。 含まれているプラグインの一覧は[snacks.nvimのREADME](https://github.com/folke/snacks.nvim)を見たほうが良いと思うので、個人的に試して良かったプラグインとその推しポイントを紹介します。 ## [picker](https://github.com/folke/snacks.nvim/blob/main/docs/picker.md) ![pickerの画像](https://gyazo.com/639a3c1cf01260d97d8f2837e563fbc9.jpeg) fuzzy finderです。Neovimのfuzzy finderには、他にもtelescope.nvim、fzf-luaなど沢山あるのでどれを選ぶかは好みになってくるんですが、私はsnacks.nvimのpickerが好みでした。 今まではtelescope.nvimを利用していたんですが、デフォルトで提供されているソースの見た目が私好みでした。 - 見た目の違い - telescope.nvimのcommand_history - ![telescope.nvimのcommand_history](https://gyazo.com/950d534520951ef64497fff3f8eb3de0.jpeg) - snacks.nvim pickerのcommand_history - ![snacks.nvim pickerのcommand_history](https://gyazo.com/8961a742d06f8d4dab73f1f37bb9925c.jpeg) 見た目以外の部分では、snacks.nvimの[bufdelete](https://github.com/folke/snacks.nvim/blob/main/docs/bufdelete.md)との組み合わせでバッファの絞り込み画面から、`dd`とするだけでバッファの削除が可能です。 これまでの`:bd`を連打していた生活からはおさらばできそうです。 ![snacks.nvimのbufdelete](https://i.gyazo.com/d3204992c64085056a82269571c5e336.gif) ## [explorer](https://github.com/folke/snacks.nvim/blob/main/docs/explorer.md) ファイルエクスプローラーです。 個人的にはこれまでoil.nvimを使っていて、不満は無いんですがファイルエクスプローラーに絞り込み機能が付属しているのは今まで見たことが無かったので紹介します。(私が知らないだけで、他プラグインもあるかもしれないです) 下記のようにファイルエクスプローラーに絞り込み機能がついており、検索文字をファイル名に含むものだけ一覧表示可能です。 変わらずメインはoil.nvimを使うつもりですが、用途ごとに使い分けるのも良さそうだなと思っています。 ![snacks.nvimのexplorer](https://gyazo.com/32d0cb1e95d6101669b209e21f114a61.jpeg) ## [indent](https://github.com/folke/snacks.nvim/blob/main/docs/indent.md) 現在のインデントの深さに対応して線を引いてくれるプラグインです。 この手のプラグイン、なんとなく入れたことが無かったんですが、有効にするだけなら敷居が低いので入れてみました。入れてみたらめっちゃ便利ですね。 デフォルトだと線が描画されるときにアニメーションが入ってオシャレなんですが、個人的にはさっさと描画されて欲しいのでOFFにしています。 ```lua opts = { indent = { enabled = true, animate = { enabled = false } } } ``` ![snacks.nvimのindent](https://gyazo.com/1968dd50e22f6c05f19638bcd4b04f24.jpeg) ## [lazygit](https://github.com/folke/snacks.nvim/blob/main/docs/lazygit.md) Neovim上でLazygitを触れるようにするプラグインです。 Neovimのカラースキームで起動してくれます。オシャレ!! ![snacks.nvimのlazygit](https://gyazo.com/b3d361058206c578c863e3ef5fca2d7d.jpeg) ## [scratch](https://github.com/folke/snacks.nvim/blob/main/docs/scratch.md) 現在開いているディレクトリをベースに、ちょっとしたコードやメモを書いておくことが出来て、luaのコードならそのまま実行ができます。 luaのコード実行が出来るのが、ちょっとNeovimの設定用にlua関数試してみるか...とかやってるときにかなり便利です。 ![snacks.nvimのscratch](https://gyazo.com/b90c07663e5023053341a96f90a12c32.jpeg) # このサイトでllms-full.txtを出力するようにした このサイト (https://tkancf.com/) でllms-full.txtを出すようにしました。https://tkancf.com/llms-full.txt からアクセス可能です。 ## llms.txt、llms-full.txtについて [The /llms.txt file – llms-txt](https://llmstxt.org/)に詳しいです。 ざっくり説明だと、llms.txtにサイト・コンテンツの概要、リンク集を用意。llms-full.txtにサイトの全コンテンツを用意してLLMで便利に使おうよってルールです。 ## 理由 ブログのデータを[Google NotebookLM](https://notebooklm.google.com/)、などに丸っと取り込んで活用できたら便利かな〜というのと、今後AIツールが増えていったときにペラ一のデータで存在していたほうが入力しやすいという状況が発生する機会が増えそうという予測で追加してみました。 ## 実装 このPRで[Add llms-full.txt by tkancf · Pull Request #58 · tkancf/tkancf.com](https://github.com/tkancf/tkancf.com/pull/58/files)追加しています。 現状、このサイトは[quartz](https://quartz.jzhao.xyz/)を使って作ってるんですが、そのquartzのビルドスクリプト内でllms-full.txtを生成してtxt形式で保存しているだけです。 ## お気持ち 各サイトでのスタンダードになったら、LLMへの情報入力で便利そうなので流行って欲しいな〜という気持ちです。 ## 参考 [このサイトで llms-full.txt を提供し始めた | Hirotaka Miyagi](https://www.mh4gf.dev/articles/llms-full-txt) # Commandキーをtmuxのプレフィックスキーとして使う方法 on iTerm2 ## はじめに tmuxのプレフィックスキーに最適なキーを探して数年が経ちました。 Vimのキーマップやターミナルのショートカットを考慮するとプレフィックスキーとして使える組み合わせってほぼ残って無いです。 (デフォルトのCtrl+bとか、shellでめっちゃ多用します) なので色々な組み合わせを試してきたんですが、最近MacだったらCommandキーをプレフィックスキーとして使えば良いのではと考えて設定してみたら結構いい感じです。 「Commandキー+何かのキー」をプレフィックスキーとして使うメリットには主に下記2点が挙がります。 - 押しやすい位置にある - ターミナルで動くツール(vim, bash, 他CLIツール類)とショートカットでバッティングすることが無い(多分) 親指で押せる位置にあるというのは、ターミナルで生活する者としては結構重要です。小指とかで押すCtrl等をプレフィックスキーとして使用すると小指が死んでしまいます。 Commandキー単押しでプレフィックスキーとして動作させることも可能ですし、 `Commandキー + '` をtmuxのpane分割キーとして設定すること等も可能です。 ## 前提 - 下記環境で動作確認を行っています。 - macOS Catalinaバージョン10.15.5 - iTerm2 Build 3.3.11 - tmux 3.0a ## 設定方法 iTerm2にはキーボードショートカットを自分で登録する機能が最初からついてます。 ショートカットを入力した際に色々なアクションを実行できるのですが、そんなアクションの中に "Send Hex Code" というアクションがあります。 その名の通りショートカットを入力した際にASCIIコードを送信してくれる機能です。 これを利用して、Commandキーを入力した際にtmuxのプレフィックスキーとして設定したキーのASCIIコードを送信してもらいます。 どのキーがASCIIコードの16進数で何に該当するのかは下記サイトをみると分かります。 ASCIIコード表: https://ja.wikipedia.org/wiki/ASCII ### tmux 側の設定 tmuxのprefix設定は何でも良いわけではありません。 tmuxでは `Ctrl-` をプレフィックスキーとして使うことが出来るのですが、上記 "send Hex Code" の機能ではASCIIコード表に載っている文字もしくは制御文字しか対応していません。 なので普段使わなさそうな制御文字をプレフィックスキーとして利用します。 ASCIIコードの制御文字とその説明はWikipediaみると分かりやすいです。 Wikipedia制御文字: https://ja.wikipedia.org/wiki/%E5%88%B6%E5%BE%A1%E6%96%87%E5%AD%97 私は `Ctrl + \` をtmuxのプレフィックスキーとして設定しました。 (制御文字としてはFile Separatorだそうです。) `.tmux.conf` の設定として書くなら下記のようになります。(エスケープするためにバッククォートが2つついてます。) ``` # prefix key set -g prefix C-\\ ``` ### iTerm2 側の設定 次にiTerm2側の設定です。 iTerm2のPreferencesから設定します。(Preferencesの開き方は`Commandキー + ,`) Preferences > Keys > Key Bindingsの左下の + ボタンからキーボードショートカットを新しく登録します。 私の設定を例にすると以下のようになります。 1. Preferences > Keys > Key Bindingsの左下の + ボタンを押す 2. Commandキーの単押しをプレフィックスキーとして使いたいので、 "Keyboard Shortcut" のところをクリックしてCommandキーを押す 3. Actionで "Send Hex Code" を選択する 4. Actionの下に入力欄が出るので、そこに先程プレフィックスキーとして設定した制御文字のASCIIコードを入力する - (私はFile Separatorをプレフィックスキーとして設定したので、そのASCIIコードである1cを入力します) 上記設定ができれば下記画像のようになるはずです。 ![Commandキーをプレフィックスキーとして設定できたときの画像](https://i.gyazo.com/a3622686f316808a6da999e7e290665b.png) ここまででCommandキーをプレフィックスキーとして利用できます。動作確認して終わりです。お疲れさまでした。 ### おまけ ここまでの設定の応用として、`Commandキー + '` をプレフィックスキーを押したあとで ' キーを押したと同様の動作(tmuxのデフォルト設定だとpaneの分割) をするようにしてみます。 1. Preferences > Keys > Key Bindingsの左下の + ボタンを押す 2. `Commandキー + '`をプレフィックスキーとして使いたいので、 "Keyboard Shortcut" のところをクリックしてCommandキーを押す 3. Actionで "Send Hex Code" を選択する 4. Actionの下に入力欄が出るので、そこに先程プレフィックスキーとして設定した制御文字のASCIIコードを入力し、半角スペースを入れて ' キーのASCIIコード(22) を入力します。 - (私はFile Separatorをプレフィックスキーとして設定したので、そのASCIIコードである1cを入力します) これで `Commandキー + '` をpane分割のショートカットとして登録できました。 この調子でよく使うtmuxの操作をショートカットとして登録すると便利です。私の設定は現在下記画像の様になっていました。 ![上記設定が全て完了した時の画像](https://i.gyazo.com/a8a03f684ccf587baa11d047596368b5.png) Commandキーをプレフィックスキーとして利用すると小指に優しいのでおすすめです。 良かったらぜひ試してみて下さいませ。 # AstroとCloudflare Pagesでブログを作成しました [Astro](https://astro.build/) を利用して[ブログ](https://tkancf.com)を作成しました。ホスト先には Cloudflare Pages を利用しています。 ## 選定理由 ### Astro Astro はコンテンツが豊富な Web サイトを構築するためのフレームワークです。 > **Astro was designed for building content-rich websites.** This includes most marketing sites, publishing sites, documentation sites, blogs, portfolios, and some ecommerce sites. [^1] [^1]: Why Astro?: https://docs.astro.build/en/concepts/why-astro/#content-focused 今回はブログを作りたかったので、静的サイトジェネレータをいくつか調べていました。 Hugo は以前に利用したことがありそれ以外を検討していたのですが、Astro は以下の点に魅力を感じたので選択しました。 - デフォルトで高速 - 実際にブログテンプレートで生成されるデフォルトのブログを Cloudflare Pages へデプロイすると、 [PageSpeed Insights](pagespeed.web.dev)で 100 点になります。 - React、Svelte などの UI フレームワークとインテグレーションが可能 - [example projects](https://astro.new/) に参考になりそうな例が豊富 ### Cloudflare Pages Astro では静的サイトが生成されるので、ホスト先の選択肢は豊富です。 GitHub Pages、Cloudflare Pages、Netlify、Vercel などがよく選ばれているようなので、その中で検討しました。 - GitHub Pages - Netlify - 上記 2 つは過去に利用したことがあるので保留 - 両サービス共、特に不満はないです - Vercel - 無料プランだと[商用利用(アドセンス含む)は不可](https://vercel.com/docs/concepts/limits/fair-use-policy#commercial-usage) なので NG - 今後広告入れるかは未定ですが念のため - Cloudflare Pages - 利用するドメインも Cloudflare で購入・管理しているので選定 ## 導入から公開までやったこと サイトは [GitHub へ公開](https://github.com/tkancf/tkancf.com)しているのでそのコミットを貼りつつ、どんなことをしたか書いていきます。 ### ブログテンプレートを生成 - コミット: https://github.com/tkancf/tkancf.com/commit/26013ad20e8d417468ddc53cbc49f690ea4ebd4f - 実行コマンド例 ```bash ❯ npm create astro@latest -- --template blog ╭─────╮ Houston: │ ◠ ◡ ◠ Let's make the web weird! ╰─────╯ astro v2.3.0 Launch sequence initiated. dir Where should we create your new project? ./blog ◼ tmpl Using blog as project template ✔ Template copied deps Install dependencies? Yes ✔ Dependencies installed ts Do you plan to write TypeScript? Yes use How strict should TypeScript be? Strict ✔ TypeScript customized git Initialize a new git repository? Yes ✔ Git initialized next Liftoff confirmed. Explore your project! Enter your project directory using cd ./blog Run npm run dev to start the dev server. CTRL+C to stop. Add frameworks like react or tailwind using astro add. Stuck? Join us at https://astro.build/chat ╭─────╮ Houston: │ ◠ ◡ ◠ Good luck out there, astronaut! 🚀 ╰─────╯ ``` ### 基本的な情報の更新 #### URL、サイトタイトルの変更 https://github.com/tkancf/tkancf.com/commit/eb4c2fa535b591b2d50ae0400952b3fa55cacb46 #### コピーライト部分の変更 Twitter、GitHub アカウントの URL を自分のものに変更 Prettier のフォーマットが働いてしまって diff がでかくなってます... https://github.com/tkancf/tkancf.com/commit/763fff1bc69d1a828b8c646a5da398ce7ce02df5 #### アバウトページの更新 https://github.com/tkancf/tkancf.com/commit/4ba74d011265211f14ff17201a1ddae7a9f6bc09 #### トップページの更新 https://github.com/tkancf/tkancf.com/commit/80ff54a1eda4d53e9db2f2c90d398042c26a2178 #### 画像ファイルの更新 https://github.com/tkancf/tkancf.com/commit/46673876dd7d41b8d08a49576155300cff64b702 ### .node-version ファイルを追加 この指定がない場合、デフォルトでは `12.18.0` が利用されるのですが、これだとビルドが失敗してしまうので `.node-version` ファイルに Node.js のバージョンを指定しておきます。 https://github.com/tkancf/tkancf.com/commit/80c890626dbd4742ecb83d9694343451069107b0 ### Cloudflare Pages で公開 Pages の画面から Create a project => Connect to Git => repository の選択 などを進めていくだけのぽちぽち作業。簡単です。 ### robots.txt の追加 テンプレートには robots.txt が存在していなかったので、本当に最低限のものを用意しました。 https://github.com/tkancf/tkancf.com/commit/9db9e7c09c78a7e0c00c81f92fcfb1795ff9295f ```txt User-agent: * Allow: / Sitemap: https://example.com/sitemap-index.xml ``` ### jpeg 画像を webp へ変換 jpeg 画像が重く PageSpeed Insights のパフォーマンスが 93 点になっていたため、webp へ変換しました。 https://github.com/tkancf/tkancf.com/commit/591fdc4d0df85b532434ce396ec123a726ee46dc 変換前の PageSpeed Insights の点数 ![PageSpeed Insightsで93点の画像](https://i.gyazo.com/4c8afae8ddc1a5ad2367aab37455d884.png) 変換後の PageSpeed Insights の点数 ![PageSpeed Insightsで100点の画像](https://i.gyazo.com/2f33199c706919774595dfb264e32abd.png) 変換後は無事 100 点になりました。 ## 終わりに こんな感じで簡単に公開することが出来ました。今後デザインの変更などもやっていこうかと思っています。 ブログ以外にも Astro を利用して作ってみたいコンテンツがあるので、色々遊びたいです。 また、Cloudflare Pages を調べる中で Cloudflare Workers というのがあるのを知れたので、これも試してみようと思います。 # ブログ記事一覧ページに、外部サイト記事も表示するようにしてみた ## 概要 Astroのブログ記事一覧ページに、過去に他の場所で書いた記事も一覧表示したかったので対応しました。 やったことについては、このcommitを見てもらうのが一番早いです。 https://github.com/tkancf/tkancf.com/pull/28/commits/4ff45a1cf5c75fd5d37d0649eb1c65b743481507 ## もう少し詳しく How to - IndexページのAstroファイル (`src/pages/blog/index.astro`)に、externalPostsという配列で、外部記事のリンク集を用意 - 既存の記事 (`getCollection("blog")`)とガッチャンコ - 合わせた配列を日付順に表示して一覧表示 - 一覧表示する際に、外部記事の場合はリンク先を外部サイトにしつつ、タイトルの前に `(外部リンク):` という文字列を付与 というのが、ざっくりやったことです。 ### 変更のdiff [commitの内容](https://github.com/tkancf/tkancf.com/pull/28/commits/4ff45a1cf5c75fd5d37d0649eb1c65b743481507)より、一部抜粋 ```diff --- a/src/pages/blog/index.astro +++ b/src/pages/blog/index.astro @@ -6,15 +6,133 @@ import { SITE_TITLE, SITE_DESCRIPTION } from "../../consts"; import { getCollection } from "astro:content"; import FormattedDate from "../../components/FormattedDate.astro"; +const externalPosts = [ + { + id: "external-1", + slug: "", + body: "", + collection: "external", + data: { + title: "VimでMarkdownの日本語メモを取るための設定をする", + pubDate: new Date("2017-04-27"), + url: "https://qiita.com/tkancf/items/e61b7c09def497204628", + }, + }, + { + id: "external-2", + slug: "", + body: "", + collection: "external", + data: { + title: "この1冊ですべてわかる 新版 コーチングの基本を読みました", + pubDate: new Date("2022-08-21"), + url: "https://tkancf.hateblo.jp/blog/%E3%81%93%E3%81%AE1%E5%86%8A%E3%81%A7%E3%81%99%E3%81%B9%E3%81%A6%E3%82%8F%E3%81%8B%E3%82%8B_%E6%96%B0%E7%89%88_%E3%82%B3%E3%83%BC%E3%83%81%E3%83%B3%E3%82%B0%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE", + }, + }, (中略) + { + id: "external-10", + slug: "", + body: "", + collection: "external", + data: { + title: "fish shellの初期設定覚え書き(PATHの設定とか)", + pubDate: new Date("2017-03-30"), + url: "https://tkancf.hateblo.jp/blog/2017/03/30", + }, + }, +]; + const posts = (await getCollection("blog")).sort( (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf() ); + +const combinedPosts = [...posts, ...externalPosts].sort( + (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf() +); --- @@ -40,10 +158,19 @@ const posts = (await getCollection("blog")).sort(
    { - posts.map((post) => ( + combinedPosts.map((post) => (
  • - {post.data.title} + + {post.collection === "external" ? "(外部リンク): " : ""} + {post.data.title}{" "} +
  • )) } ``` 以上、とっても簡単でした。Astroは便利ですね。 # Gitでマルチバイト文字列がエスケープされる対策 デフォルトだとGitでマルチバイト文字列がエスケープされるのでその対策方法のメモです。 ## どうすればいいのか? core.quotepath オプションを false にする 下記コマンドを実行する ```bash git config --global core.quotepath false ``` またはgitconfigに下記記載する ``` [core] quotepath = false ``` ## core.quotepath is なんのオプション このオプションがtrue(デフォルト設定)になっていると、マルチバイト文字列がCのエスケープ方法と同じようにエスケープされる。 UTF-8の"μ"を例にすると、 "μ"はhex codeで"0xC2 0xB5"なので、これを10進数にして"\302\265"にエスケープされる。 日本語文字列も同じ要領でエスケープされるので、日本語をファイル名に含むファイルをGit管理するときは false にしたほうが良い。 ## 参考資料 - Git - git-config Documentation - https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath # ブログをAstroからHonoのSSGに移行しました このブログは元々Astroを使って生成していました。 Astroはサクッとコンテンツメインのサイトが作れて便利なんですが、[Blogを作り、育み、慈しむ ~ Blog Hacks 2024](https://junkyard.song.mu/slides/yapc-hiroshima-2024/#0)というスライドを見て、もうちょっと「好きなもの」を使って作り変えるのも良いかなと思っていました。 同じくらいの時期に[Honoのv4でSSGが可能になり](https://zenn.dev/yusukebe/articles/b20025ebda310a)、触ってみたい気持ちが高まっていたので移行してみました。 Honoは以前、CloudFlare Workersで[LINE botを作ったとき](https://tkancf.com/blog/creating-line-bot-with-cloudflare-workers-d1-and-hono)に使ったんですが、かなり感触が良かったので定期的に状況をウォッチしていました。 Hono自体も良いですし、[作者さん(@yusukebe)](https://github.com/yusukebe)のブログがワクワクする内容で好きなんですよね。 [Honoのv4が2月9日にリリースされます](https://zenn.dev/yusukebe/articles/b20025ebda310a)とか、[OSSで世界と戦うために - ゆーすけべー日記](https://yusukebe.com/posts/2023/oss-against-the-world/)とか。 ## 移行作業について 移行と言いつつ既存のコードはほとんど残っておらず、記事以外はほぼ作り直しになりましたが、Honoはシンプルで公式ドキュメントもexampleが分かりやすく、[先行事例](https://zenn.dev/razokulover/articles/9818ef632f677f)もあったので、大きくハマって悩むこともなく作れました。 ざっくり以下のような流れで作りました。 - [yusukebe/hono-ssg-example](https://github.com/yusukebe/hono-ssg-example/)を参考に最小構成で動くことを確認 - [remark](https://remark.js.org/)を使ってMarkdownからHTML生成→表示確認 - CSSを適用 - sitemapを追加 - RSSフィード作成 - デプロイして動作確認 ## やったこと 私が雑にお試しして試行錯誤しているリポジトリは[GitHub - tkancf/sandbox](https://github.com/tkancf/sandbox/tree/main/hono-ssg)です。 ### 最小構成で動かしてみる まずは、Hono作者さんの[yusukebe/hono-ssg-example](https://github.com/yusukebe/hono-ssg-example/)を参考に別のリポジトリでとりあえず生成できることを確認するだけのコードを用意してみました。 [yusukebe/hono-ssg-example](https://github.com/yusukebe/hono-ssg-example/)はHono v4公開前にpatchを適用して作成しているexampleだったので、改変しつつ動かしてみました。 [この辺りのcommit](https://github.com/tkancf/sandbox/tree/22af695683965d210df1c0d50d87c14ad1b5a1fd/hono-ssg)が最小構成で動くことを確認できた所だと思います。 [Hono v4紹介記事](https://zenn.dev/yusukebe/articles/b20025ebda310a)では、静的ページを生成するために`build.ts`というファイルを作っていましたが、`@hono/vite-ssg`というViteのプラグインを使えば`build.ts`は不要でした。 細かい部分は[該当commit](https://github.com/tkancf/sandbox/tree/22af695683965d210df1c0d50d87c14ad1b5a1fd/hono-ssg)をみてもらうと分かりますが、ポイントを一部抜粋して記載します。 以下が`vite.config.ts`です。 `@hono/vite-ssg`を使うと、`vite build`実行時に各ページを生成してくれます。 ```typescript import { defineConfig } from "vite"; import ssg from "@hono/vite-ssg"; // 追加 import devServer from "@hono/vite-dev-server"; const entry = "src/index.tsx"; export default defineConfig(() => { return { plugins: [devServer({ entry }), ssg({ entry })], // ssg({entry})を追加 }; }); ``` `src/index.tsx`についてはほぼ見た通りで、該当コードは[こちら](https://github.com/tkancf/sandbox/blob/22af695683965d210df1c0d50d87c14ad1b5a1fd/hono-ssg/src/index.tsx)です。 `ssgParams(() => posts),`の部分は、Path Parameterがついた各パスに静的に生成されるパスを割り当てるためのミドルウェアです。 これがないと、`/posts/hoge`みたいなページが生成されません。 私はNext.jsを触ったことがないので知りませんでしたが、Next.jsの[generateStaticPaths](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths)と似た機能らしいです。 ```typescript app.get( "/posts/:id", ssgParams(() => posts), (c) => { return c.render(

    {c.req.param("id")}

    ); } ); ``` ### Markdownから記事生成 ここはHono関係なく、Astroのブログテンプレートだとデフォルトで用意されていたMarkdown→HTML変換を自前で用意する工程です。 [Astroのドキュメント](https://docs.astro.build/en/guides/markdown-content/)を見ると[remark](https://remark.js.org/)というライブラリを使っていると書いていたので、同じライブラリを使って同様の機能を用意しました。 該当コードは[src/lib/post.ts](https://github.com/tkancf/tkancf.com/blob/bc9f6936b2bd0a73d997281892e1c11c16bfce14/src/lib/post.ts)です。remarkを使えば簡単に用意できました。 こんな感じでパースできます。便利。 ```typescript const content = fs.readFileSync(filePath, { encoding: "utf-8" }); const result = await remark() .use(remarkParse) .use(remarkFrontmatter, [ { type: "yaml", marker: "-", anywhere: false }, ]) .use(remarkExtractFrontmatter, { yaml: yaml.parse, name: "frontMatter", }) .use(remarkExpressiveCode, { theme: "github-light", }) .use(remarkGfm) .use(remarkRehype, { allowDangerousHtml: true }) .use(rehypeStringify, { allowDangerousHtml: true }) .use(remarkGfm) .process(content); ``` ### sitemapの生成 こちらもAstroのブログテンプレートだとデフォルトで用意されていましたが、自前で生成してあげる必要があります。 とは言ってもコード書くまでもなかったです。 `vite-plugin-sitemap`を入れて、`vite.config.ts`に設定を書いてあげるだけで完了しました。 追加後の`vite.config.ts` ```typescript import { defineConfig } from "vite"; import ssg from "@hono/vite-ssg"; import devServer from "@hono/vite-dev-server"; import Sitemap from "vite-plugin-sitemap"; // vite-plugin-sitemapをいれて import { baseURL } from "./src/lib/constants"; const entry = "src/index.tsx"; export default defineConfig(() => { return { plugins: [ devServer({ entry }), ssg({ entry }), Sitemap({ hostname: baseURL, generateRobotsTxt: true }), // ←追加した設定はこの部分 ], }; }); ``` ### RSSフィードの生成 こちらもAstroのブログテンプレートだとデフォルトで用意されていたRSSフィードを生成してあげます。 記事一覧のデータさえ用意出来ていれば`rss`を利用してサクッと作れます。 ```typescript import RSS from "rss"; (中略) const generateFeed = async () => { const rss = new RSS({ title: siteName, site_url: baseURL, description: siteName, feed_url: baseURL + "/feed", generator: siteName, }); posts.forEach(async (post: any) => { const url = baseURL + "/blog/" + post.slug; rss.item({ title: post.title, url: url, date: new Date(post.pubDate), description: post.description, }); }); return rss.xml(); }; app.get("/feed", async (c) => { const feeds = await generateFeed(); return c.text(feeds, 200, { "Content-Type": "text/xml", }); }); ``` ### CSSの適用 Honoには`hono/css`というCSS in JSのヘルパーがあるので、それを利用しました。 グローバルなCSSをどう適用すれば良いのかちょっと試行錯誤しましたが、以下のようにhtmlタグに全体適用したいCSSを付与してあげて、headタグ内に `