Skip to content

Commit

Permalink
Refactor accept 1
Browse files Browse the repository at this point in the history
  • Loading branch information
luozhiya committed May 15, 2024
1 parent 01480bd commit 0662602
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 101 deletions.
15 changes: 0 additions & 15 deletions lua/fittencode/base.lua
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,6 @@ function M.is_bsd()
end, sys) > 0
end

---@param char string
---@return boolean
function M.is_alpha(char)
---@type integer
local byte = char:byte()
return (byte >= 65 and byte <= 90) or (byte >= 97 and byte <= 122)
end

---@param char string
---@return boolean
function M.is_space(char)
local byte = string.byte(char)
return byte == 32 or byte == 9
end

function M.tbl_keys_by_value(tbl, value)
local keys = {}
for k, v in pairs(tbl) do
Expand Down
6 changes: 6 additions & 0 deletions lua/fittencode/color.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@ local Base = require('fittencode.base')
local M = {}

M.FittenSuggestion = 'FittenSuggestion'
M.FittenSuggestionCommit = 'FittenSuggestionCommit'
M.FittenSuggestionWhitespace = 'FittenSuggestionWhitespace'

-- Define FittenCode colors
local colors = {}
colors.gray = '#808080'
colors.yellow = '#ffaf00'

function M.setup_highlight()
Base.set_hi(M.FittenSuggestion, {
fg = colors.gray,
ctermfg = 'LightGrey',
})
Base.set_hi(M.FittenSuggestionCommit, {
fg = colors.yellow,
ctermfg = 'LightYellow',
})
Base.set_hi(M.FittenSuggestionWhitespace, {
bg = colors.gray,
ctermbg = 'LightGrey',
Expand Down
59 changes: 23 additions & 36 deletions lua/fittencode/engines/inline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -369,41 +369,6 @@ function M.accept_line()
end)
end

-- Calculate the next word index, split by word boundary
---@param line string
local function calculate_next_word_index(line, utf8_index)
local prev_ctype = nil
for i = 1, string.len(line) do
local char, pos = Unicode.find_first_character(line, utf8_index, i)
if not pos or not char then
break
end
if pos[1] ~= pos[2] then
if not prev_ctype then
return pos[2]
else
return pos[1] - 1
end
end

local is_alpha = Base.is_alpha(char)
local is_space = Base.is_space(char)

if not is_alpha and not is_space then
return prev_ctype and i - 1 or 1
end
if prev_ctype then
if is_alpha and prev_ctype ~= 'alpha' then
return i - 1
elseif is_space and prev_ctype ~= 'space' then
return i - 1
end
end
prev_ctype = is_alpha and 'alpha' or is_space and 'space'
end
return string.len(line)
end

function M.accept_word()
Log.debug('Accept word...')

Expand All @@ -426,7 +391,7 @@ function M.accept_word()
Log.debug('No line cached')
return
end
local utf8_index = Unicode.calculate_utf8_index(line)
local utf8_index = Unicode.calculate_utf_startpoints(line)
local next_word_index = calculate_next_word_index(line, utf8_index)
local word = ''
if next_word_index > 0 then
Expand Down Expand Up @@ -568,4 +533,26 @@ function M.get_status()
return status:get_current()
end

---@class AccpetOptions
---@field mode string
---@field forward boolean

---@param opts AccpetOptions
function M.accept(opts)
if opts.mode == 'line' then
cache:commit_line(opts.forward)
elseif opts.mode == 'word' then
cache:commit_word(opts.forward)
elseif opts.mode == 'all' then
cache:commit_all()
end
if cache:is_commit_reach_end() then
Lines.set_text(cache.lines)
cache:flush()
generate_one_stage_at_cursor()
else
Lines.render_virt_text(cache.lines, cache.commit_cursor)
end
end

return M
177 changes: 132 additions & 45 deletions lua/fittencode/suggestions_cache.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
-- local Unicode = require('fittencode.unicode')
local Unicode = require('unicode')

---@class SuggestionsCache
---@field private task_id? integer
---@field private lines? string[]
---@field private row? integer
---@field private col? integer
---@field private count? integer
---@field task_id? integer
---@field lines? string[]
---@field doc_cursor Cursor
---@field commit_cursor Cursor
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.row = nil
self.col = nil
self.count = 0
self.utf_startpoints = {}
self.doc_cursor = {}
self.commit_cursor = { row = 1, col = 1 }
return self
end

Expand All @@ -26,59 +32,140 @@ end
---@param lines? string[]
function SuggestionsCache:update(task_id, row, col, lines)
self.task_id = task_id
self:update_cursor(row, col)
lines = lines or {}
self.lines = lines
self.count = vim.tbl_count(lines)
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 }
end

