TL;DR

  • ์ฝ๊ธฐ ๋ชจ๋“œ์—์„œ ์ฃฝ์–ด๋ฒ„๋ฆฌ๋Š” vim ๋‚ด๋น„๊ฒŒ์ด์…˜์„ ๋˜์‚ด๋ฆฌ๋Š” Obsidian ํ”Œ๋Ÿฌ๊ทธ์ธ
  • j/kยทd/u ์Šคํฌ๋กค๊ณผ f ๋งํฌ ํžŒํŠธ๋กœ ๋งˆ์šฐ์Šค ์—†์ด ์ฝ๊ธฐ ๋ชจ๋“œ ํƒ์ƒ‰
  • ์›์ž‘์ž ์Šน์ธ์„ ๋ฐ›์•„ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์Šคํ† ์–ด์— ์ •์‹ ๋“ฑ๋ก

AI-assisted


Obsidian์—์„œ vim ํ‚ค ๋ฐ”์ธ๋”ฉ์„ ์ผœ๋†“๊ณ  ์“ด๋‹ค. ํŽธ์ง‘ํ•  ๋•Œ๋Š” j, k๋กœ ์ž˜ ๋Œ์•„๋‹ค๋‹ˆ๋Š”๋ฐ, ์ฝ๊ธฐ ๋ชจ๋“œ๋กœ ๋ฐ”๊พธ๋Š” ์ˆœ๊ฐ„ ๋‹ค ๋จนํ†ต์ด ๋œ๋‹ค.
๊ธ€์„ ์ฝ์„ ๋•Œ๋Š” ๊น”๋”ํ•˜๊ฒŒ ์ฝ๊ธฐ ๋ชจ๋“œ๋กœ ๋ณด๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๊ฐ€ ๋” ๋งŽ์•„์„œ ์ฝ๋Š” ์ค‘์—๋„ ํ‚ค๋ณด๋“œ๋กœ ํœ™ํœ™ ๋„˜๊ธฐ๊ณ  ์‹ถ์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ฐพ์•„๋ดค๋”๋‹ˆ ๋งˆ์นจ ๋”ฑ ๋งž๋Š” ๊ฒŒ ์žˆ์—ˆ๋‹ค. vim-scrolling์ด๋ผ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ธ๋ฐ, ์ฝ๊ธฐ ๋ชจ๋“œ์—์„œ๋„ j/k๋กœ ์Šคํฌ๋กคํ•˜๊ณ  gg, G๋กœ ์œ„์•„๋ž˜ ๋๊นŒ์ง€ ์ ํ”„๊ฐ€ ๋œ๋‹ค. ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋งŒ ๋”ฑ ๋“ค์–ด์žˆ์–ด์„œ ํ•œ์ฐธ ์ž˜ ์ผ๋‹ค.

๋‹ค๋งŒ ์“ฐ๋‹ค ๋ณด๋‹ˆ ๊ธฐ์กด ํฌ๋กฌ์—์„œ ์‚ฌ์šฉํ•˜๋˜ Vimium ์ต์Šคํ…์…˜์— ๋น„ํ•˜๋ฉด ์‚ด์ง ์•„์‰ฌ์šด ๊ฒŒ ๋‘ ๊ฐœ ์žˆ์—ˆ๋‹ค.

ํ•˜๋‚˜๋Š” ๋ฐ˜ ํŽ˜์ด์ง€ ์Šคํฌ๋กค. Ctrl+D/Ctrl+U๋กœ๋งŒ ๋˜๋Š”๋ฐ ๋‚˜๋Š” ๊ทธ๋ƒฅ d/u๋กœ ๋ˆ„๋ฅด๋Š” ๊ฒŒ ํŽธํ–ˆ๋‹ค. ์ฝ๊ธฐ ๋ชจ๋“œ์—” ์–ด์ฐจํ”ผ ํŽธ์ง‘ ๊ธฐ๋Šฅ์ด ์—†์œผ๋‹ˆ d, u๋กœ ํ•ด๋„ ํฐ ๋ฌธ์ œ๊ฐ€ ์—†์„ ๊ฒƒ ๊ฐ™์•˜๋‹ค (์›์ž‘์žํ•œํ…Œ ์ถ”๊ฐ€ํ•ด๋‹ฌ๋ผ๊ณ  ์ด์Šˆ๋„ ๋‚จ๊ฒจ๋ดค๋Š”๋ฐ ์›๋ณธ์€ vim ํ‘œ์ค€์— ์ถฉ์‹คํ•˜๊ฒŒ ๋‘๊ณ  ์‹ถ๋‹ค๋Š” ๋‹ต์ด ์™”๋‹ค)

๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋งํฌ์˜€๋‹ค. ์ฝ๋‹ค๊ฐ€ ๋งํฌ๋ฅผ ๋ˆ„๋ฅด๋ ค๋ฉด ๊ฒฐ๊ตญ ๋งˆ์šฐ์Šค๋กœ ์†์ด ๊ฐ”๋‹ค. ํฌ๋กฌ์—์„œ Vimium์œผ๋กœ f ๋ˆŒ๋Ÿฌ์„œ ๋งํฌ๋งˆ๋‹ค ๋ผ๋ฒจ ๋„์šฐ๊ณ  ํ‚ค๋ณด๋“œ๋กœ ์ ํ”„ํ•˜๋˜ ๊ฒŒ ์›Œ๋‚™ ํŽธํ–ˆ์–ด์„œ ๊ทธ ๋А๋‚Œ์„ ์ฝ๊ธฐ ๋ชจ๋“œ์—๋„ ๋„ฃ๊ณ  ์‹ถ์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‘ ๊ฐœ๋ฅผ ๋ถ™์˜€๋‹ค.

  • Ctrl ์—†์ด d/u๋กœ๋„ ๋ฐ˜ ํŽ˜์ด์ง€ ์Šคํฌ๋กค
  • f๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ™”๋ฉด์— ๋ณด์ด๋Š” ๋งํฌ๋งˆ๋‹ค ๋ผ๋ฒจ์ด ๋œจ๊ณ  ๋ผ๋ฒจ์„ ์ž…๋ ฅํ•˜๋ฉด ๊ทธ ๋งํฌ๋กœ ์ ํ”„. ๋‚ด๋ถ€ ๋ฌธ์„œ๋Š” ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊นŒ์ง€ ๋œจ๊ณ , Enter๋กœ ์ด๋™(์™ธ๋ถ€ ๋งํฌ๋Š” URL์ด ์—ด๋ฆฐ๋‹ค), Esc๋กœ ์ทจ์†Œ.

๊ฒฐ๊ณผ์ ์œผ๋กœ ์ฝ๋Š” ๋™์•ˆ ๋งˆ์šฐ์Šค์— ์† ์•ˆ ๋Œ€๊ณ  vim ํ‚ค๋งŒ์œผ๋กœ ๊ฑฐ์˜ ๋‹ค ๋œ๋‹ค. ๋”ฑ ์›ํ•˜๋˜ ๊ทธ๋ฆผ์ด๋‹ค.


์ปค๋ฎค๋‹ˆํ‹ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋“ฑ๋ก๊นŒ์ง€

๊ฐœ์ธ์šฉ fork๋กœ ํ•œ๋™์•ˆ ์“ฐ๋‹ค๊ฐ€ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์Šคํ† ์–ด์— ์ •์‹์œผ๋กœ ์˜ฌ๋ ธ๋‹ค. ์ด์ œ Vim Reading Navigation์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๊ฒ€์ƒ‰ํ•ด์„œ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

