vimkim’s blog

Hi, my name is vimkim.

I am a vim user as well as a software developer, also interested in CLI / TUI tools, System Softwares, and Rust.

You are currently on my blog (https://blog.vimkim.dev).

You can come visit my website (https://vimkim.dev), or my github page (https://github.com/vimkim).

I use Arch btw.

CLI Tools I Use

  • neovim
  • zellij
  • tmux
  • fzf
  • fd
  • ripgrep
  • lazygit
  • lazydocker
  • rr debugger
  • uftrace
  • htop
  • btop
  • bottom
  • delta
  • diffnav
  • diffstat
  • diff-so-fancy
  • difftastic
  • atuin
  • asdf
  • eza
  • nix
  • pacman & paru package manager
  • lsd
  • bat
  • grc
  • dust
  • diskonaut
  • yazi
  • broot
  • sheldon
  • direnv
  • forgit
  • termshark
  • cgdb
  • gdb-dashboard
  • bpftrace
  • chezmoi
  • miniserve
  • mdbook
  • arp-scan
  • asciinema
  • beautysh
  • bed binary editor
  • binsider
  • hexyl
  • bison
  • chafa
  • croc
  • fastfetch
  • fq
  • gibo
  • gita
  • gitui
  • glances
  • glow
  • graphviz
  • helix
  • hugo
  • jq
  • nmap
  • parallel
  • procs
  • sc-im
  • shfmt
  • slides
  • socat
  • spring-boot-cli
  • starship
  • systemctl-tui
  • taskwarrior
  • taskwarrior-tui
  • tealdeer
  • tokei
  • trash-cli
  • tt
  • tui-journal
  • valgrind
  • conan
  • cmake & ccmake & cmake presets
  • vcpkg
  • vhs
  • viu
  • zig
  • zoxide
  • carbonyl
  • netscanner

Trying out Ghostty

I’m currently using ghostty for writing in the terminal after installing it, and it seems quite usable.

It has a lot of features, and I think I’ll use it alongside WezTerm for a while.

Learning Rust, in progress

There are numerous resources available for studying Rust, and I feel overwhelmed by the amount of material. These include:

  • The Rust CLI book
  • The Rust Programming book
  • The Tokio manual
  • Ratatui documentation
  • Turso Limbo guides
  • Rust algorithms and other topics

It’s challenging to maintain focus with so many learning paths. I’ll try my best to make a progress without losing focus.

2024-10-27: Underrated Broot

처음 broot을 사용한 이유는 단순히 디렉토리의 트리 구조를 보기 위해서였습니다. tere, broot, 다양한 툴들을 사용해봤지만, eza –tree를 사용하는 것이 가장 편리하고 직관적이라고 생각했습니다. 그 때 몇 번 사용해본 뒤, broot은 그 후 제 기억 속에서 사라졌습니다. 그런데 최근 다시 사용해보니, broot도 꽤 편리하다는 것을 알게 되었습니다.

fd와 ripgrep을 많이 사용하는데, 이 툴들의 TUI 버전이라고 생각하면 될 것 같습니다.

fd와 ripgrep의 TUI frontend를 찾기 위해 repgrep, sad, sd, serpl 등 10개 이상의 TUI 툴들을 사용해봤는데, broot이 그 중에서도 가장 편리하다고 생각합니다. fd와 ripgrep의 검색 결과를 바로 볼 수 있고, 파일을 바로 실행할 수 있습니다. yazi에서도 비슷한 기능을 제공하고 있지만, broot만큼 다양하면서도 섬세한 기능을 제공하지는 않습니다.

fd와 ripgrep을 사용하면 결국, –no-ignore와 –hidden, –full-path 등의 옵션을 사용해야 하고, fd의 결과를 ripgrep에 전달해서 파일이름 필터링과 파일내용 필터링을 동시에 사용하는 경우도 잦은데, 이런 기능을 broot는 자연스럽게 제공합니다. 심지어 결과물을 단순히 파일 이름의 나열이 아닌, 트리 구조를 유지하면서 보여줍니다.

당분간 broot을 매우 많이 사용할 것 같습니다.

2024-10-22: Zellij Synchronized Mode

bind "s" { ToggleActiveSyncTab; SwitchToMode "Normal"; }

Zellij에서 이 설정을 사용하면, 해당 탭의 모든 pane에 동일한 입력을 보내는 기능을 활성화할 수 있습니다. 정말 유용한 기능입니다! 덕분에 여러 세션에서 동시에 명령어를 입력할 수 있게 되었습니다.

예를 들어, 3-5개의 간단한 컨테이너에서 동일한 명령어를 입력하거나, 여러 conf 파일을 vim으로 동시에 수정해야 할 때, Zellij나 Tmux에 있는 Sync 기능을 이용하면 상당히 편리합니다.

Easy GitHub Pages

지금까지 찾아낸 방법 중 GitHub Pages를 가장 간단하게 배포하는 방법은 파이썬 모듈인 ghp-import를 사용하는 것입니다. 물론 GitHub Actions를 통해 자동으로 배포되도록 workflows에 yml 설정을 추가하는 방법도 좋지만, ghp-import 방식이 직관적이고 깔끔하게 작동합니다. gh-pages 브랜치에 대해 신경 쓸 필요 없이 쉽게 배포할 수 있어 더욱 편리합니다.

Search & Replace

자료를 정리하면서 search & replace 툴의 필요성을 느끼게 되었는데, 여러 좋은 툴들을 찾았습니다. 특히 repgrep, rep-grep 등 다양한 유용한 툴이 있습니다. 그리고 broot을 잘 활용하면 검색과 치환 작업을 더욱 쉽게 할 수 있을 것 같습니다.

Diffnav Reply

diff -ur의 결과를 파일 트리 형태로 시각적으로 보여주는 TUI 툴인 diffnav는 정말 유용합니다. 이 툴의 개발자는 gh-dash라는 또 다른 멋진 도구의 개발자이기도 한데, 감사 인사를 전했더니 답장을 받아서 매우 기뻤습니다.

2024-10-21

nest new를 사용하면 안 되는 이유

최근 nest new로 생성한 프로젝트에서 문제가 발생했습니다. eslint의 버전이 8에서 9로 올라가면서, eslintrc.jseslint.config.js로 변경해야 하는 breaking change가 있었는데, 이 변경이 nest new로 자동 생성되는 파일에는 적용되지 않았습니다.

반면, nest new 대신 typescript-starter를 사용해 새로 생성한 프로젝트에는 이러한 이슈가 없었습니다. 이 경험을 통해 nest new보다는 다음 명령어를 사용하는 것이 더 안정적이라고 할 수 있습니다:

git clone https://github.com/nestjs/typescript-starter

Nest의 공식 문서에서는 두 명령어가 동일한 결과를 낸다고 적혀 있지만, 엄밀히 말하면 이는 잘못된 정보입니다. 아래는 nest newgit clone으로 생성한 프로젝트의 차이점을 비교한 내용입니다.

$ diff -ur nest-new-project ts-starter-project

...

   "dependencies": {
-    "@nestjs/common": "^10.0.0",
-    "@nestjs/core": "^10.0.0",
-    "@nestjs/platform-express": "^10.0.0",
-    "reflect-metadata": "^0.2.0",
+    "@nestjs/common": "^10.3.2",
+    "@nestjs/core": "^10.4.4",
+    "@nestjs/platform-express": "^10.4.4",
+    "reflect-metadata": "^0.2.1",
     "rxjs": "^7.8.1"
   },
   "devDependencies": {
-    "@nestjs/cli": "^10.0.0",
-    "@nestjs/schematics": "^10.0.0",
-    "@nestjs/testing": "^10.0.0",
-    "@types/express": "^5.0.0",
-    "@types/jest": "^29.5.2",
-    "@types/node": "^20.3.1",
-    "@types/supertest": "^6.0.0",
-    "@typescript-eslint/eslint-plugin": "^8.0.0",
-    "@typescript-eslint/parser": "^8.0.0",
-    "eslint": "^9.0.0",
-    "eslint-config-prettier": "^9.0.0",
-    "eslint-plugin-prettier": "^5.0.0",
-    "jest": "^29.5.0",
-    "prettier": "^3.0.0",
+    "@nestjs/cli": "^10.4.5",
+    "@nestjs/schematics": "^10.1.0",
+    "@nestjs/testing": "^10.3.2",
+    "@swc/cli": "^0.3.9",
+    "@swc/core": "^1.4.0",
+    "@types/express": "^4.17.21",
+    "@types/jest": "^29.5.12",
+    "@types/node": "^20.11.16",
+    "@types/supertest": "^6.0.2",
+    "@typescript-eslint/eslint-plugin": "^6.21.0",
+    "@typescript-eslint/parser": "^6.21.0",
+    "eslint": "^8.56.0",
+    "eslint-config-prettier": "^9.1.0",
+    "eslint-plugin-prettier": "^5.1.3",
+    "jest": "^29.7.0",
+    "prettier": "^3.2.5",
     "source-map-support": "^0.5.21",
-    "supertest": "^7.0.0",
-    "ts-jest": "^29.1.0",
-    "ts-loader": "^9.4.3",
-    "ts-node": "^10.9.1",
+    "supertest": "^6.3.4",
+    "ts-jest": "^29.1.2",
+    "ts-loader": "^9.5.1",
+    "ts-node": "^10.9.2",
     "tsconfig-paths": "^4.2.0",
-    "typescript": "^5.1.3"
+    "typescript": "^5.3.3"

...

그 외에도 tsconfig나 소스 자체에서 차이점이 많습니다. 직접 비교해보는 것을 추천합니다.

위에서 볼 수 있듯이, typescript-starter는 Nest 사용자 커뮤니티에서 편의성과 안정성을 위해 고려한 많은 흔적이 있지만, nest new로 생성된 프로젝트는 관심과 지원이 다소 부족한 것으로 보입니다.

nest new를 사용할 때 자동 생성에 사용되는 파일의 템플릿은 nestjs/schematics 레포에서 확인할 수 있으며, 로컬에서도 다음 명령어로 위치를 확인할 수 있습니다:

$ fd -H -I prettierrc
22.9.0/lib/node_modules/@nestjs/cli/node_modules/@nestjs/schematics/dist/lib/application/files/ts/.prettierrc

놀랍게도, eslint의 버전을 8에서 9로 올린 원인 제공자는 Renovate Bot입니다. 이는 자동으로 package.json의 의존성 버전을 업데이트해주는 봇입니다. 관련 커밋은 여기에서 확인할 수 있습니다.

봇이 eslint를 8에서 9로 올리면서, eslintrc 또한 eslint.config.js로 이주했더라면 좋았겠지만, 그렇게 되지 않아 eslint가 에러를 내면서 Nest와 Node에 처음 입문한 많은 개발자들에게 혼란을 주었을 것입니다. 저 또한 지인의 에디터에서 발생한 에러를 함께 해결하다가 이 사실을 알게 되었습니다.

NestJS가 좀 더 안정적이 되기를 바라며 이 글을 마칩니다.

2024-10-20

bison 없이 flex 만 사용하기

https://github.com/vimkim/flex-without-bison

오늘은 bison 없이 flex만으로 토크나이저를 만들어 사용하는 방법을 학습했다.

볼 수 있는 대부분의 학습 자료들은 모두 flex와 bison을 동시에 사용하기 때문에, 그 중간에 있는 레이어에 대한 나의 이해가 부족하게 느껴졌다.

중간 단계에서 어떤 과정이 일어나는지에 대한 명확한 이해가 없으니 제대로 사용하는 방법을 모르는 느낌이 들었다.

따라서 bison 없이 오로지 flex만을 사용하고, flex가 생성한 lex.yy.c를 사용하는 간단한 c 프로그램을 만들어서 구조와 원리를 이해하려고 노력했다.

flex -d -Cf -b --reentrant $(FLEX_FILE)

덕분에 flex에 부여할 수 있는 다양한 옵션에 대해 알게 되었다.

gdb를 통해서 YY_INPUT 등 다양한 flex 매크로와 함수가 어떻게 동작하는지 감을 잡고자 했다.

아쉬운 점은 gdb가 macro가 순차적으로 어떻게 실행되는지 보여주지 않고 바로 next로 넘어가 버리기 때문에 조금 불편하다는 점이 있다.

디버거를 사용할 때, -g, -ggdb 옵션과 -g3 옵션이 서로 어떻게 다른지도 자세히 알아보고 싶다.

계속 업데이트 해볼 예정이다.

nest-cli new vs. git clone typescript-starter

flex를 보다가 갑자기 nest가 나와서 뜬금 없지만, 예전에 하던 프로젝트가 문득 생각나서 갑작스레 다시 한번 살펴보게 되었다.

nest new와 nest typescript-starter의 차이점에 대해 궁금했다.

공식 문서에는 분명 둘 다 동일한 역할을 한다고 적혀있었으나, 실제 행동은 다르다.

예를 들어, nest new로 생성한 프로젝트는 eslint ‘^9.0.0’ 버전이 package.json에 적혀 있었고,

git clone https://github.com/nestjs/typescript-starter.git project-name

위 명령어를 통해 생성한 프로젝트는 eslint 8이 package.json에 명시되어 있었고, 오류 없이 동작했다.

nest new에서 eslint를 돌렸을 때는 한창 breaking change의 문제인 flat config 등등 때문에 제대로 동작을 하지 않았다. 과도기에 있는 업데이트가 아직 unstable한 것 같았다.

그렇다고 typescript-starter가 업데이트가 느린 것도 아니었다. 분명 3일 전에 업데이트가 되었고, 많은 버그들이 수정되어 있었다.

현업에서는 조금 더 stable한 git clone을 분명 선호할 것 같았다.

시간이 나면 둘을 다운 받아서 어떤 점이 다른지 명확히 비교를 해보려고 한다.

이에 대한 자세한 분석을 해볼 예정이다.

2024-10-19 회고: 블로그 생성

오늘 https://vimkim.dev 도메인을 사고 blog를 이주했다.

이번 기회에 rust와 mdbook과 더 친해지고 싶어서 이번에 사용해보기로 했다.

mkdocs와 hugo와는 다른 매력이 있다.

문서화를 위한 도구지만 블로그로도 나쁘지 않은 포맷인 것 같아 이번에 시도해본다.

아주 간단한 조정만으로도 보기 좋아서, 개발 블로그를 만들어보고 싶은 사람이 있다면 한번 사용해보는 것을 추천해보고 싶다.