nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: nvim-lua/plenary.nvim
Pull request #143 (2021-04-20 18:06:08)

added tbl.freeze


Patch:
diff --git a/lua/plenary/tbl.lua b/lua/plenary/tbl.lua
index d1f018c..44de295 100644
--- a/lua/plenary/tbl.lua
+++ b/lua/plenary/tbl.lua
@@ -24,5 +24,17 @@ function tbl.unpack(t, i, j)
   return unpack(t, i or 1, j or t.n or #t)
 end
 
+---Freeze a table. A frozen table is not able to be modified.
+---http://lua-users.org/wiki/ReadOnlyTables
+---@param t table
+---@return table
+function tbl.freeze(t)
+  return setmetatable({}, {
+    __index = t,
+    __newindex = function()
+      error("Attempt to modify frozen table")
+    end
+  })
+end
 
 return tbl


Test patch:
diff --git a/tests/plenary/tbl_spec.lua b/tests/plenary/tbl_spec.lua
new file mode 100644
index 0000000..60faa18
--- /dev/null
+++ b/tests/plenary/tbl_spec.lua
@@ -0,0 +1,27 @@
+local tbl = require('plenary.tbl')
+
+local function should_fail(fun)
+  local stat = pcall(fun)
+  assert(not stat, "Function should have errored")
+end
+
+describe('tbl utilities', function()
+  it('should be able to freeze a table', function()
+    local t = {1, 2, 3}
+    local frozen = tbl.freeze(t)
+    assert(t[1] == frozen[1])
+    assert(t[2] == frozen[2])
+    assert(t[3] == frozen[3])
+
+    should_fail(function()
+      frozen[4] = "thisthis"
+    end)
+
+    should_fail(function()
+      frozen.hello = "asdfasdf"
+    end)
+
+    assert(not frozen[5])
+    assert(not frozen.hello)
+  end)
+end)
Repository: nvim-lua/plenary.nvim
Pull request #288 (2021-12-14 13:46:41)

fix: change `EndOfBuffer` highlight for popups
Fixes nvim-telescope/telescope.nvim#1596

@mrjones2014 does this fix your issue?

l-kershaw: Great, thanks. I'll merge this fix now 🙂

Patch:
diff --git a/lua/plenary/popup/init.lua b/lua/plenary/popup/init.lua
index 49ef913..92dec7f 100644
--- a/lua/plenary/popup/init.lua
+++ b/lua/plenary/popup/init.lua
@@ -386,7 +386,11 @@ function popup.create(what, vim_options)
   end
 
   if vim_options.highlight then
-    vim.api.nvim_win_set_option(win_id, "winhl", string.format("Normal:%s", vim_options.highlight))
+    vim.api.nvim_win_set_option(
+      win_id,
+      "winhl",
+      string.format("Normal:%s,EndOfBuffer:%s", vim_options.highlight, vim_options.highlight)
+    )
   end
 
   -- enter


Test patch:
diff --git a/tests/plenary/popup_spec.lua b/tests/plenary/popup_spec.lua
index 81d7e8d..a02453d 100644
--- a/tests/plenary/popup_spec.lua
+++ b/tests/plenary/popup_spec.lua
@@ -27,7 +27,7 @@ describe("plenary.popup", function()
       highlight = "PopupColor1",
     })
 
-    eq("Normal:PopupColor1", vim.api.nvim_win_get_option(win_id, "winhl"))
+    eq("Normal:PopupColor1,EndOfBuffer:PopupColor1", vim.api.nvim_win_get_option(win_id, "winhl"))
   end)
 
   it("can create a border", function()
Repository: nvim-lua/plenary.nvim
Pull request #347 (2022-04-09 01:44:56)

fix: plenary.path normalize
This aims to fix problems seen in #330.

1. double-slash at the front for tilde-subbed home paths
2. extra `./` in the middle of a path

Conni2461: Thanks :)

Nice the tests show its fixed. Can you now change them and make the code stylua conform. Thanks again
Conni2461: I updated the tests so i can merge this PR.

Again thank you very much for the fix :)

Patch:
diff --git a/lua/plenary/path.lua b/lua/plenary/path.lua
index de68341..dc3f0f3 100644
--- a/lua/plenary/path.lua
+++ b/lua/plenary/path.lua
@@ -88,6 +88,12 @@ local function _normalize_path(filename, cwd)
     return filename
   end
 