fork๋ฅผ ์Šคํ† ์–ด์— ์˜ฌ๋ฆฌ๋Š” ๊ฒƒ ์ž์ฒด๋Š” ์ •์ƒ ๊ฒฝ๋กœ๋‹ค. ์˜ฌ๋ฆฌ๊ธฐ ์ „์— ์„ธ ๊ฐ€์ง€๋ฅผ ํ™•์ธํ–ˆ๋‹ค.

  • ๋ผ์ด์„ ์Šค: ์›๋ณธ์ด 0BSD๋ผ ์ˆ˜์ •ยท์žฌ๋ฐฐํฌ์— ์ œ์•ฝ์ด ์—†๋‹ค
  • fork ์ •์ฑ…: Developer Policies์ƒ ์›์ž‘์ž์˜ ๊ณต๊ฐœ ์Šน์ธ์ด ์žˆ๊ฑฐ๋‚˜, ์—ฐ๋ฝ์ด ๋‹ฟ์ง€ ์•Š๊ณ  ์›๋ณธ์ด 6๊ฐœ์›” ์ด์ƒ ๋ฌดํ™œ๋™์ด๋ฉด ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค. ์–ด๋А ์ชฝ์ด๋“  ์›์ž‘์ž ํฌ๋ ˆ๋”ง์€ ํ•„์ˆ˜
  • ์„ ๋ก€: Slides Extended์ฒ˜๋Ÿผ ์Šคํ† ์–ด์— ์Šน์ธ๋œ fork๊ฐ€ ์ด๋ฏธ ์žˆ๋‹ค

์›์ž‘์ž ์Šน์ธ์€ ์›๋ณธ repo์— issue๋กœ ์š”์ฒญํ–ˆ๋‹ค. ์˜ˆ์ „์— ๋‚จ๊ธด ๊ธฐ๋Šฅ ์ œ์•ˆ issue๋ฅผ ์ธ์šฉํ•ด upstream ๊ธฐ์—ฌ๋ฅผ ๋จผ์ € ์‹œ๋„ํ–ˆ๋˜ ํ๋ฆ„์„ ๋ณด์—ฌ์ฃผ๊ณ  โ€œapproved ํ•œ๋งˆ๋””๋ฉด ๋œ๋‹คโ€๊ณ  ์ ์–ด ์›์ž‘์ž์˜ ๋ถ€๋‹ด์„ ์ค„์˜€๋‹ค. ์ดํ‹€ ๋งŒ์— ์Šน์ธ ์ฝ”๋ฉ˜ํŠธ๋ฅผ ๋ฐ›์•˜๊ณ  ๊ทธ permalink๊ฐ€ ์Šน์ธ ์ฆ๊ฑฐ๊ฐ€ ๋œ๋‹ค.

๋ฆด๋ฆฌ์ฆˆ ์ž๋™ํ™”

๋ฆด๋ฆฌ์ฆˆ๋Š” ๋กœ์ปฌ ๋ช…๋ น์—์„œ ์‹œ์ž‘ํ•ด CI๊ฐ€ ๋๊นŒ์ง€ ์ฒ˜๋ฆฌํ•œ๋‹ค.

npm version patch               # ๋ฒ„์ „ ๋™๊ธฐํ™” + ํƒœ๊ทธ ์ƒ์„ฑ
git push origin master --tags   # ํƒœ๊ทธ push โ†’ release workflow ํŠธ๋ฆฌ๊ฑฐ
  • ๋ฒ„์ „ ๋™๊ธฐํ™”: npm version์ด package.json์˜ version ์Šคํฌ๋ฆฝํŠธ ํ›…์œผ๋กœ version-bump.mjs๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. manifest.json์˜ ๋ฒ„์ „์„ ์˜ฌ๋ฆฌ๊ณ  versions.json์— "์ƒˆ ๋ฒ„์ „": minAppVersion ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค
  • ํƒœ๊ทธ ๊ทœ์น™: Obsidian์€ release ํƒœ๊ทธ์™€ manifest ๋ฒ„์ „์ด ์ผ์น˜ํ•ด์•ผ ํ•œ๋‹ค. .npmrc์— tag-version-prefix=""๋ฅผ ๋„ฃ์–ด ํƒœ๊ทธ๊ฐ€ v1.1.1์ด ์•„๋‹ˆ๋ผ 1.1.1๋กœ ์ƒ๊ธฐ๊ฒŒ ํ–ˆ๋‹ค
  • ๋นŒ๋“œ ๊ฒ€์ฆ: pushยทPR๋งˆ๋‹ค lint workflow๊ฐ€ Node 20ยท22 matrix์—์„œ ๋นŒ๋“œ์™€ eslint๋ฅผ ๋Œ๋ฆฐ๋‹ค