---@param index integer
---@param line? string
function SuggestionsCache:update_line(index, line)
if line == nil then
self:remove_line(index)
return
end
self.lines[index] = line
---@param char string
---@return boolean
local function is_alphax(char)
---@type integer
local byte = char:byte()
return (byte >= 65 and byte <= 90) or (byte >= 97 and byte <= 122)
end

---@return string[]
function SuggestionsCache:get_lines()
return self.lines
---@param char string
---@return boolean
local function is_spacex(char)
local byte = string.byte(char)
return byte == 32 or byte == 9
end

---@return string?
function SuggestionsCache:get_line(index)
return self.lines[index]
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()
end
return next_row, next_col
end

---@return string?
function SuggestionsCache:remove_line(index)
return table.remove(self.lines, index)
-- 0 0 -1 -2 0 0
-- 0 0 -2 -1 0 0
---@param line string
local function _calculate_next_col_by_char(line, utf_sp, next_col)
local prev_ctype = nil
for i = next_col, string.len(line) do
local char, pos = Unicode.find_first_character(line, utf_sp, i)
if not pos or not char then
break
end
if pos[1] ~= pos[2] then
if not prev_ctype then
return pos[2]
else
return pos[1] - 1
end
end

local is_alpha = is_alphax(char)
local is_space = is_spacex(char)

if not is_alpha and not is_space then
return prev_ctype and i - 1 or 1
end
if prev_ctype then
if is_alpha and prev_ctype ~= 'alpha' then
return i - 1
elseif is_space and prev_ctype ~= 'space' then
return i - 1
end
end
prev_ctype = is_alpha and 'alpha' or is_space and 'space'
end
return string.len(line)
end

---@return integer
function SuggestionsCache:get_count()
return self.count
-- 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)
-- next_col = next_col + (forward and 1 or -1)
if forward and next_col == string.len(line) then
return next_col + 1
end
if not forward and next_col == 1 then
return next_col - 1
end
if not forward then
line = string.reverse(line)
next_col = string.len(line) - next_col + 1
end
local col = _calculate_next_col_by_char(line, utf_sp, next_col)
if not forward then
col = string.len(line) - col + 1
end
return col
end

---@param row? integer
---@param col? integer
function SuggestionsCache:update_cursor(row, col)
self.row = row
self.col = col
function SuggestionsCache:commit_word(forward)
local next_row = self.commit_cursor.row
local next_col = self.commit_cursor.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
end
if next_col == 0 then
next_row = next_row - 1
end
next_row, next_col = commit_post(self.lines, next_row, next_col)
self.commit_cursor = { row = next_row, col = next_col }
end

---@param row integer
---@param col integer
---@return boolean
function SuggestionsCache:equal_cursor(row, col)
return self.row == row and self.col == col
---@param forward boolean
function SuggestionsCache:commit_line(forward)
local next_row = self.commit_cursor.row
local next_col = self.commit_cursor.col

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 }
end

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

---@return integer?, integer?
function SuggestionsCache:get_cursor()
return self.row, self.col
function SuggestionsCache:is_commit_reach_end()
if not self.commit_cursor.row or not self.commit_cursor.col then
return false
end
if self.commit_cursor.row == #self.lines and self.commit_cursor.col == self.lines[#self.lines]:len() then
return true
end
return false
end

return SuggestionsCache
Loading

0 comments on commit 0662602

Please sign in to comment.