# 🏆MVP ## ghostwriter.nvimでNeovimプラグイン開発デビュー [[Vim]]をはじめて6年半、[[Neovim]]をはじめて1年半... [[Vim]]/[[Neovim]]あわせてはじめてのプラグインを開発した。その名も[[🦉ghostwriter.nvim]]だ。 <div class="link-card"> <div class="link-card-header"> <img src="https://github.githubassets.com/favicons/favicon.svg" class="link-card-site-icon"/> <span class="link-card-site-name">GitHub</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">GitHub - tadashi-aikawa/ghostwriter.nvim</p> <p class="link-card-description">A Neovim plugin to share Markdown task lists as Slack posts.</p> </div> <img src="https://opengraph.githubassets.com/fe74131169720c6ea6bfa43b791a0921a8041a5f3f841c1a4fbe6fc39d5720fc/tadashi-aikawa/ghostwriter.nvim" class="link-card-image" /> </div> <a href="https://github.com/tadashi-aikawa/ghostwriter.nvim"></a> </div> ![[Pasted image 20240805081551.png]] 機能としては、[[Neovim]]の[[Markdown]]で書いた内容を[[Slack]]に1コマンドで投稿できるというもの。主に箇条書きやタスクリストでの利用を想定している。 たとえば以下のような内容を書く。 ![[Pasted image 20240805082020.png|frame]] *Markdownの内容* `:Ghostwrite`コマンドを実行すると、[[Slack]]に以下の内容が投稿される。 ![[Pasted image 20240805082042.png|frame]] *Slackの投稿* 特徴的なのは、**直前に投稿した内容を1度削除し、同じchannelに最新の内容として投稿しなおすこと** だ。channelによってはノイズになってしまうかもしれないが、進捗状況などを逐一共有しておきたい場合や、MTGの議事録を(なぜか)[[Slack]]でリアルタイムに共有しておきたい場合にはその方が都合がいい。今後ユースケースが増えたり、ユーザーがついて要望が出てきたら、設定でのカスタマイズは考えている。 [[🦉ghostwriter.nvim]]の開発を通して、[[Lua]]の知見も深まった。型に関する[[lua-language-server|LuaLS]]の機能 ([[LuaCATSアノテーション]]) には感動させられた。[[Lua]]は[[Python]]や[[Elixir]]などと同じく[[動的型付け言語]]だが、それらの言語よりも後付けである型に対して真剣に取り組んでいる様が感じられるクオリティだった。 初見では難しかった非同期処理についても自分の中では腑に落ちたので、今後の[[Neovimプラグイン]]開発がさらに捗ることは間違いないだろう。 <div class="link-card"> <div class="link-card-header"> <img src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" class="link-card-site-icon"/> <span class="link-card-site-name">minerva.mamansoft.net</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">📜2024-08-03 Luaを使ったNeovimのプラグイン開発で非同期を学ぶ</p> <p class="link-card-description">Neovimプラグインとして🦉ghostwriter.nvimを作ったが、非同期処理が結局実装できないままでいた。文献を漁って🦉ghostwriter.nvimで試した限りでは上手くいかなかったため、1から勉強用のプロジェクトを作成し、丁寧に理解していく。</p> </div> <img src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/activity.webp" class="link-card-image" /> </div> <a class="internal-link" data-href="Notes/📜2024-08-03 Luaを使ったNeovimのプラグイン開発で非同期を学ぶ.md"></a> </div> %%[[📜2024-08-03 Luaを使ったNeovimのプラグイン開発で非同期を学ぶ]]%% このあたりの知見はかなりの量だったので、[[🦉ghostwriter.nvim]]が一息ついたタイミングで[[📒Articles]]を書きたいと思っている。詳しくはそちらで。 # 🥈RUP ## Nuxtの快適な開発設定を突き詰めたArticle執筆 7月2つ目の[[📒Articles]]は、珍しくガッツリ技術的な内容を書いた。 <div class="link-card"> <div class="link-card-header"> <img src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" class="link-card-site-icon"/> <span class="link-card-site-name">minerva.mamansoft.net</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">📘完全武装をしてNeovimでも安全で快適なNuxt3の開発をするのだ</p> <p class="link-card-description">Neovimにて、できるだけ型安全かつ快適なNuxt3の開発ができるよう、設定をチューニングしてみました。</p> </div> <img src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/%F0%9F%93%98Articles/attachments/2024-07-26.webp" class="link-card-image" /> </div> <a class="internal-link" data-href="📘Articles/📘完全武装をしてNeovimでも安全で快適なNuxt3の開発をするのだ.md"></a> </div> %%[[📘完全武装をしてNeovimでも安全で快適なNuxt3の開発をするのだ]]%% 最近は仕事でも[[Nuxt]]で開発する機会が増えたが、どうもデフォルトでは型安全とは言えず、実行時に初めて問題に気づくことが多かったため、この機会に安全性に舵取りをした...という内容だ。ただし、安全性を重視しつつも開発の快適さはできるだけ損なわないように工夫したつもり。もちろん[[IDE]]を使いこなしていることが前提ではある。 1週間ほどこの設定を使い続けてみたが、今のところ大きな不満はない。むしろ、[[IDE]]の補完やquickfixを何も考えずに受け入れているだけで安全なコードが書けており、非常に満足している。import文が増えてしまうデメリットはあるものの、今のところ可読性を損ねているとは感じない。import文のブロックを認知などしていないのだから。 [[React]]のコーディング快適レベルを期待されると厳しいかもしれないが、それに近しい体験を得られるようにはなっていると思う。[[Nuxt]]の[[Auto-imports (Nuxt)|Auto-imports]]や型の緩さにモヤモヤ感を抱いているなら是非1度試してみてほしい。 # 🪙OPA ## Marpスライドのテンプレート作成 [[📰2024年29週 Weekly Report]]でもピックアップした[[Marp]]について、今後のスライド作成スピードとクオリティアップのため、自分用のテンプレートプロジェクトをつくることにした。 <div class="link-card"> <div class="link-card-header"> <img src="https://github.githubassets.com/favicons/favicon.svg" class="link-card-site-icon"/> <span class="link-card-site-name">GitHub</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">slides/template at main · tadashi-aikawa/slides</p> <p class="link-card-description">Contribute to tadashi-aikawa/slides development by creating an account on GitHub.</p> </div> <img src="https://opengraph.githubassets.com/6ec38c90c4cb105fe76cc3bff733c521cd3ad1fde2cd13a899c74a3ba746b392/tadashi-aikawa/slides" class="link-card-image" /> </div> <a href="https://github.com/tadashi-aikawa/slides/tree/main/template"></a> </div> 今後はこのテンプレを充実させていきつつ、スライド作成が必要な時はコピペをして[[Neovim]]でちょろちょろっといじるだけで済ませていきたいと思っている。過去に2度、コードベースのスライド管理にチャレンジして失敗したことがある... が、世の中の技術も色々便利になり、自身のWeb開発スキルも向上して、[[Neovim]]という強力な相棒も得たこの3度目は何とかしてモノにしたいものだ。 # 🚀Releases - [[🦉ghostwriter.nvim]] - ファーストリリース - [[🦉Silhouette]] - [Silhouette v0.22.0リリース](https://github.com/tadashi-aikawa/silhouette/releases/tag/0.22.0) - 繰り返しパターンのOR指定対応 - [[🦉Fenice]] - [Fenice v0.26.0リリース](https://github.com/tadashi-aikawa/fenice/releases/tag/v0.26.0) - 重要メッセージ検索間隔設定追加 (default: 5分) # 👀Reading ## Emacsは優れたOSだが、優秀なテキストエディタを欠いている — PDFも表示できちゃう最近のEmacs事情 <div class="link-card"> <div class="link-card-header"> <img src="https://techfeed.io/images/logo/logo-192x192.png" class="link-card-site-icon"/> <span class="link-card-site-name">TechFeed (テックフィード)</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">Emacsは優れたOSだが、優秀なテキストエディタを欠いている — PDFも表示できちゃう最近のEmacs事情</p> <p class="link-card-description">Emacsの最新情報をお伝えします。</p> </div> <img src="https://res.cloudinary.com/techfeed/image/upload/w_1200,h_630,c_fill/entries/cnqzprqc5jwoaaxulwon.png" class="link-card-image" /> </div> <a href="https://techfeed.io/entries/66a1b00170b1f142398f112a"></a> </div> ~~~ メチャクチャ面白かった。エモいし中身もある話はやっぱいい😊 https://techfeed.io/entries/66a1b00170b1f142398f112a ~~~ ## TypeScriptの標準ライブラリで使われているdeclaration mergingのテクニック <div class="link-card"> <div class="link-card-header"> <img src="https://static.zenn.studio/images/logo-transparent.png" class="link-card-site-icon"/> <span class="link-card-site-name">Zenn</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">TypeScriptの標準ライブラリで使われているdeclaration mergingのテクニック</p> </div> <img src="https://res.cloudinary.com/zenn/image/upload/s--o80psio_--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:TypeScript%25E3%2581%25AE%25E6%25A8%2599%25E6%25BA%2596%25E3%2583%25A9%25E3%2582%25A4%25E3%2583%2596%25E3%2583%25A9%25E3%2583%25AA%25E3%2581%25A7%25E4%25BD%25BF%25E3%2582%258F%25E3%2582%258C%25E3%2581%25A6%25E3%2581%2584%25E3%2582%258Bdeclaration%2520merging%25E3%2581%25AE%25E3%2583%2586%25E3%2582%25AF%25E3%2583%258B%25E3%2583%2583%25E3%2582%25AF%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:uhyo%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzVjYjFlMDJlNGQuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png" class="link-card-image" /> </div> <a href="https://zenn.dev/uhyo/articles/typescript-lib-declaration-merging"></a> </div> ~~~ なるほどなぁ。。。Volarでカスタム属性生やすのも同じ仕組み使ってそう。 https://zenn.dev/uhyo/articles/typescript-lib-declaration-merging ~~~ ## 非同期処理とリトライと冪等性 - GS2 Blog <div class="link-card"> <div class="link-card-header"> <img src="https://gs2.hatenablog.com/icon/favicon" class="link-card-site-icon"/> <span class="link-card-site-name">GS2 Blog</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">非同期処理とリトライと冪等性 - GS2 Blog</p> <p class="link-card-description">今回の記事は普段の GS2 のアップデート告知とは少し毛色が異なり、技術的なトピックを扱うエントリーです。gs2.hatenablog.comこちらで告知した消費アクションの分岐処理を実装するにあたって、どのようなアプローチで課題に向き合ってきたのかを解説しようと思います。 非同期処理とリトライ まずは、非同期処理とリトライについて考えてみま ... </p> </div> <img src="https://ogimage.blog.st-hatena.com/10328749687181239785/6801883189125648753/1722309685" class="link-card-image" /> </div> <a href="https://gs2.hatenablog.com/entry/2024/07/29/232715"></a> </div> ~~~ ちょうどこういうことやってるのでタイムリー https://gs2.hatenablog.com/entry/2024/07/29/232715 ~~~ ## plenary.nvim による非同期処理 - Qiita <div class="link-card"> <div class="link-card-header"> <img src="https://cdn.qiita.com/assets/favicons/public/production-c620d3e403342b1022967ba5e3db1aaa.ico" class="link-card-site-icon"/> <span class="link-card-site-name">Qiita</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">plenary.nvim による非同期処理 - Qiita</p> <p class="link-card-description">1. plenary.nvim とは?Neovim 界で一番メジャーなプラグインとは何でしょう? 異論はあるかも知れませんが、多くの人は telescope.nvim を挙げると思います。ファジー…</p> </div> <img src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fcdn.qiita.com%2Fassets%2Fpublic%2Fadvent-calendar-ogp-background-7940cd1c8db80a7ec40711d90f43539e.jpg?ixlib=rb-4.0.0&w=1200&mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTk3MiZoPTM3OCZ0eHQ9cGxlbmFyeS5udmltJTIwJUUzJTgxJUFCJUUzJTgyJTg4JUUzJTgyJThCJUU5JTlEJTlFJUU1JTkwJThDJUU2JTlDJTlGJUU1JTg3JUE2JUU3JTkwJTg2JnR4dC1hbGlnbj1sZWZ0JTJDdG9wJnR4dC1jb2xvcj0lMjMzQTNDM0MmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9NTYmcz05NDY1MzFhMzVmZmE3ODU0NjMzYjFmMTYxZTQ1MGY1Zg&mark-x=120&mark-y=96&blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZoPTc2Jnc9OTcyJnR4dD0lNDBkZWxwaGludXMmdHh0LWNvbG9yPSUyMzNBM0MzQyZ0eHQtZm9udD1IaXJhZ2lubyUyMFNhbnMlMjBXNiZ0eHQtc2l6ZT0zNiZ0eHQtYWxpZ249bGVmdCUyQ3RvcCZzPTgyNjRjMDE1MWQxNWY3M2YxNmZiOTY5OGFjNWRiNGQy&blend-x=120&blend-y=445&blend-mode=normal&txt64=aW4g5qCq5byP5Lya56S-44OH44Kj44O844O744Ko44OM44O744Ko44O8&txt-width=972&txt-clip=end%2Cellipsis&txt-color=%233A3C3C&txt-font=Hiragino%20Sans%20W6&txt-size=36&txt-x=134&txt-y=546&s=c9898d1b5c44c0cd2cf4d5f658ba1ee3" class="link-card-image" /> </div> <a href="https://qiita.com/delphinus/items/2d60bd2f00834c7709e6"></a> </div> ~~~ Neovimプラグイン開発での非同期が今一つできてないので勉強する。 https://qiita.com/delphinus/items/2d60bd2f00834c7709e6 ~~~ ## Annotations <div class="link-card"> <div class="link-card-header"> <img src="https://github.githubassets.com/favicons/favicon.svg" class="link-card-site-icon"/> <span class="link-card-site-name">GitHub</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">Annotations</p> <p class="link-card-description">A language server that offers Lua language support - programmed in Lua - LuaLS/lua-language-server</p> </div> <img src="https://opengraph.githubassets.com/fe3e24593b98f869e1b805449153df2fccee2c4c9cb27f40d7a1634306e39343/LuaLS/lua-language-server" class="link-card-image" /> </div> <a href="https://github.com/LuaLS/lua-language-server/wiki/Annotations#param"></a> </div> ~~~ ここはちゃんと読んでおきたい。 https://github.com/LuaLS/lua-language-server/wiki/Annotations#param ~~~ ## 自分が書いたコードより目立つな - エンジニアがバズったので自戒 - じゃあ、おうちで学べる <div class="link-card"> <div class="link-card-header"> <img src="https://syu-m-5151.hatenablog.com/icon/favicon" class="link-card-site-icon"/> <span class="link-card-site-name">じゃあ、おうちで学べる </span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">自分が書いたコードより目立つな - エンジニアがバズったので自戒 - じゃあ、おうちで学べる </p> <p class="link-card-description">はじめに 私はソフトウェアエンジニアだ。私はソフトウェアエンジニアだ。私の本質的な仕事は、複雑な問題を解決し、効率的で革新的なソフトウェアを開発すること ... </p> </div> <img src="https://m.media-amazon.com/images/I/41u4r0mRSeL._SL500_.jpg" class="link-card-image" /> </div> <a href="https://syu-m-5151.hatenablog.com/entry/2024/07/31/104151"></a> </div> ~~~ 心に響いた。 改善業務や執筆作業、批評などが主体なっていた時期もあったけど、価値あるものを創っているときが楽しいと最近も変わらず思う。技術や勉強は興味ないしあんま好きじゃないけど。(ある程度スキル習得した優越感と相殺してプラマイ0くらい) > ソフトウェアエンジニアとして作る側の人間に強烈に憧れてきたにも関わらず批評家みたいなことばかりしているのは衰弱している証拠。このままでは本当に作る人間として死ぬ。本質を忘れず、コードを書いて自戒したまま死にたい。 https://syu-m-5151.hatenablog.com/entry/2024/07/31/104151 ~~~ ## 【山田祥平のRe:config.sys】 起きて半畳寝て一畳、それでも欲しい2階建ての15.6型 <div class="link-card"> <div class="link-card-header"> <img src="https://pc.watch.impress.co.jp/favicon.ico" class="link-card-site-icon"/> <span class="link-card-site-name">PC Watch</span> </div> <div class="link-card-body"> <div class="link-card-content"> <p class="link-card-title">【山田祥平のRe:config.sys】 起きて半畳寝て一畳、それでも欲しい2階建ての15.6型 </p> <p class="link-card-description"> 大きな画面が1つがいいのか、そこそこのサイズの画面が複数あったほうがいいのか。ここは賛否両論あるにしても、PCの作業効率は作業エリアの物理的な面積に比例する。これについての異論は認め ... </p> </div> <img src="https://pc.watch.impress.co.jp/img/pcw/list/1613/690/01.jpg" class="link-card-image" /> </div> <a href="https://pc.watch.impress.co.jp/docs/column/config/1613690.html"></a> </div> ~~~ 凄く気になるところではあるけど、今のところユースケースが若干微妙だったりする... - 家だとウルトラワイド+正方形+FullHDモバイルで間に合ってる - 会社だとUSB Type-Cが全然足りないので無理 - MTG持ち運び時だと重すぎる ワンちゃんあるとしたら急遽スタンディングで仕事したくなったときのサブモニタとしてくらいかなあ... https://pc.watch.impress.co.jp/docs/column/config/1613690.html ~~~ # 📚New Notes - [[3種類の等価アサーション (Jest)]] - [[Annotations (LuaLS)]] - [[Diagnostics (LuaLS)]] - [[LuaCATSアノテーション]] - [[lazydev.nvim]] - [[libuv]] - [[luv]] - [[toBe (Jest)]] - [[toEqual (Jest)]] - [[toStrictEqual (Jest)]] - [[util.promisify]] - [[vim.notify]] - [[vueCompilerOptions.strictTemplates]] - [[インサートモードでもtoggle.checkboxを実行 (markdown-toggle.nvim)]] - [[カレントディレクトリ (Neovim)]] - [[コンポーネント (lualine.nvim)]] - [[コンポーネントにカレントディレクトリからの相対パスを表示 (lualine.nvim)]] - [[セクション (lualine.nvim)]] - [[フォントを指定 (Marp)]] - [[ブロッキングのsleep (Neovim)]] - [[ユーザーにINFO情報を通知 (Neovim)]] - [[ローカルディレクトリのプラグインを指定 (lazy.nvim)]] - [[文字列が指定された文字列で終わるか (Lua)]] - [[📕現在のLuaファイル実行結果をその場で確認 (Neovim)]] - [[📕Neovimプラグイン開発のユースケース]] - [[📜2024-08-03 Luaを使ったNeovimのプラグイン開発で非同期を学ぶ]] - [[📜2024-08-03 neodev.nvimからlazydev.nvimへ移行]] - [[🦉ghostwriter.nvim]] - [[📘完全武装をしてNeovimでも安全で快適なNuxt3の開発をするのだ]]