Skip to content

Commit

Permalink
Object 85
Browse files Browse the repository at this point in the history
  • Loading branch information
luozhiya committed Jan 2, 2025
1 parent 7ff61f9 commit 5415d25
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 41 deletions.
18 changes: 18 additions & 0 deletions lua/fittencode/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,24 @@ function M.generate_one_stage(options)
return HTTP.fetch(url, req)
end

function M.accept_completion(options)
local key = M.get_ft_token()
if not key then
Fn.schedule_call(options.on_error)
return
end
local headers = {
['Content-Type'] = 'application/json',
}
local url = M.server_url() .. preset_urls.accept .. '/' .. key
local req = make_req_from_options(options, {
method = 'POST',
headers = headers,
body = options.prompt,
})
return HTTP.fetch(url, req)
end

function M.chat(options)
local key = M.get_ft_token()
if not key then
Expand Down
15 changes: 15 additions & 0 deletions lua/fittencode/editor.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local Log = require('fittencode.log')
local Position = require('fittencode.position')

---@class FittenCode.Editor
local Editor = {}
Expand Down Expand Up @@ -113,6 +114,20 @@ function Editor.word_count(buf)
return wc.chars
end

-- Return the zero-based current position of the cursor in the window
---@param win integer?
---@return FittenCode.Position?
function Editor.position(win)
if not win or not vim.api.nvim_win_is_valid(win) then
return
end
local row, col = unpack(vim.api.nvim_win_get_cursor(win))
return Position:new({
row = row - 1,
col = col,
})
end

---@param buf integer?
---@param pos FittenCode.Position
---@return integer?
Expand Down
113 changes: 83 additions & 30 deletions lua/fittencode/inline/controller.lua
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,46 @@ function Controller:lazy_completion()
end
end

local function vie(buf, e, r, n)
local function vie(buf, a, b, n)
local i = Editor.word_count(buf)
local s = t:offsetAt(e)
local o = t:offsetAt(r)
local s = t:offsetAt(a)
local o = t:offsetAt(b)
local a = math.max(0, s - n)
local A = math.min(i, o + n)
local l = t:positionAt(a)
local u = t:positionAt(A)
local c = t:getText(N.Range(l, e))
local h = t:getText(N.Range(r, u))
local c = t:getText(N.Range(l, s))
local h = t:getText(N.Range(b, u))
return c .. '<fim_middle>' .. h
end

function Controller:generate_prompt(buf, row, col)
local within_the_line = col ~= string.len(vim.api.nvim_buf_get_lines(buf, row, row + 1, false)[1])
---@class FittenCode.Inline.Prompt
---@field inputs string
---@field meta_datas FittenCode.Inline.Prompt.MetaDatas

---@class FittenCode.Inline.Prompt.MetaDatas
---@field plen number
---@field slen number
---@field bplen number
---@field bslen number
---@field pmd5 string
---@field nmd5 string
---@field diff string
---@field filename string
---@field cpos number
---@field bcpos number
---@field pc_available boolean
---@field pc_prompt string
---@field pc_prompt_type string

---@param buf number
---@param position FittenCode.Position?
---@return FittenCode.Inline.Prompt?
function Controller:generate_prompt(buf, position)
if not position then
return
end
local within_the_line = position.col ~= string.len(vim.api.nvim_buf_get_lines(buf, position.row, position.row + 1, false)[1])
if Config.inline_completion.disable_completion_within_the_line and within_the_line then
return
end
Expand All @@ -119,10 +144,11 @@ function Controller:generate_prompt(buf, row, col)
local A = ''
local max_chars = 22e4
if Editor.word_count(buf).chars <= max_chars then
local prefix = table.concat(vim.api.nvim_buf_get_text(buf, 0, 0, row, col, {}), '\n')
local suffix = table.concat(vim.api.nvim_buf_get_text(buf, row, col, -1, -1, {}), '\n')
local pos = Position:new({ line = row, character = col })
A = vie(buf, pos, pos, 100)
local prefix = table.concat(vim.api.nvim_buf_get_text(buf, 0, 0, position.row, position.col, {}), '\n')
local suffix = table.concat(vim.api.nvim_buf_get_text(buf, position.row, position.col, -1, -1, {}), '\n')
local a = position:clone()
local b = position:clone()
A = vie(buf, a, b, 100)
end
return {
inputs = '',
Expand All @@ -144,8 +170,32 @@ function Controller:generate_prompt(buf, row, col)
}
end

function Controller:generate_completion(data)
local generated_text = (vim.fn.substitute(data.generated_text, '<|endoftext|>', '', 'g') or '') .. data.ex_msg
---@class FittenCode.Inline.Completion
---@field response FittenCode.Inline.GenerateOneStageResponse
---@field position FittenCode.Position