+  -- handles redundant `./` in the middle
+  local redundant = path.sep .. "." .. path.sep
+  if filename:match(redundant) then
+    filename = filename:gsub(redundant, path.sep)
+  end
+
   local out_file = filename
 
   local has = string.find(filename, path.sep .. "..", 1, true) or string.find(filename, ".." .. path.sep, 1, true)
@@ -341,7 +347,8 @@ function Path:normalize(cwd)
   self:make_relative(cwd)
 
   -- Substitute home directory w/ "~"
-  self.filename = self.filename:gsub("^" .. path.home, "~" .. path.sep, 1)
+  local removed_path_sep = path.home:gsub(path.sep .. "$", "")
+  self.filename = self.filename:gsub("^" .. removed_path_sep, "~", 1)
 
   return _normalize_path(self.filename, self._cwd)
 end


Test patch:
diff --git a/tests/plenary/path_spec.lua b/tests/plenary/path_spec.lua
index 026feea..e229c55 100644
--- a/tests/plenary/path_spec.lua
+++ b/tests/plenary/path_spec.lua
@@ -211,7 +211,7 @@ describe("Path", function()
       local p = Path:new { home, "./test_file" }
       p.path.home = home
       p._cwd = "/tmp/lua"
-      assert.are.same("~/./test_file", p:normalize())
+      assert.are.same("~/test_file", p:normalize())
     end)
 
     it("can normalize ~ when file is within home directory (no trailing slash)", function()
@@ -219,7 +219,7 @@ describe("Path", function()
       local p = Path:new { home, "./test_file" }
       p.path.home = home
       p._cwd = "/tmp/lua"
-      assert.are.same("~//./test_file", p:normalize())
+      assert.are.same("~/test_file", p:normalize())
     end)
   end)
Repository: nvim-lua/plenary.nvim
Pull request #348 (2022-04-09 18:21:10)

fix: path normalize with one char directories
fix https://github.com/nvim-telescope/telescope.nvim/issues/1833


Patch:
diff --git a/lua/plenary/path.lua b/lua/plenary/path.lua
index dc3f0f3..34607b1 100644
--- a/lua/plenary/path.lua
+++ b/lua/plenary/path.lua
@@ -89,7 +89,7 @@ local function _normalize_path(filename, cwd)
   end
 
   -- handles redundant `./` in the middle
-  local redundant = path.sep .. "." .. path.sep
+  local redundant = path.sep .. "%." .. path.sep
   if filename:match(redundant) then
     filename = filename:gsub(redundant, path.sep)
   end


