Skip to content

Commit

Permalink
add diff3 support (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
tronikelis authored Nov 2, 2024
1 parent ee71476 commit 09d2b76
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 13 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: ci

on:
push

jobs:
ci:
runs-on: ubuntu-latest
steps:
- name: Cloning repo
uses: actions/checkout@v4

- name: Run tests
run: "./run_tests.sh"

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ You can customize these colors, I just picked something at random :P
## Features
- [x] highlights
- [x] resolving conflicts
- [ ] diff3 style (FYI I currently don't have this enabled myself)
- [x] diff3 style

## User commands

Expand Down
49 changes: 37 additions & 12 deletions lua/conflict-marker/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ local M = {}
local CONFLICT_START = "^<<<<<<<"
local CONFLICT_END = "^>>>>>>>"
local CONFLICT_MID = "^=======$"
local CONFLICT_BASE = "^|||||||"

local HL_CONFLICT_OURS = "ConflictOurs"
local HL_CONFLICT_THEIRS = "ConflictTheirs"
Expand Down Expand Up @@ -144,7 +145,7 @@ function Conflict:conflict_range()
end)

if from == 0 or to == 0 then
return nil, nil
return
end

self:in_buf(function()
Expand All @@ -161,51 +162,75 @@ function Conflict:conflict_range()
end)

if not in_range then
return nil, nil
return
end

return from, to
end

function Conflict:choose_ours()
local from, to = self:conflict_range()
local from, to = self:conflict_range_without_base()
if not from or not to then
return
end

local start = utils.target_in_range(from, to, self:two_way_search(CONFLICT_START))
local ending = utils.target_in_range(from, to, self:two_way_search(CONFLICT_MID))
if not start or not ending then
local mid = utils.target_in_range(from, to, self:two_way_search(CONFLICT_MID))
if not start or not mid then
return
end

vim.api.nvim_buf_set_lines(self.bufnr, start - 1, start, true, {})
-- offset by -1 because we deleted one line above
vim.api.nvim_buf_set_lines(self.bufnr, ending - 2, to - 1, true, {})
vim.api.nvim_buf_set_lines(self.bufnr, mid - 2, to - 1, true, {})
end

function Conflict:choose_theirs()
local from, to = self:conflict_range()
local from, to = self:conflict_range_without_base()
if not from or not to then
return
end

local start = utils.target_in_range(from, to, self:two_way_search(CONFLICT_MID))
local mid = utils.target_in_range(from, to, self:two_way_search(CONFLICT_MID))
local ending = utils.target_in_range(from, to, self:two_way_search(CONFLICT_END))
if not start or not ending then
if not mid or not ending then
return
end

vim.api.nvim_buf_set_lines(self.bufnr, ending - 1, ending, true, {})
vim.api.nvim_buf_set_lines(self.bufnr, from - 1, start, true, {})
vim.api.nvim_buf_set_lines(self.bufnr, from - 1, mid, true, {})
end

function Conflict:choose_both()
---@return integer?, integer?
function Conflict:conflict_range_without_base()
local from, to = self:conflict_range()
if not from or not to then
return
end

local base = utils.target_in_range(from, to, self:two_way_search(CONFLICT_BASE))
if not base then
return from, to
end

local mid = utils.target_in_range(from, to, self:two_way_search(CONFLICT_MID))
if not mid then
return
end

vim.api.nvim_buf_set_lines(self.bufnr, base - 1, mid - 1, true, {})

to = to - (mid - base)

return from, to
end

function Conflict:choose_both()
local from, to = self:conflict_range_without_base()
if not from or not to then
return
end

local start = utils.target_in_range(from, to, self:two_way_search(CONFLICT_START))
local mid = utils.target_in_range(from, to, self:two_way_search(CONFLICT_MID))
local ending = utils.target_in_range(from, to, self:two_way_search(CONFLICT_END))
Expand All @@ -220,7 +245,7 @@ function Conflict:choose_both()
end

function Conflict:choose_none()
local from, to = self:conflict_range()
local from, to = self:conflict_range_without_base()
if not from or not to then
return
end
Expand Down
11 changes: 11 additions & 0 deletions run_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

(
cd test || exit
docker build -t tronikel/conflict-marker.nvim-test .
)

docker run --rm \
-v ./lua:/root/.config/nvim/lua/ \
-v ./test:/root/test/ \
tronikel/conflict-marker.nvim-test:latest
5 changes: 5 additions & 0 deletions test/.busted
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
return {
_all = {
lua = "./lua.sh",
},
}
17 changes: 17 additions & 0 deletions test/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM nickblah/luajit:2-luarocks

RUN apt-get update && apt-get install -y build-essential

RUN luarocks install busted
RUN echo "$(luarocks path --bin)" >> ~/.profile

# install neovim
RUN <<EOF
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz
rm -rf /opt/nvim
tar -C /opt -xzf nvim-linux64.tar.gz
EOF

ENV PATH="$PATH:/opt/nvim-linux64/bin"

CMD ["/bin/bash", "-c", "cd ~/test && busted ."]
3 changes: 3 additions & 0 deletions test/lua.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

nvim -c "set loadplugins" -l "$@"
160 changes: 160 additions & 0 deletions test/main_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
describe("main", function()
local nvim
local lines

local exec_lua = function(fn, ...)
return vim.fn.rpcrequest(nvim, "nvim_exec_lua", fn, { ... })
end

before_each(function()
lines = {
[[<<<<<<< HEAD]],
[[local value = 5 + 7]],
[[print(value)]],
[[print(string.format("value is %d", value))]],
[[=======]],
[[local value = 1 - 1]],
[[>>>>>>> new_branch]],
}

nvim = vim.fn.jobstart({ "nvim", "--embed", "--headless" }, { rpc = true })
exec_lua([[require("conflict-marker").setup()]])
end)

after_each(function()
vim.fn.jobstop(nvim)
end)

for _, prepare in ipairs({
{
"diff2",
function()
lines = {
[[<<<<<<< HEAD]],
[[local value = 5 + 7]],
[[print(value)]],
[[print(string.format("value is %d", value))]],
[[=======]],
[[local value = 1 - 1]],
[[>>>>>>> new_branch]],
}
end,
},
{
"diff3",
function()
lines = {
[[<<<<<<< HEAD]],
[[local value = 5 + 7]],
[[print(value)]],
[[print(string.format("value is %d", value))]],
[[||||||| 229039e]],
[[local value = 1 + 1]],
[[=======]],
[[local value = 1 - 1]],
[[>>>>>>> new_branch]],
}
end,
},
}) do
describe("with " .. prepare[1], function()
before_each(function()
prepare[2]()
exec_lua(
[[
vim.api.nvim_buf_set_lines(0, 0, -1, true, ({...})[1])
vim.cmd("doautocmd BufReadPost")
]],
lines
)
end)

it("Conflict ours works", function()
local result = exec_lua([[
vim.cmd("Conflict ours")
return vim.api.nvim_buf_get_lines(0, 0, -1, true)
]])

assert.is_same(result, {
[[local value = 5 + 7]],
[[print(value)]],
[[print(string.format("value is %d", value))]],
})
end)

it("Conflict theirs works", function()
local result = exec_lua([[
vim.cmd("Conflict theirs")
return vim.api.nvim_buf_get_lines(0, 0, -1, true)
]])

assert.is_same(result, {
[[local value = 1 - 1]],
})
end)

it("Conflict both works", function()
local result = exec_lua([[
vim.cmd("Conflict both")
return vim.api.nvim_buf_get_lines(0, 0, -1, true)
]])

assert.is_same(result, {
[[local value = 5 + 7]],
[[print(value)]],
[[print(string.format("value is %d", value))]],
[[local value = 1 - 1]],
})
end)

it("Conflict none works", function()
local result = exec_lua([[
vim.cmd("Conflict none")
return vim.api.nvim_buf_get_lines(0, 0, -1, true)
]])

assert.is_same(result, { "" })
end)
end)
end

it("selects conflict under cursor", function()
lines = {
[[<<<<<<< HEAD]],
[[ours]],
[[=======]],
[[theirs]],
[[>>>>>>> new_branch]],
[[<<<<<<< HEAD]],
[[ours2]],
[[=======]],
[[theirs2]],
[[>>>>>>> new_branch]],
}

local result = exec_lua(
[[
local lines = ({...})[1]
vim.api.nvim_buf_set_lines(0, 0, -1, true, lines)
vim.cmd("doautocmd BufReadPost")
vim.api.nvim_win_set_cursor(0, { #lines, 0 })
vim.cmd("Conflict ours")
return vim.api.nvim_buf_get_lines(0, 0, -1, true)
]],
lines
)

assert.is_same(result, {
[[<<<<<<< HEAD]],
[[ours]],
[[=======]],
[[theirs]],
[[>>>>>>> new_branch]],
[[ours2]],
})
end)
end)

0 comments on commit 09d2b76

Please sign in to comment.