Skip to content

Commit

Permalink
Refactor accept 2
Browse files Browse the repository at this point in the history
  • Loading branch information
luozhiya committed May 14, 2024
1 parent d8e61cc commit 127fefa
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 109 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.PHONY: cf
cf:
CodeFormat format -c .editorconfig -w lua/
CodeFormat format -c .editorconfig -w tests/

.PHONY: sl
sl:
Expand All @@ -9,3 +10,7 @@ sl:
.PHONY: lint
lint:
luacheck .

.PHONY: test
test:
nvim --headless -u tests/init.lua -c 'qa'
7 changes: 7 additions & 0 deletions lua/fittencode/bindings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ function M.setup_keymaps()
end)
Base.map('i', '<C-Down>', API.accept_line)
Base.map('i', '<C-Right>', API.accept_word)
-- Base.map('i', '<CR>', function ()
-- if API.has_suggestions() then
-- API.accept_suggestion()
-- else
-- Lines.enter()
-- end
-- end)
end

function M.setup_keyfilters()
Expand Down
233 changes: 194 additions & 39 deletions lua/fittencode/suggestions_cache.lua
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
-- local Unicode = require('fittencode.unicode')
local Unicode = require('unicode')
local Unicode = require('fittencode.unicode')

---@class SuggestionsCache
---@field task_id? integer
---@field lines? string[]
---@field doc_cursor Cursor
---@field commit_cursor Cursor
---@field doc_cursor table<integer, integer>
---@field commit_cursor table<integer, integer>
local SuggestionsCache = {}

---@class Cursor
---@field row? integer
---@field col? integer

function SuggestionsCache.new()
local self = setmetatable({}, { __index = SuggestionsCache })
self.task_id = nil
self.lines = {}
self.utf_startpoints = {}
self.doc_cursor = {}
self.commit_cursor = { row = 1, col = 1 }
self.commit_cursor = { 0, 0 }
return self
end

Expand All @@ -34,8 +29,8 @@ function SuggestionsCache:update(task_id, row, col, lines)
self.task_id = task_id
self.lines = lines or {}
self.utf_startpoints = Unicode.calculate_utf_startpoints_tbl(self.lines)
self.doc_cursor = { row = row, col = col }
self.commit_cursor = { row = 1, col = 1 }
self.doc_cursor = { row, col }
self.commit_cursor = { 0, 0 }
end

---@param char string
Expand All @@ -53,17 +48,51 @@ local function is_spacex(char)
return byte == 32 or byte == 9
end

local function commit_post(lines, next_row, next_col)
if next_row < 1 then
next_row = 1
next_col = 1
end
if next_row > #lines then
next_row = #lines
next_col = lines[next_row]:len()
end
if next_col < 1 then
next_col = lines[next_row]:len()
-- row 取值范围
-- 0 no start 没有上一行了,则设置col为0
-- 1 lines[1]
-- n lines[n]
-- n+1 没有下一行了,则设置col为改行末尾

-- col 取值范围
-- -1 需要换到上一列的末尾,如果没有上一列了,则设置col为0
-- 0 行还没开始
-- 1 第一个字符
-- n 第n个字符
-- n+1 超出了当前行,需要跳到下一行的开始,如果没有下一行了,则设置col为末尾
local function postcommit(lines, next_row, next_col)
if next_col == -1 then
next_row = next_row - 1
if next_row <= 0 then
next_row = 0
next_col = 0
else
next_col = string.len(lines[next_row])
end
elseif next_col > 0 then
if next_row == 0 then
next_row = 1
end
if next_row > #lines then
next_row = #lines
next_col = string.len(lines[next_row])
else
if next_col == string.len(lines[next_row]) + 1 then
if next_row == #lines then
next_col = string.len(lines[next_row])
else
next_row = next_row + 1
next_col = 0
end
end
end
elseif next_col == 0 then
-- if next_row == #lines + 1 then
-- next_row = #lines
-- next_col = string.len(lines[next_row])
-- elseif next_row == 1 then
-- next_row = 0
-- end
end
return next_row, next_col
end
Expand Down Expand Up @@ -106,7 +135,7 @@ end

-- Calculate the next word index, split by word boundary
---@param line string
local function calculate_next_col_by_char(line, utf_sp, next_col, forward)
local function calculate_next_col_by_word(line, utf_sp, next_col, forward)
-- next_col = next_col + (forward and 1 or -1)
if forward and next_col == string.len(line) then
return next_col + 1
Expand All @@ -125,37 +154,163 @@ local function calculate_next_col_by_char(line, utf_sp, next_col, forward)
return col
end

function SuggestionsCache:commit_word(forward)
local next_row = self.commit_cursor.row
local next_col = self.commit_cursor.col
local function find_zero_reverse(tbl, start)
if not start then
return
end
for i = start, 1, -1 do
if tbl[i] == 0 then
return i
end
end
end