ํƒœ๊ทธ๊ฐ€ push๋˜๋ฉด release workflow๊ฐ€ ์ด์–ด๋ฐ›๋Š”๋‹ค. ํ•ต์‹ฌ๋งŒ ๋ฐœ์ทŒํ•˜๋ฉด ์ด๋ ‡๋‹ค.

on:
    push:
        tags: ["*"]
permissions:
    contents: write
    attestations: write
    id-token: write
steps:
    # actions/checkout โ†’ setup-node โ†’ npm ci โ†’ npm run build
    - uses: actions/attest-build-provenance@v2
      with:
          subject-path: |
              main.js
              styles.css
    - run: gh release create "${GITHUB_REF_NAME}" main.js manifest.json styles.css
  • ๋นŒ๋“œ: npm run build๊ฐ€ tsc -noEmit ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ํ†ต๊ณผํ•ด์•ผ esbuild production ๋ฒˆ๋“ค์„ ๋งŒ๋“ ๋‹ค
  • ์ถœ์ฒ˜ ์ฆ๋ช…: attest-build-provenance๊ฐ€ ๋นŒ๋“œ ์‚ฐ์ถœ๋ฌผ์— attestation์„ ์ฒจ๋ถ€ํ•œ๋‹ค. ์Šคํ† ์–ด ์ž๋™ ๋ฆฌ๋ทฐ๊ฐ€ ํ™•์ธํ•˜๋Š” ํ•ญ๋ชฉ์ด๊ณ  gh attestation verify main.js --repo DS-argus/vim-reading-nav๋กœ ๋ˆ„๊ตฌ๋‚˜ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค
  • release ์ƒ์„ฑ: ํƒœ๊ทธ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ release๋ฅผ ๋งŒ๋“ค๊ณ  main.jsยทmanifest.jsonยทstyles.css๋ฅผ ์ž์‚ฐ์œผ๋กœ ์ฒจ๋ถ€ํ•œ๋‹ค

์ œ์ถœ๊ณผ ๋ฆฌ๋ทฐ ๋Œ€์‘

์ œ์ถœ์€ community.obsidian.md์— ๋กœ๊ทธ์ธํ•ด repo URL์„ ์›น์œผ๋กœ ๋„ฃ์œผ๋ฉด ๋๋‚œ๋‹ค. obsidian-releases repo์— community-plugins.json PR์„ ๋ณด๋‚ด๋˜ ์˜› ๋ฐฉ์‹์€ ํ๊ธฐ๋๊ณ  ์ง€๊ธˆ ๊ทธ ํŒŒ์ผ์€ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์ž๋™ ๋ฏธ๋Ÿฌ๋ง๋˜๋Š” ์‚ฐ์ถœ๋ฌผ์ด๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ id๋Š” ์ „์—ญ์—์„œ ์œ ์ผํ•ด์•ผ ํ•˜๊ณ  obsidian์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋„ฃ์„ ์ˆ˜ ์—†๋‹ค.

์ œ์ถœํ•˜๋ฉด ์ž๋™ ๋ฆฌ๋ทฐ(Scorecard)๊ฐ€ ๋ˆ๋‹ค. ์‹ค์ œ๋กœ ๋ฐ›์€ ํ”ผ๋“œ๋ฐฑ์€ 3๊ฑด์ด์—ˆ๋‹ค.

  • Issues disabled: fork๋Š” Issues ํƒญ์ด ๊ธฐ๋ณธ์œผ๋กœ ๊บผ์ ธ ์žˆ๋‹ค. gh repo edit --enable-issues๋กœ ํ™œ์„ฑํ™”
  • README links to another repository with the same name: upstream๊ณผ repo ์ด๋ฆ„์ด ๊ฐ™์•„ ์ƒ๊ธด ์˜คํƒ. repo๋ฅผ ํ”Œ๋Ÿฌ๊ทธ์ธ id์ธ vim-reading-nav๋กœ renameํ•˜๋‹ˆ ๋ฐœ๋™ ์กฐ๊ฑด์ด ์‚ฌ๋ผ์กŒ๋‹ค. GitHub ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋•์— ๊ธฐ์กด ๋งํฌ๋„ ์•ˆ์ „ํ•˜๋‹ค. ๋‹จ, ๊ตฌ ์ด๋ฆ„์œผ๋กœ ์ƒˆ repo๋ฅผ ๋งŒ๋“ค๋ฉด ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๊ฐ€ ๋Š๊ธด๋‹ค
  • Missing artifact attestations: ์œ„์˜ release workflow์— attestation ๋‹จ๊ณ„๋ฅผ ์ถ”๊ฐ€ํ•ด ํ•ด๊ฒฐ

