1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
local micro = import("micro")
local buffer = import("micro/buffer")
local config = import("micro/config")
local shell = import("micro/shell")

function gitBlame(bp, args)
  local filePath = bp.Buf.Path
  local currentLine = bp.Cursor.Y + 1 -- Convert to 1-based for cursor position

  if not filePath or filePath == "" then
    micro.InfoBar():Error("No file to blame")
    return
  end

  -- Get the buffer view to access viewport information
  local view = bp:BufView()

  -- Calculate cursor's actual screen row position (accounting for soft wrapping)
  -- Diff() returns the number of screen rows between two SLocs
  local cursorLoc = buffer.Loc(bp.Cursor.X, bp.Cursor.Y)
  local cursorSLoc = bp:SLocFromLoc(cursorLoc)
  local viewportSLoc = view.StartLine
  local cursorScreenRow = bp:Diff(viewportSLoc, cursorSLoc)

  -- Debug: Log calculations (check ~/.config/micro/log.txt with micro -debug)
  micro.Log(string.format("[git-blimey] cursorY=%d, viewportLine=%d, screenRow=%d",
    bp.Cursor.Y, viewportSLoc.Line, cursorScreenRow))

  -- Calculate viewport offset that preserves cursor's screen position
  -- Git-blimey will calculate: viewportStart = viewportOffset + 3
  -- We want: cursor screen row in git-blimey = cursorScreenRow from micro
  -- Therefore: cursorLine - viewportStart = cursorScreenRow
  -- Solving: viewportOffset = cursorLine - cursorScreenRow - 3
  local viewportOffset = bp.Cursor.Y - cursorScreenRow - 3

  -- Debug: Log final calculation
  micro.Log(string.format("[git-blimey] offset=%d (%d-%d-3)",
    viewportOffset, bp.Cursor.Y, cursorScreenRow))

  -- Run git-blimey with calculated viewport offset
  -- Negative offsets are allowed (will be clamped to viewportStart=0 in git-blimey)
  local blimeyCmd = string.format("git-blimey --viewport-offset=%d '%s:%d'", viewportOffset, filePath, currentLine)

  -- Debug: Log command being executed
  micro.Log(string.format("[git-blimey] CMD: %s", blimeyCmd))

  shell.RunInteractiveShell(blimeyCmd, false, false) -- wait=false: return immediately after git-blimey exits

  micro.InfoBar():Message("Launched git-blimey")
end