• protocでprotoc-gen-js: program not found or is not executableエラーが出るとき

    • javascript
    • grpc
    原因 protocで proto ファイルから型生成をしようとすると出るエラー。 $ protoc \ --plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \ --js_out="import_style=commonjs,binary:${OUT_DIR}" \ --ts_out="${OUT_DIR}" \ users.proto base.proto protoc-gen-js: program not found or is not executable Please specify a program using absolute path or make sure the program is available in your PATH system variable --js_out: protoc-gen-js: Plugin failed with status code 1. 最初 protoc-gen-js なんてパッケージ使ってないし何やねんと思ったのだけど --js_out オプションを指定すると内部で暗黙的に呼ばれる実行ファイルのことっぽく、これが2022年の時点でprotocのコアに含まれなくなったため見つからないというエラーが出るらしい。 (JSの実
  • Hugoでsyntax highlightをダークモード対応させる

    • hugo
    Hugoでsyntax highlightを実現するには2つの方法がある。 ビルド時点でHTMLに色情報を含むインラインスタイルを付与する ビルド時点でクラスのみを付与し別途CSSで文字を着色する 手っ取り早くダークモード対応を実現するために、後者を選択する。 config.toml を編集し、syntax highlight用のクラス付与を有効化する。 # see: https://gohugo.io/getting-started/configuration/ [markup] [markup.highlight] noClasses = false (二重否定でややこしいけど、要するに「クラスを付与する」の意)
  • Railsでクラス名文字列のModule部分をなんやかんやする

    • rails
    Module部分を取り除きたいときは demodulize する。 1 v = Some::AwesomeKlass p v.class.name # => "Some::AwesomeKlass" p v.class.name.demodule # => "AwesomeKlass" p v.class.name.demodulize.underscore # => "awesome_klass" 逆にModule部分だけを取得したいときは deconstantize を使う。2 v = Some::AwesomeKlass p v.class.name # => "Some::AwesomeKlass" p v.class.name.deconstantize # => "Some" v = ::Another::AwesomeKlass p v.class.name.deconstantize # => "::Another" いずれもActiveSupportの独自拡張なので、Rails環境の外では使えない。 上記メソッドの実装付近には他にも便利そうなやつが色々あるので、調べてみると面白いかも。そんなことないかも。 https://github.com/rails/rails/blob/eb254db4addbee8cbaff0362e3321df2fced1871/activesupport/lib/active_support/core_ext/string/inflections.rb#L152-L164  ↩︎ https://github.com/rails/rails/blob/eb254db4addbee8cbaff0362e3321df2fced1871/activesupport/lib/active_support/core_ext/string/inflections.rb#L166-L179  ↩︎
  • shellでプロジェクト内のテキストを一括置換する

    • shell
    素朴にやる rg と sed を組み合わせれば実現できる。 $ rg FOO -l | xargs sed -i s/FOO/BAR/g ( ripgrepでgrep検索しつつsedで一括置換をかける | 7me を読みました、ありがとうございます) 素朴に関数化する いちいちパイプでコマンド繋いで~パターン2回書いて~とやってられないので、こういう関数を .zshrc などに書いておくと一応シュッと呼べる。 rp() { rg $1 -l | xargs sed -i s/$1/$2/g } $ rp print println # ... (特に何も出ない) 多少いい感じに関数化する 上記の例だと何も表
  • MacとLinuxはsedの引数が違う

    • shell
    Macの場合は第一引数に "" をつける必要がある。1 知らんかったですね。 OS X + Sed: “extra characters at the end of l command” Error | My Shitty Code  ↩︎
  • GitHubっぽいCSSを生成する

    • css
    sindresorhus/generate-github-markdown-css: Generate the CSS for github-markdown-css GitHubのMarkdownプレビューに使われているCSSを取得できるスクリプト。コードは読んでいないけど、READMEを流し読みした限りAPI経由で実際に使われるスタイルを引き抜いているらしい。 こんな感じで簡単にCSSが生成できた。 $ npx --package=generate-github-markdown-css -- github-markdown-css --type dark_high_contrast > markdown.css ちなみに、テーマがいくつかある中で light と dark だけは上記の手順で生成されたCSSファイルが以下のリポジトリで配布されている。 sindresorhus/github-markdown-css: The minimal amount of CSS to replicate
  • ALEでrubocopが動かなかった

    • vim
    • raiis
    3行 ALEはデフォルトでGemfile に記載されてるものじゃなくグローバルインストールされてる rubocop を使う 両者のバージョンが違うとエラーになって rubocop は静かに異常終了してしまう let g:ale_ruby_rubocop_executable = 'bundle' すると解決する 前提 Ubuntu20 (WSL2) NeoVim v0.6.1 ALE Ruby rubocop 起きたこと ALEにrubocopを設定した。こんな感じで。 " ale let g:ale_fix_on_save = 1 let g:ale_sign_column_always = 1 let g:ale_disable_lsp = 1 let g:ale_linters = { \ "... \ 'ruby': ['solargraph', 'rubocop'], \ } let g:ale_fixers = { \ '*': ['remove_trailing_lines', 'trim_whitespace'], \ " ... \ 'ruby': ['rubocop'], \ } let g:ale_ruby_rubocop_auto_correct_all = 1 しかし、コードに空行をあけてみても、まった
  • ParamsWrapperの挙動

    • rails
    spec記述中に見つけた挙動 試みたこと 「POSTリクエストを受け付けてファイル出力ジョブを予約する」というAPIエンドポイントを追加したく、ほぼ同じ挙動をする FugasController をコピペしつつ HogesController を作った。エンドポイントも /api/v1/exports/hoges と /api/v1/exports/fugas という感じなのだけど、この命名は RESTful APIとしてアプリケーション内のリソース名を用いたものではなく、出力されるファイル名に基づいていた。 これは今回のケースで大事な前提である。 追加した HogesController にrequ
  • Working Out Loudの実践と学び

    • team
    これは SmartHR Advent Calendar 2021 の10日目に書かれた記事です。今は 12月10日の42時31分なので、ギリギリ滑り込んだ形になってしまいましたね。 スクラムの中心で進捗を叫んだけもの 僕の所属するチームは2021年はじめから働き方にWorking Out Loud (WOL) という考え方を取り入れて実践してきた。あれこれ試行錯誤を重ねつつ1年弱やってきて一定の成果を実感できているので、なんとなくまとめておく。 Working Out Loudとは Working Out Loudとはなに
  • fugitive.vimでソースコードのGitHubリンクを取得する

    • neovim
    動機 業務の中でソースコードの中の特定部分をGitHubリンクで共有する機会は多い。 こういうやつ のことである。 今まではVim上でコードベースをあれこれ眺めて目当てのコードを探し当てたあと、改めてGitHubを開いてポチポチ移動して該当ファイルまで辿り着き、行数を頼りにスクロールしたりブラウザのページ内検索を駆使したりしてリンクを取得していた。一人で作業しながらSlackにコード片を貼るような場面なら
  • スライスという存在を誤解してた

    • python
    スライスは参照だと思ってた PythonでもNode.jsでも配列は参照渡しなので、以下のような挙動をする。1 >>> mc = ["百田", "玉井", "佐々木", "高城", "有安", "早見"] >>> mc2 = mc >>> mc[0] = "俺" >>> mc ['俺', '玉井', '佐々木', 
  • 諦念とフィルターバブル

    • essay
    こじらせと幸福 僕は思春期からけっこう最近まで、「正しさ」1を希求しない人間に対してメチャメチャに苛立つという謎の習性があった。結果正しくないのは別にいいけど、「正しくあろう」というモチベーションを持たない人間の気持ちが全く分からなくて、おまえ~~~という厳しい感情が沸き上がってしまう。この頃は何かと「怖い」「暗い」と評されがちだった気がする。 社会人になってからしばらく経って、急速に色んな人から「期
  • スーパーハッカーコンプレックスに対する現時点の答え

    • essay
    漠然とした「自分は本当の技術者じゃない」という気持ち なんとなく、そういうものを抱えながら生きている。内訳はいろいろある。 まず、結構大きい気がしているのは理数系に対するもの。中学時代こそゲームを自作したり偏差値80を叩き出したりして謎に神童ルートを歩んでいたものの、高校時代に中途半端な遊び癖ができてから一切そういう生産的な遊びをやめて、大した意志もなく「楽そうだから」と文系を志望した。大学こそ理系だ
  • fzfとripgrepをvim連携させて優勝する

    • vim
    動機 まず何を実現したいかと言うと、以下の2つである。率直に言うと「VSCodeのアレ」をやりたいのだ。1 CtrlP 的な、大雑把なファイル名検索 インクリメンタルなソースコード全文検索 1 は要するにfuzzy finderで、言うなれば「今開いているディレクトリ (プロジェクト?) の中からfuzzy matchでいい感じに目的のファイルを呼び出す」機能である。最初はどばーっと全てのファイルが表示されており、一文字ずつ
  • vim-plugを導入する

    • vim
    動機 「Deinをやめる理由」と「vim-plugを入れる理由」がある。あくまで僕は乗り換えますというだけで、誰かにそうすることを推奨する気はない。 プラグインの toml 管理があんまり合わなかった プラグインの導入と関連する設定をまとめて書ける点はめっちゃよかった 複数ファイルの行き来が意外と面倒だったので多少煩雑になってでも1ファイルにまとめたくなった (toml 管理せずに Dein を使うこともできるので、これは別に Dein への不満
  • ghqディレクトリを移動するキーバインドを設定する

    • shell
    動機 ghq で管理しているディレクトリに移動するコマンド、ちゃんとしたい 一番使うのに g 一文字でエイリアスを張るという絶妙な手抜き技だった キャンセルしたときの挙動とかも含めて、ちゃんと…! 作業 move_ghq_directories() { selected=`ghq list | fzf` if [ ${#selected} -gt 0 ] then target_dir="`ghq root`/$selected" echo "cd $target_dir" cd $target_dir zle accept-line fi } zle -N move_ghq_directories bindkey "^]" move_ghq_directories (非常にわかりづらいが、一度 Ctrl + C で interrupt をかけている) reverse した方が見やすそうとか、全画面乗っ取る必要ないんじゃないかとか、そもそも shell が下手すぎるとかは色々ありつ
  • ripgrepを導入する

    • shell
    動機 速い README にも書いてあるけど、ベンチマーク見る限りエグいぐらい速い 正直 grep にそこまで不満があるわけでもないが、そこまで言われると体感してみたい 作業 この勢いに乗って、そのまま zplug で導入していく。 # ripgrep zplug "BurntSushi/ripgrep", \ from:gh-r, \ as:command, \ rename-to:rg 導入自体はこれで終わりなんだけど、ついでに fzf + ripgrep で爆速検索できるようにしてみる。これは fzf の README に載っているので、素直にやっていく。 # interactive ripgrep fzgrep() { INITIAL_QUERY="" RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case " FZF_DEFAULT_COMMAND="$RG_PREFIX '$INITIAL_QUERY'" \ fzf --bind "change:reload:$RG_PREFIX {q} || true" \ --ansi --phony --query "$INITIAL_QUERY" \ --preview 'cat `echo {}
  • pecoからfzfに乗り換える

    • shell
    動機 公式で Vim に対応している 「対応している」という言い方が正しいかは分からないが、そもそもが実行ファイルと Vim Plugin のセットみたいな状態で配布されている カスタマイズ項目が多い 自分が思っていたより fuzzy matcher をよく使う人間であるということが分かったので、peco より自由度が高い fzf へ移行していく 作業 やっていくぞ。 fzf のリポジトリを見ると、GitHub Releases で実行ファイルが配布されている。つまり zplug チャンスである。 .zshrc に以下を追
  • anyenvからasdfに乗り換える

    • shell
    動機 Global のバージョンが .tool-version として静的に吐き出せるらしいよ けっこう書き捨てのスクリプトとか REPL とか使うので、地味に嬉しい init と shim への PATH 構築がシングルスクリプトで終わる anyenv みたいに envs ディレクトリ以下でループ回したりしなくていい 作業 asdf のリポジトリ を見てみると、なんと GitHub Releases を使って実行ファイルを配布している。つまり、zplug チャンスである。 ということで、試しに zplug 経由でインストールを試みてみる。 # asdf zplug "asdf-vm/asdf", \ from:github, \ as:command, \ rename-to:asdf, \
  • zplugを導入する

    • shell
    [追記]: しばらく使ってみた結果、WSL2環境だとプロンプト表示が異常に遅くなることが分かったので使うのをやめました。 これは ターミナル環境大掃除2021 の1発目です。 動機 zsh の設定を Git 管理したい 当たり前ですわな ということで、プラグイン情報をコード管理できる必要がある インストールしたコマンド類も同様に管理したい 後からインストールしたツールに依存した設定をしてしまうとマシン移行で詰むので まあ設定は極力コ
  • フロントエンドと素朴なコードベース

    • frontend
    • essay
    これは SmartHR Advent Calendar 2020 の4日目に書かれた記事です。今は 12月4日の42時10分なので、ギリギリ滑り込んだ形になってしまいましたね。 React と自由 SmartHR で開発している様々なプロダクトはその大半 1 がフロントエンドに React を採用している。僕も Twitter で「React が好きだ!TypeScript 最高だ!」と叫んでいたら「弊社 React + TypeScript ですよ」というスカウトをいただいて転職に至ったという経緯があって、それぐらい全社的に React をやっていくぞとい
  • 結局 JavaScriptで「押されたキー」はどう取得するのがよいのか

    • javascript
    • frontend
    背景 @types/react のコードを眺めていると、 KeyboardEvent の中身が一部 deprecated になっていることがわかる ( GitHub )。 interface KeyboardEvent<T = Element> extends SyntheticEvent<T, NativeKeyboardEvent> { altKey: boolean; /** @deprecated */ charCode: number; ctrlKey: boolean; /** * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method. */ getModifierState(key: string): boolean; /** * See the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values). for possible values */ key: string; /** @deprecated */ keyCode: number; locale: string; location: number; metaKey: boolean; repeat: boolean; shiftKey: boolean; /** @deprecated */ which: number; } このコードを見る限りだと、キーボードイベントに対して e.charCode とか e.keyCode という形でキーを取得する方法は非推奨ということになるが、僕は正直このへんの実装に対してあまり思い入れがない。 keyCode は
  • ブログ書きコンプレックス

    • essay
    コンプレックス 日常的に「コンプレックス」というと「劣等感」みたいな日本語が思い浮かぶけど、厳密にいうとこの邦訳は誤りなのだ。元々この語を皆の知るところとしたユングの定義は「何らかの感情によって統合されている心的内容の集まり」というより広範な深層心理であり、日本ではアドラーが提唱した理論の中心にあった「劣等コンプレックス」が有名になりすぎて変な解釈をされてしまったという歴史的な経緯があるのだという。