Test patch:
diff --git a/tests/plenary/path_spec.lua b/tests/plenary/path_spec.lua
index e229c55..b8a1c47 100644
--- a/tests/plenary/path_spec.lua
+++ b/tests/plenary/path_spec.lua
@@ -168,6 +168,12 @@ describe("Path", function()
   end)
 
   describe(":normalize", function()
+    it("can take path that has one character directories", function()
+      local orig = "/home/j/./p//path.lua"
+      local final = Path:new(orig):normalize()
+      assert.are.same(final, "/home/j/p/path.lua")
+    end)
+
     it("can take paths with double separators change them to single separators", function()
       local orig = "/lua//plenary/path.lua"
       local final = Path:new(orig):normalize()
Repository: nvim-lua/plenary.nvim
Pull request #350 (2022-04-09 19:42:20)

Add before_each, after_each for async tests.
Useful when setup/teardown function are asynchronous.

ipod825: @tjdevries @Conni2461
tjdevries: Could you add a test that uses both of these? Like increments a number before an async test and then asserts that they have been run? Something like that.
ipod825: > Could you add a test that uses both of these? Like increments a number before an async test and then asserts that they have been run? Something like that.

Done.

Patch:
diff --git a/lua/plenary/async/init.lua b/lua/plenary/async/init.lua
index f8222fc..71ccd84 100644
--- a/lua/plenary/async/init.lua
+++ b/lua/plenary/async/init.lua
@@ -36,6 +36,8 @@ exports.tests.add_globals = function()
   a.describe = exports.tests.describe
   -- must prefix with a or stack overflow
   a.it = exports.tests.it
+  a.before_each = exports.tests.before_each
+  a.after_each = exports.tests.after_each
 end
 
 exports.tests.add_to_env = function()
@@ -50,6 +52,8 @@ exports.tests.add_to_env = function()
   env.a.describe = exports.tests.describe
   -- must prefix with a or stack overflow
   env.a.it = exports.tests.it
+  a.before_each = exports.tests.before_each
+  a.after_each = exports.tests.after_each
 
   setfenv(2, env)
 end


Test patch:
diff --git a/lua/plenary/async/tests.lua b/lua/plenary/async/tests.lua
index 367b83d..4895773 100644
--- a/lua/plenary/async/tests.lua
+++ b/lua/plenary/async/tests.lua
@@ -10,4 +10,12 @@ M.it = function(s, async_func)
   it(s, util.will_block(async_func))
 end
 
+M.before_each = function(async_func)
+  before_each(util.will_block(async_func))
+end
+
+M.after_each = function(async_func)
+  after_each(util.will_block(async_func))
+end
+
 return M
diff --git a/tests/plenary/async/test_spec.lua b/tests/plenary/async/test_spec.lua
new file mode 100644
index 0000000..6a37309
--- /dev/null
+++ b/tests/plenary/async/test_spec.lua
@@ -0,0 +1,52 @@
+require("plenary.async").tests.add_to_env()
+
+a.describe("a.before_each", function()
+  local counter = 0
+
+  local set_counter_to_one = a.wrap(function(callback)
+    a.util.sleep(5)
+    counter = 1
+  end, 1)
+
+  a.before_each(a.void(function()
+    set_counter_to_one()
+  end))
+
+  a.it("should run in async context", function()
+    counter = counter + 1
+    assert.are.same(counter, 2)
+  end)
+
+  a.it("should run for all tests", function()
+    counter = counter + 2
+    assert.are.same(counter, 3)
+  end)
+end)
+
+a.describe("a.after_each", function()
+  local counter = 0
+
+  local set_counter_to_one = a.wrap(function(callback)
+    a.util.sleep(5)
+    counter = 1
+  end, 1)
+
+  a.after_each(a.void(function()
+    set_counter_to_one()
+  end))
+
+  a.it("should not run before first test", function()
+    counter = counter + 1
+    assert.are.same(counter, 1)
+  end)
+
+  a.it("should run before the second test", function()
+    counter = counter + 2
+    assert.are.same(counter, 3)
+  end)
+
+  a.it("should run before the third test", function()
+    counter = counter + 3
+    assert.are.same(counter, 4)
+  end)
+end)
Repository: nvim-lua/plenary.nvim
Pull request #355 (2022-04-20 22:57:17)

fix (path:normalize): handle filenames with the same prefix as the home directory
Scenario:

home: /home/foo
file: /home/foobar/baz.txt

normalize returned ~/bar/baz.txt instead of /home/foobar/baz.txt


Patch:
diff --git a/data/plenary/filetypes/builtin.lua b/data/plenary/filetypes/builtin.lua
index c533052..ef23d47 100644
--- a/data/plenary/filetypes/builtin.lua
+++ b/data/plenary/filetypes/builtin.lua
@@ -32,6 +32,7 @@ return {
     ['jl'] = 'julia',
     ['coffee'] = 'coffee',
     ['_coffee'] = 'coffee',
+    ['cljd'] = 'clojure',
     ['nix'] = 'nix',
     ['erb'] = 'eruby',
     ['hbs'] = 'handlebars',
@@ -40,7 +41,7 @@ return {
     ['gql'] = 'graphql',
     ['rkt'] = 'racket',
     ['res'] = 'rescript',
-    ['resi'] = 'rescript'
+    ['resi'] = 'rescript',
   },
   file_name = {
     ['cakefile'] = 'coffee',
diff --git a/lua/plenary/path.lua b/lua/plenary/path.lua
index 4a1fd23..2f74885 100644
--- a/lua/plenary/path.lua
+++ b/lua/plenary/path.lua
@@ -349,7 +349,11 @@ function Path:normalize(cwd)
   -- Substitute home directory w/ "~"
   -- string.gsub is not useful here because usernames with dashes at the end
   -- will be seen as a regexp pattern rather than a raw string
-  local start, finish = string.find(self.filename, path.home, 1, true)
+  local home = path.home
+  if string.sub(path.home, -1) ~= path.sep then
+    home = home .. path.sep
+  end
+  local start, finish = string.find(self.filename, home, 1, true)
   if start == 1 then
     self.filename = "~" .. path.sep .. string.sub(self.filename, (finish + 1), -1)
   end


Test patch:
diff --git a/tests/plenary/path_spec.lua b/tests/plenary/path_spec.lua
index 2713532..f5a9097 100644
--- a/tests/plenary/path_spec.lua
+++ b/tests/plenary/path_spec.lua
@@ -235,6 +235,12 @@ describe("Path", function()
       p._cwd = "/tmp/lua"
       assert.are.same("~/test_file", p:normalize())
     end)
+
+    it("handles filenames with the same prefix as the home directory", function()
+      local p = Path:new "/home/test.old/test_file"
+      p.path.home = "/home/test"
+      assert.are.same("/home/test.old/test_file", p:normalize())
+    end)
   end)
 
   describe(":shorten", function()
Repository: nvim-lua/plenary.nvim
Pull request #501 (2023-06-22 17:17:53)

fix: ensure that handlers are emptied after notify_all
Hi guys, I found that the condvar break in the following logic

```lua
local condvar = async.control.Condvar.new()

async.run(function()
    condvar:wait()
end)

async.run(function()
    condvar:wait()
end)

condvar:notify_all()

async.run(function()
    condvar:wait()
end)

-- break: The coroutine failed with this message: cannot resume dead coroutine
condvar:notify_all()
```

After some deeper research, I found that notify_all uses an index to empty the table inside the loop, but misses some elements due to index changed.


Patch:
diff --git a/lua/plenary/async/control.lua b/lua/plenary/async/control.lua
index b9e15c5..3a8a8ed 100644
--- a/lua/plenary/async/control.lua
+++ b/lua/plenary/async/control.lua
@@ -32,10 +32,10 @@ function Condvar:notify_all()
     callback()
   end
 
-  for i = 1, len do
+  for _ = 1, len do
     -- table.remove will ensure that indexes are correct and make "ipairs" safe,
     -- which is not the case for "self.handles[i] = nil"
-    table.remove(self.handles, i)
+    table.remove(self.handles)
   end
 end
 


Test patch:
diff --git a/tests/plenary/async/condvar_spec.lua b/tests/plenary/async/condvar_spec.lua
index 9fd7ea7..b677762 100644
--- a/tests/plenary/async/condvar_spec.lua
+++ b/tests/plenary/async/condvar_spec.lua
@@ -125,4 +125,34 @@ describe("condvar", function()
 
     eq(3, counter)
   end)
+
+  a.it("notify all works multiple times", function()
+    local condvar = Condvar.new()
+    local counter = 0
+
+    a.run(function()
+      condvar:wait()
+      counter = counter + 1
+    end)
+
+    a.run(function()
+      condvar:wait()
+      counter = counter + 1
+    end)
+
+    eq(0, counter)
+
+    condvar:notify_all()
+
+    eq(2, counter)
+
+    a.run(function()
+      condvar:wait()
+      counter = 0
+    end)
+
+    condvar:notify_all()
+
+    eq(0, counter)
+  end)
 end)
Repository: nvim-lua/plenary.nvim
Pull request #505 (2023-07-02 14:48:05)

feat: add `Iterator:fold` and `Iterator:enumerate`
I often need these and end up implementing them myself, so thought they'd be useful to have in here.

Conni2461: thanks :)

Patch:
diff --git a/lua/plenary/iterators.lua b/lua/plenary/iterators.lua
index 826f08d..ca83cfb 100644
--- a/lua/plenary/iterators.lua
+++ b/lua/plenary/iterators.lua
@@ -486,6 +486,16 @@ function Iterator:filter(fun)
   return wrap(filter_gen, { self.gen, self.param, fun }, self.state)
 end
 
+---Iterator adapter that will provide numbers from 1 to n as the first multival
+---@return Iterator
+function Iterator:enumerate()
+  local i = 0
+  return self:map(function(...)
+    i = i + 1
+    return i, ...
+  end)
+end
+
 --------------------------------------------------------------------------------
 -- Reducing
 --------------------------------------------------------------------------------
@@ -531,6 +541,19 @@ function Iterator:find(val_or_fn)
   end
 end
 
+---Folds an iterator into a single value using a function.
+---@param init any
+---@param fun fun(acc: any, val: any): any
+---@return any
+function Iterator:fold(init, fun)
+  local acc = init
+  local gen, param, state = self.gen, self.param, self.state
+  for _, r in gen, param, state do
+    acc = fun(acc, r)
+  end
+  return acc
+end
+
 ---Turns an iterator into a list.
 ---If the iterator yields multivals only the first multival will be used.
 ---@return table


Test patch:
diff --git a/tests/plenary/iterators_spec.lua b/tests/plenary/iterators_spec.lua
index 3fed816..8d553bf 100644
--- a/tests/plenary/iterators_spec.lua
+++ b/tests/plenary/iterators_spec.lua
@@ -31,6 +31,35 @@ describe("iterators", function()
     check_keys(tbl, { 1, 2, 3, 4 })
   end)
 
+  it("should be able to fold", function()
+    local numbers = { 1, 2, 3, 4 }
+    local result = i.iter(numbers):fold(0, function(a, v)
+      return a + v
+    end)
+    eq(result, 10)
+
+    local strings = { "hello", "world", "this", "is", "a", "test" }
+    result = i.iter(strings):fold("", function(a, v)
+      return a .. v
+    end)
+    eq(result, "helloworldthisisatest")
+  end)
+
+  it("should be able to enumerate", function()
+    local tbl = { 1, 2, 3, 4 }
+    local results = i.iter(tbl)
+      :enumerate()
+      :map(function(idx, v)
+        return { idx, v }
+      end)
+      :tolist()
+    eq(#results, 4)
+    eq(results[1], { 1, 1 })
+    eq(results[2], { 2, 2 })
+    eq(results[3], { 3, 3 })
+    eq(results[4], { 4, 4 })
+  end)
+
   it("should be able to find", function()
     local tbl = { 1, 2, 3, 4 }
     local tbl_iter = i.iter(tbl)
Repository: nvim-lua/plenary.nvim
Pull request #507 (2023-07-06 07:18:52)

Fix spelling in comment in iterators.lua
Super small - `Se` should probably be `See`.


Patch:
diff --git a/lua/plenary/iterators.lua b/lua/plenary/iterators.lua
index 826f08d..904d2db 100644
--- a/lua/plenary/iterators.lua
+++ b/lua/plenary/iterators.lua
@@ -128,7 +128,7 @@ end
 
 ---Wraps the iterator triplet into a table to allow metamethods and calling with method form
 ---Important! We do not return param and state as multivals like the original luafun
----Se the __call metamethod for more information
+---See the __call metamethod for more information
 ---@param gen any
 ---@param param any
 ---@param state any
@@ -486,6 +486,16 @@ function Iterator:filter(fun)
   return wrap(filter_gen, { self.gen, self.param, fun }, self.state)
 end
 
+---Iterator adapter that will provide numbers from 1 to n as the first multival
+---@return Iterator
+function Iterator:enumerate()
+  local i = 0
+  return self:map(function(...)
+    i = i + 1
+    return i, ...
+  end)
+end
+
 --------------------------------------------------------------------------------
 -- Reducing
 --------------------------------------------------------------------------------
@@ -531,6 +541,19 @@ function Iterator:find(val_or_fn)
   end
 end
 
+---Folds an iterator into a single value using a function.
+---@param init any
+---@param fun fun(acc: any, val: any): any
+---@return any
+function Iterator:fold(init, fun)
+  local acc = init
+  local gen, param, state = self.gen, self.param, self.state
+  for _, r in gen, param, state do
+    acc = fun(acc, r)
+  end
+  return acc
+end
+
 ---Turns an iterator into a list.
 ---If the iterator yields multivals only the first multival will be used.
 ---@return table


Test patch:
diff --git a/tests/plenary/iterators_spec.lua b/tests/plenary/iterators_spec.lua
index 3fed816..8d553bf 100644
--- a/tests/plenary/iterators_spec.lua
+++ b/tests/plenary/iterators_spec.lua
@@ -31,6 +31,35 @@ describe("iterators", function()
     check_keys(tbl, { 1, 2, 3, 4 })
   end)
 
+  it("should be able to fold", function()
+    local numbers = { 1, 2, 3, 4 }
+    local result = i.iter(numbers):fold(0, function(a, v)
+      return a + v
+    end)
+    eq(result, 10)
+
+    local strings = { "hello", "world", "this", "is", "a", "test" }
+    result = i.iter(strings):fold("", function(a, v)
+      return a .. v
+    end)
+    eq(result, "helloworldthisisatest")
+  end)
+
+  it("should be able to enumerate", function()
+    local tbl = { 1, 2, 3, 4 }
+    local results = i.iter(tbl)
+      :enumerate()
+      :map(function(idx, v)
+        return { idx, v }
+      end)
+      :tolist()
+    eq(#results, 4)
+    eq(results[1], { 1, 1 })
+    eq(results[2], { 2, 2 })
+    eq(results[3], { 3, 3 })
+    eq(results[4], { 4, 4 })
+  end)
+
   it("should be able to find", function()
     local tbl = { 1, 2, 3, 4 }
     local tbl_iter = i.iter(tbl)
Repository: nvim-lua/plenary.nvim
Pull request #562 (2024-03-16 10:02:19)

fix(path): make find_upwards stop at root
When there is no file to be found `find_upwards` gets stuck in an infinite-loop.
This PR should address this.


Patch:
diff --git a/lua/plenary/log.lua b/lua/plenary/log.lua
index 7ef0941..1bf091b 100644
--- a/lua/plenary/log.lua
+++ b/lua/plenary/log.lua
@@ -97,6 +97,9 @@ log.new = function(config, standalone)
   end
 
   local round = function(x, increment)
+    if x == 0 then
+      return x
+    end
     increment = increment or 1
     x = x / increment
     return (x > 0 and math.floor(x + 0.5) or math.ceil(x - 0.5)) * increment
diff --git a/lua/plenary/path.lua b/lua/plenary/path.lua
index 049c2b0..51229f1 100644
--- a/lua/plenary/path.lua
+++ b/lua/plenary/path.lua
@@ -78,7 +78,7 @@ end
 
 local is_absolute = function(filename, sep)
   if sep == "\\" then
-    return string.match(filename, "^[%a]:\\.*$") ~= nil
+    return string.match(filename, "^[%a]:[\\/].*$") ~= nil
   end
   return string.sub(filename, 1, 1) == sep
 end
@@ -929,7 +929,9 @@ end
 
 function Path:find_upwards(filename)
   local folder = Path:new(self)
-  while self:absolute() ~= path.root do
+  local root = path.root(folder)
+
+  while folder:absolute() ~= root do
     local p = folder:joinpath(filename)
     if p:exists() then
       return p
diff --git a/lua/plenary/popup/init.lua b/lua/plenary/popup/init.lua
index 0afcbd1..90a8a30 100644
--- a/lua/plenary/popup/init.lua
+++ b/lua/plenary/popup/init.lua
@@ -123,6 +123,9 @@ function popup.create(what, vim_options)
     assert(bufnr, "Failed to create buffer")
 
     vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe")
+    if vim.o.modifiable == false then
+      vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
+    end
 
     -- TODO: Handle list of lines
     if type(what) == "string" then


Test patch:
diff --git a/tests/plenary/popup_spec.lua b/tests/plenary/popup_spec.lua
index a02453d..250ba0e 100644
--- a/tests/plenary/popup_spec.lua
+++ b/tests/plenary/popup_spec.lua
@@ -22,6 +22,19 @@ describe("plenary.popup", function()
     eq(20, win_config.width)
   end)
 
+  it("can create a very simple window after 'set nomodifiable'", function()
+    vim.o.modifiable = false
+    local win_id = popup.create("hello there", {
+      line = 1,
+      col = 1,
+      width = 20,
+    })
+
+    local win_config = vim.api.nvim_win_get_config(win_id)
+    eq(20, win_config.width)
+    vim.o.modifiable = true
+  end)
+
   it("can apply a highlight", function()
     local win_id = popup.create("hello there", {
       highlight = "PopupColor1",