์ฃผ์˜: ๊ณต์‹ ๋ฌธ์„œ์— ์—†๋Š” ๊ฒƒ๋“ค

  • fork repo๋Š” ์†Œ์œ ์ž๊ฐ€ Actions ํƒญ์—์„œ workflow๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ผœ๊ธฐ ์ „๊นŒ์ง€ ์–ด๋–ค ํŠธ๋ฆฌ๊ฑฐ๋„ ๋Œ์ง€ ์•Š๋Š”๋‹ค
  • ์ œ์ถœ ๋ชฉ๋ก์˜ Request review๋Š” ์ž๋™ ์žฌ๊ฒ€์‚ฌ๊ฐ€ ์•„๋‹ˆ๋ผ ์‚ฌ๋žŒ ๋ฆฌ๋ทฐ ์š”์ฒญ์ด๋‹ค. ์ž๋™ ๋ฆฌ๋ทฐ๋ฅผ ๋‹ค์‹œ ๋Œ๋ฆฌ๋ ค๋ฉด ๋ฒ„์ „์„ ์˜ฌ๋ฆฐ ์ƒˆ release๊ฐ€ ํ•„์š”ํ•˜๋‹ค
  • Publish ํ›„ ์•ฑ ๊ฒ€์ƒ‰์— ๋œจ๊ธฐ๊นŒ์ง€ ๋ฐฐ์น˜ ์ „ํŒŒ๊ฐ€ ๋ช‡ ๋‹จ๊ณ„ ์žˆ๋‹ค. ์‹ค์ธก์œผ๋กœ 4-5์‹œ๊ฐ„ ๊ฑธ๋ ธ๋‹ค

์จ๋ณด๋ ค๋ฉด

์ด์ œ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์„ค์น˜ํ•˜๋ฉด ๋œ๋‹ค. ์„ค์ • โ†’ Community plugins โ†’ Browse์—์„œ Vim Reading Navigation์„ ๊ฒ€์ƒ‰ํ•œ๋‹ค.

์ง์ ‘ ๋นŒ๋“œํ•ด์„œ ์“ฐ๋Š” ๋ฐฉ๋ฒ•๋„ ๊ทธ๋Œ€๋กœ ์žˆ๋‹ค.

git clone https://github.com/DS-argus/vim-reading-nav
cd vim-reading-nav
npm install
npm run build

๋นŒ๋“œํ•˜๋ฉด ๋‚˜์˜ค๋Š” main.js, manifest.json, styles.css๋ฅผ ๋ณผํŠธ์˜ .obsidian/plugins/vim-reading-nav/์— ๋„ฃ๊ณ  Obsidian์„ ๋‹ค์‹œ ์ผœ๋ฉด ๋œ๋‹ค. ๋‘ ๊ฐ€์ง€๋งŒ ์ผœ์ ธ ์žˆ์œผ๋ฉด ๋œ๋‹ค: Vim key bindings(์„ค์ • โ†’ ์—๋””ํ„ฐ), ๊ทธ๋ฆฌ๊ณ  ๋งํฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์“ฐ๋ ค๋ฉด Page Preview ์ฝ”์–ด ํ”Œ๋Ÿฌ๊ทธ์ธ.