local function find_zero(tbl, start)
for i = start, #tbl do
if tbl[i] == 0 then
return i
end
end
end

local function find_diff(line, utf_sp, start, current)
local x = find_zero(utf_sp, start)
if x ~= start then
return x - start + 1
end
local is_space = is_spacex(current)
for i = start, #line do
if line[i] ~= current then
return i
end
end
end

local function find_diff_reverse(line, utf_sp, start, current)
for i = start, 1, -1 do
if line[i] ~= current then
return i
end
end
end

local function calculate_offset(unit, line, utf_sp, col, forward)
local offset = (forward and 1 or -1)

-- 1 2 3 4 5 6 7 8
-- { 0, 0, 0, 0, 0, 0, -1, -2 }
if unit == 'char' then
if forward then
local x = find_zero(utf_sp, col + 1)
if x then
offset = x - col
else
offset = #line - col + 1
end
else
local x = find_zero_reverse(utf_sp, col - 1)
if x then
offset = x - col
end
end
end

if unit == 'word' then
return calculate_next_col_by_word(line, utf_sp, col, forward) - col

next_col = calculate_next_col_by_char(self.lines[next_row], self.utf_startpoints[next_row], next_col, forward)
print("commit_word", next_row, next_col)
if next_col > string.len(self.lines[next_row]) then
next_row = next_row + 1
next_col = 1
-- local current = line[col]
-- if forward then
-- local x = find_diff(line, col + 1, current)
-- if x then
-- offset = x - col
-- else
-- offset = #line - col + 1
-- end
-- else
-- local x = find_diff_reverse(line, col - 1, current)
-- if x then
-- offset = x - col
-- end
-- end
end

return offset
end

local function precommit(lines, next_row, next_col, forward)
if next_col == 0 then
next_row = next_row - 1
if not forward then
next_row = next_row - 1
if next_row > 0 then
next_col = string.len(lines[next_row]) + 1
else
next_row = 0
end
else
if next_row == 0 then
next_row = 1
end
end
elseif next_col == string.len(lines[next_row]) then
if forward then
next_row = next_row + 1
next_col = 0
if next_row > #lines then
next_row = #lines
next_col = string.len(lines[next_row])
end
end
end
return next_row, next_col
end

function SuggestionsCache:commit_char(forward)
local next_row = self.commit_cursor[1]
local next_col = self.commit_cursor[2]

-- 1. Compute next_row, make next_col on next_row
next_row, next_col = precommit(self.lines, next_row, next_col, forward)

-- 2. Compute next_col
local offset = (forward and 1 or -1)
if next_row >= 1 and next_row <= #self.lines then
offset = calculate_offset('char', self.lines[next_row], self.utf_startpoints[next_row], next_col, forward)
end
next_row, next_col = commit_post(self.lines, next_row, next_col)
self.commit_cursor = { row = next_row, col = next_col }
next_col = next_col + offset

-- 3. Fixup next_row and next_col
next_row, next_col = postcommit(self.lines, next_row, next_col)
self.commit_cursor = { next_row, next_col }
end

function SuggestionsCache:commit_word(forward)
local next_row = self.commit_cursor[1]
local next_col = self.commit_cursor[2]

next_row, next_col = precommit(self.lines, next_row, next_col, forward)
local offset = calculate_offset('word', self.lines[next_row], self.utf_startpoints[next_row], next_col, forward)
next_col = next_col + offset

next_row, next_col = postcommit(self.lines, next_row, next_col)
self.commit_cursor = { next_row, next_col }
end

---@param forward boolean
function SuggestionsCache:commit_line(forward)
local next_row = self.commit_cursor.row
local next_col = self.commit_cursor.col
local next_row = self.commit_cursor[1]
local next_col = self.commit_cursor[2]

next_row, next_col = precommit(self.lines, next_row, next_col, forward)

next_row = next_row + (forward and 1 or -1)
next_col = 1

next_row, next_col = commit_post(self.lines, next_row, next_col)
self.commit_cursor = { row = next_row, col = next_col }
next_row, next_col = postcommit(self.lines, next_row, next_col)
self.commit_cursor = { next_row, next_col }
end

function SuggestionsCache:commit_all()
self.commit_cursor = { row = #self.lines, col = self.lines[#self.lines]:len() }
self.commit_cursor = { #self.lines, self.lines[#self.lines]:len() }
end

function SuggestionsCache:is_commit_reach_end()
Expand Down
70 changes: 0 additions & 70 deletions lua/fittencode/suggestions_cache_tests.lua

This file was deleted.

Loading

0 comments on commit 127fefa

Please sign in to comment.