Skip to content

Commit

Permalink
update: erase duplicated history
Browse files Browse the repository at this point in the history
  • Loading branch information
amedama41 committed Jul 29, 2023
1 parent 853cc01 commit 9e5b2a9
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 60 deletions.
61 changes: 1 addition & 60 deletions lua/vfiler/context.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local git = require('vfiler/libs/git')
local vim = require('vfiler/libs/vim')

local Directory = require('vfiler/items/directory')
local History = require('vfiler/libs/history')

------------------------------------------------------------------------------
-- ItemAttribute class
Expand Down Expand Up @@ -46,66 +47,6 @@ function ItemAttribute.new(name)
}, ItemAttribute)
end

------------------------------------------------------------------------------
-- History class
------------------------------------------------------------------------------
local History = {}
History.__index = History

function History.new(max_size)
return setmetatable({
_current_index = 1,
_max_size = max_size,
_history = {},
}, History)
end

function History:copy()
local new = History.new(self._max_size)
new._current_index = self._current_index
new._history = core.table.copy(self._history)
return new
end

--- Save the path in the directory history
---@param path string
function History:save(path)
local last_item = self:_last_item()
if path == last_item then
-- This case happnes when reload action
return
end
self._history[self._current_index] = path
self._current_index = self._current_index + 1
if self._current_index > self._max_size then
self._current_index = 1
end
end

--- Get the directory history
function History:items()
local history = {}
for i = 1, #self._history do
local index = self._current_index - i
if index <= 0 then
index = index + #self._history
end
table.insert(history, self._history[index])
end
return history
end

function History:_last_item()
if #self._history == 0 then
return nil
end
local index = self._current_index - 1
if index == 0 then
index = #self._history
end
return self._history[index]
end

------------------------------------------------------------------------------
-- Session class
------------------------------------------------------------------------------
Expand Down
77 changes: 77 additions & 0 deletions lua/vfiler/libs/history.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
local core = require('vfiler/libs/core')
------------------------------------------------------------------------------
-- History class
------------------------------------------------------------------------------
local History = {}
History.__index = History

function History.new(max_size)
return setmetatable({
_current_index = 1,
_max_size = max_size,
_history = {},
}, History)
end

function History:copy()
local new = History.new(self._max_size)
new._current_index = self._current_index
new._history = core.table.copy(self._history)
return new
end

--- Save the path in the directory history
---@param path string
function History:save(path)
self:_erase(path)
self._history[self._current_index] = path
self._current_index = self._current_index + 1
if self._current_index > self._max_size then
self._current_index = 1
end
end

--- Get the directory history
function History:items()
local history = {}
for i = 1, #self._history do
local index = self._current_index - i
if index <= 0 then
index = index + #self._history
end
table.insert(history, self._history[index])
end
return history
end

--- Erase duplicated path from history
function History:_erase(path)
for i = 1, #self._history do
local index = self._current_index - i
if index <= 0 then
index = index + #self._history
end
if self._history[index] == path then
if index == self._current_index then
self._history[self._current_index] = nil
elseif index > self._current_index then
table.move(
self._history,
self._current_index,
index - 1,
self._current_index + 1
)
self._history[self._current_index] = nil
else
if #self._history == self._max_size then
table.move(self._history, index + 1, self._current_index - 1, index)
else
table.remove(self._history, index)
end
self._current_index = self._current_index - 1
end
end
end
end

return History
186 changes: 186 additions & 0 deletions tests/vfiler/history_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
local History = require('vfiler/libs/history')

describe('History', function()
describe('Save', function()
it('for empty', function()
local history = History.new(5)
history:save('path')
local items = history:items()
assert.equal(#items, 1)
assert.equal(items[1], 'path')
end)

it('until full', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')
history:save('path4')
history:save('path5')

local items = history:items()

assert.equal(#items, 5)
assert.equal(items[1], 'path5')
assert.equal(items[2], 'path4')
assert.equal(items[3], 'path3')
assert.equal(items[4], 'path2')
assert.equal(items[5], 'path1')
end)

describe('duplicated', function()
it('with first on non-full', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')

history:save('path1')
local items = history:items()

assert.equal(#items, 3)
assert.equal(items[1], 'path1')
assert.equal(items[2], 'path3')
assert.equal(items[3], 'path2')
end)

it('with last on non-full', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')

history:save('path3')
local items = history:items()

assert.equal(#items, 3)
assert.equal(items[1], 'path3')
assert.equal(items[2], 'path2')
assert.equal(items[3], 'path1')
end)

it('with first on full', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')
history:save('path4')
history:save('path5')

history:save('path1')
local items = history:items()

assert.equal(#items, 5)
assert.equal(items[1], 'path1')
assert.equal(items[2], 'path5')
assert.equal(items[3], 'path4')
assert.equal(items[4], 'path3')
assert.equal(items[5], 'path2')
end)

it('with middle on full', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')
history:save('path4')
history:save('path5')

history:save('path3')
local items = history:items()

assert.equal(#items, 5)
assert.equal(items[1], 'path3')
assert.equal(items[2], 'path5')
assert.equal(items[3], 'path4')
assert.equal(items[4], 'path2')
assert.equal(items[5], 'path1')
end)

it('with last on full', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')
history:save('path4')
history:save('path5')

history:save('path5')
local items = history:items()

assert.equal(#items, 5)
assert.equal(items[1], 'path5')
assert.equal(items[2], 'path4')
assert.equal(items[3], 'path3')
assert.equal(items[4], 'path2')
assert.equal(items[5], 'path1')
end)

it('with first on rotated', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')
history:save('path4')
history:save('path5')
history:save('path6')
history:save('path7')
history:save('path8')

history:save('path4')
local items = history:items()

assert.equal(#items, 5)
assert.equal(items[1], 'path4')
assert.equal(items[2], 'path8')
assert.equal(items[3], 'path7')
assert.equal(items[4], 'path6')
assert.equal(items[5], 'path5')
end)

it('to middle on rotated', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')
history:save('path4')
history:save('path5')
history:save('path6')
history:save('path7')
history:save('path8')

history:save('path6')
local items = history:items()

assert.equal(#items, 5)
assert.equal(items[1], 'path6')
assert.equal(items[2], 'path8')
assert.equal(items[3], 'path7')
assert.equal(items[4], 'path5')
assert.equal(items[5], 'path4')
end)

it('to last on rotated', function()
local history = History.new(5)
history:save('path1')
history:save('path2')
history:save('path3')
history:save('path4')
history:save('path5')
history:save('path6')
history:save('path7')
history:save('path8')

history:save('path8')
local items = history:items()

assert.equal(#items, 5)
assert.equal(items[1], 'path8')
assert.equal(items[2], 'path7')
assert.equal(items[3], 'path6')
assert.equal(items[4], 'path5')
assert.equal(items[5], 'path4')
end)
end)
end)
end)

0 comments on commit 9e5b2a9

Please sign in to comment.