elsa in mac

nvim - Neorg Index.norg 파일의 summary 자동 업데이트 본문

Mac(OS X)/Terminal

nvim - Neorg Index.norg 파일의 summary 자동 업데이트

elsa in mac 2023. 12. 27. 11:34

Org-mode 는 Emacs 편집기에서 사용되는 강력한 마크업 언어 및 툴이죠. 
터미널 에뮬레이터를 사용하는 분들 중에는 vim 이나 nvim을 사용하는 분들이 많지만, Org-mode를 사용하기 위해 Emacs 사용을 시도하는 분들이 있을 만큼 매력적인 솔루션 입니다. 

이러한 열망은 nvim 쪽에도 영향을 주어, org-mode를 사용할 수 있는 nvim plugin 들이 만들어 졌습니다. nvim-orgmodeNeorg 라는 플러그인이 대표적 입니다.  개인적으로는 Neorg를 사용하고 있는데, nvim 유저에게 보다 친숙한 인터페이스를 갖추고 있고, 사용하기 쉬우며 필요한 요소들을 잘 갖추고 있기 때문입니다. 물론 계속 진화하고 있기도 하구요.

Neorg에 대한 소개 및 사용법은 총 5개의 영상으로 구성된 아래의 youtube 채널을 참고 하시면 됩니다.  

 

아래는 Neorg 플러그 인을 설치하고, 사용하는 예 입니다. 

Notion, Obsidian, OneNote등 note-taking, todo, journal 등을 관리할 수 있는 강력한 GUI 앱들이 많이 있지만, 터미널에서 작업이나 업무에 집중할 때, window를 많이 띄워 두는 것이 불편한 경우에 많은 도움이 됩니다.

헌데, 한가지 치명적인 약점이 있습니다. 사용자가 여러 category로 작성한 norg 파일들을 summary 기능을 이용하여 인덱스를 만들어 주는 기능이 있기는 한데, 이게 자동으로 업데이트가 되지 않습니다.

새로운 norg 파일을 추가하거나, 이미 존재하는 norg 파일의 카테고리를 바꾸거나 혹은 새로 만들거나 했을 때, index.norg 파일을 불러 들인 후, 기존의 정보를 삭제하고 다시 생성을 해 줘야 하지요. 그냥 그렇게 하면 되기는 하지만 매 번 수 작업을 해줘야 한다는 것이 은근 귀찮은 일 입니다.  그래서 자동으로 업데이트 할 수 있는 코드를 넣어 주었는데요,  

아래는 index.norg 파일을 불러 들였을때, 자동으로 summary를 업데이트 하는 코드입니다.  

  
function Norg_auto_indexing()
  -- async timer : sleep
  local function sleep(ms, callback)
    vim.fn.timer_start(ms, function()
      callback()
    end)
  end

  local line_count         = vim.fn.line("$")
  local target_pattern     = "* Index"
  local target_line_number = nil
  local start_index        = 0

  for i = 1, line_count do
    local line_content = vim.fn.getline(i)
    local found_start  = string.find(tostring(line_content), target_pattern)
    if found_start then
      start_index        = found_start
      target_line_number = i
      break
    end
  end

  -- * Index 헤딩 타이틀이 있는 경우
  if target_line_number then
    vim.api.nvim_win_set_cursor(0, {target_line_number, start_index - 1})

    if line_count > target_line_number then
      vim.cmd('normal! j')
      vim.cmd('normal! VG')
      vim.cmd('normal! d')
    end

    vim.cmd("Neorg generate-workspace-summary")
  -- * Index 타이틀이 포함되어 있지 않은 경우..
  else
    if line_count == 9 then
      vim.api.nvim_buf_set_lines(0, line_count, line_count, false, {'', ''})
      vim.api.nvim_buf_set_lines(0, line_count + 1, line_count + 1, false, {'* Index'})
      vim.api.nvim_command('normal! Gk')

      vim.cmd("Neorg generate-workspace-summary")
    end
  end

  -- 내용이 변경되었으므로 자종 저장
  sleep(200, function()
    vim.cmd("w")
  end)

  -- summary 중 [index] 가 포함된 라인을 제거 한다.
  line_count     = vim.fn.line("$")
  target_pattern = "%[Index%]"
  for i = line_count, 1, -1 do
    local line_content = vim.fn.getline(i)
    local index_start = string.find(tostring(line_content), target_pattern)
    if index_start then
      vim.api.nvim_buf_set_lines(0, i-1, i, false, {})
    end
  end
end

-- autocmd 등록
-- BufRead는 파일이 열린 후를 의미한다.
vim.cmd [[
augroup norg_auto_indexing
  autocmd!
  autocmd BufRead index.norg lua Norg_auto_indexing()
augroup END
]]

source.lua
0.00MB

요약하자면, index.norg 파일이 열리면, Norg_auto_indexing() 함수를 자동으로 호출하는 구조 입니다. Norg_auto_indexing() 함수는 * Index 가 포함된 라인을 찾고 이 하 모든 라인을 제거한 후 다시 summary를 만들게 됩니다. 만약 * Index가 없다면 * Index 헤드 타이틀을 만들고, 그 밑으로 summay를 만들게 되죠. Event Trigger가 BufRead이기 때문에 해당 버퍼에 열릴 때 실행되게 됩니다. 그리고, summary에는 각 하위 디렉토리의 index 들도 링크로 생성되게 되는데, 이 것은 제거합니다.  

Nvim 의 설정이 사용자 마다 다르기 때문에, 위의 코드를 어디에 추가 해야 할지는 각자의 환경에 따라 다를 수 있지만, 일단은 init.lua에 포함하고 확인하면 됩니다.

공유하기 링크
Comments