---@class FittenCode.Inline.GenerateOneStageResponse
---@field request_id string
---@field completions FittenCode.Inline.GenerateOneStageResponse.Completion[]
---@field context any

---@class FittenCode.Inline.GenerateOneStageResponse.Completion
---@field generated_text string
---@field col_delta number
---@field row_delta number

---@class FittenCode.Inline.RawGenerateOneStageResponse
---@field server_request_id string
---@field generated_text string
---@field ex_msg string
---@field delta_char number
---@field delta_line number

---@param data FittenCode.Inline.RawGenerateOneStageResponse
---@return FittenCode.Inline.GenerateOneStageResponse?
function Controller:completion_response(data)
assert(data)
local generated_text = (vim.fn.substitute(data.generated_text or '', '<|endoftext|>', '', 'g') or '') .. (data.ex_msg or '')
if generated_text == '' then
return
end
Expand All @@ -157,7 +207,7 @@ function Controller:generate_completion(data)
{
generated_text = generated_text,
col_delta = col_delta,
row_delta = data.delta_line
row_delta = data.delta_line or 0,
},
},
context = nil -- TODO: implement fim context
Expand All @@ -172,6 +222,18 @@ function Controller:is_filetype_excluded(buf)
return vim.tbl_contains(Config.disable_specific_inline_completion.suffixes, ft)
end

function Controller:cleanup_session()
for _, handle in ipairs(self.request_handles) do
handle:abort()
end
self.request_handles = {}

if self.session then
self.session:destory()
self.session = nil
end
end

function Controller:triggering_completion(options)
options = options or {}
Log.debug('Triggering completion')
Expand All @@ -185,21 +247,13 @@ function Controller:triggering_completion(options)
if self:is_filetype_excluded(buf) or not Editor.is_filebuf(buf) then
return
end
local row, col = unpack(vim.api.nvim_win_get_cursor(vim.api.nvim_get_current_win()))
local position = Editor.position(vim.api.nvim_get_current_win())
options.force = (options.force == nil) and false or options.force
if not options.force and self.session and self.session:cache_hit(row, col) then
if not options.force and self.session and self.session:cache_hit(position) then
return
end

for _, handle in ipairs(self.request_handles) do
handle:abort()
end
self.request_handles = {}

if self.session then
self.session:destory()
self.session = nil
end
self:cleanup_session()

local timing = {
get_completion_version = {},
Expand Down Expand Up @@ -231,10 +285,10 @@ function Controller:triggering_completion(options)
self.request_handles[#self.request_handles + 1] = Client.get_completion_version(gcv_options)
end):forward(function(version)
return Promise:new(function(resolve, reject)
Log.debug('Triggering completion for row: {}, col: {}', row, col)
Log.debug('Triggering completion for position {}', position)
local gos_options = {
completion_version = version,
prompt = self:generate_prompt(buf, row - 1, col),
prompt = self:generate_prompt(buf, position),
on_create = function()
timing.generate_one_stage.on_create = vim.uv.hrtime()
end,
Expand All @@ -246,7 +300,7 @@ function Controller:triggering_completion(options)
reject()
return
end
local completion = self:generate_completion(json)
local completion = self:completion_response(json)
if not completion then
Log.error('Failed to generate completion: {}', json)
reject()
Expand All @@ -266,8 +320,7 @@ function Controller:triggering_completion(options)
end):forward(function(completion)
local model = Model:new({
buf = buf,
row = row,
col = col,
position = position,
completion = completion,
})
local view = View:new({ buf = buf })
Expand Down
9 changes: 2 additions & 7 deletions lua/fittencode/inline/model.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@ Model.__index = Model
---@return FittenCode.Inline.Model
function Model:new(opts)
local obj = {
mode = opts.mode,
generated_text = opts.generated_text,
ex_msg = opts.ex_msg,
delta_char = opts.delta_char,
delta_line = opts.delta_line,
buf = opts.buf,
row = opts.row,
col = opts.col,
position = opts.position,
completion = opts.completion,
}
setmetatable(obj, Model)
return obj
Expand Down
4 changes: 0 additions & 4 deletions lua/fittencode/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,6 @@

---@class FittenCode.Inline.Model
---@field mode 'lines' | 'multi_segments' | 'edit_completion'
---@field row number
---@field col number
---@field commit_row number
---@field commit_col number
---@field accept function
---@field make_state function
---@field clear function
Expand Down

0 comments on commit 5415d25

Please sign in to comment.