-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
835 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
local Curl = require('plenary.curl') | ||
local Log = require('fittencode.log') | ||
local Promise = require('fittencode.promise') | ||
|
||
local function schedule_call(fx, ...) | ||
if fx then | ||
local args = { ... } | ||
vim.schedule(function() | ||
fx(unpack(args)) | ||
end) | ||
end | ||
end | ||
|
||
local URLs = { | ||
register = 'https://codewebchat.fittenlab.cn/?ide=neovim', | ||
login = 'https://fc.fittenlab.cn/codeuser/login', | ||
get_ft_token = 'https://fc.fittenlab.cn/codeuser/get_ft_token', | ||
generate_one_stage = 'https://fc.fittenlab.cn/codeapi/completion/generate_one_stage', | ||
} | ||
|
||
local KEYRING_STORE = vim.fn.stdpath('data') .. '/fittencode' .. '/api_key.json' | ||
local keyring = nil | ||
|
||
local function load_last_session() | ||
local _, store = pcall(vim.fn.json_decode, vim.fn.readfile(KEYRING_STORE)) | ||
if _ and store.key then | ||
keyring = store | ||
end | ||
end | ||
|
||
local function register() | ||
vim.ui.open(URLs.register) | ||
end | ||
|
||
local function login(on_success, on_error) | ||
if keyring then | ||
Log.notify_info('You are already logged in') | ||
schedule_call(on_success) | ||
return | ||
end | ||
|
||
local username = vim.fn.input('Username ') | ||
local password = vim.fn.inputsecret('Password ') | ||
|
||
Promise:new(function(resolve, reject) | ||
Curl.post(URLs.login, { | ||
headers = { | ||
['Content-Type'] = 'application/json', | ||
}, | ||
body = vim.fn.json_encode({ | ||
username = username, | ||
password = password, | ||
}), | ||
on_error = vim.schedule_wrap(function() | ||
reject() | ||
end), | ||
on_callback = vim.schedule_wrap(function(res) | ||
if res.status ~= 200 then | ||
reject() | ||
return | ||
end | ||
local _, login_data = pcall(vim.fn.json_decode, res) | ||
if not _ or login_data.code ~= 200 then | ||
reject() | ||
return | ||
end | ||
resolve(login_data.data.token) | ||
end) | ||
}) | ||
end):forward(function(token) | ||
return Promise:new(function(resolve, reject) | ||
Curl.get(URLs.get_ft_token, { | ||
headers = { | ||
['Authorization'] = 'Bearer ' .. token, | ||
}, | ||
on_error = vim.schedule_wrap(function() | ||
reject() | ||
end), | ||
on_callback = vim.schedule_wrap(function(res) | ||
if res.status ~= 200 then | ||
reject() | ||
return | ||
end | ||
local _, fico_data = pcall(vim.fn.json_decode, res) | ||
if not _ or fico_data.data == nil or fico_data.data.fico_token == nil then | ||
reject() | ||
return | ||
end | ||
resolve(fico_data.data.fico_token) | ||
end), | ||
}) | ||
end) | ||
end, function() | ||
schedule_call(on_error) | ||
end):forward(function(fico_token) | ||
keyring = { | ||
name = username, | ||
key = fico_token, | ||
} | ||
Log.notify_info('Login successful') | ||
vim.fn.writefile(vim.fn.json_encode(keyring), KEYRING_STORE) | ||
schedule_call(on_success) | ||
end, function() | ||
schedule_call(on_error) | ||
end) | ||
end | ||
|
||
local function logout() | ||
keyring = nil | ||
if vim.fn.filereadable(KEYRING_STORE) == 0 then | ||
Log.notify_info('You are already logged out') | ||
return | ||
end | ||
vim.fn.delete(KEYRING_STORE) | ||
Log.notify_info('Logout successful') | ||
end | ||
|
||
-- Example of `completion_data`: | ||
-- { | ||
-- "generated_text": ". Linear Regression", | ||
-- "server_request_id": "1727022491.679533.348777", | ||
-- "delta_char": 0, | ||
-- "delta_line": 0, | ||
-- "ex_msg": "" | ||
-- } | ||
local function generate_one_stage(prompt, on_success, on_error) | ||
if not keyring then | ||
Log.notify_error('You are not logged in, please try `FittenCode login` first') | ||
schedule_call(on_error) | ||
return | ||
end | ||
local url = URLs.generate_one_stage .. '/' .. keyring.key .. '?ide=neovim&v=0.2.0' | ||
Promise:new(function(resolve, reject) | ||
Curl.post(url, { | ||
headers = { | ||
['Content-Type'] = 'application/json', | ||
}, | ||
body = vim.fn.json_encode(prompt), | ||
on_error = vim.schedule_wrap(function() | ||
reject() | ||
end), | ||
on_callback = vim.schedule_wrap(function(res) | ||
if res.status ~= 200 then | ||
reject() | ||
return | ||
end | ||
local _, completion_data = pcall(vim.fn.json_decode, res) | ||
if not _ then | ||
reject() | ||
return | ||
end | ||
resolve(completion_data) | ||
end) | ||
}) | ||
end):forward(function(completion_data) | ||
schedule_call(on_success, completion_data) | ||
end, function() | ||
schedule_call(on_error) | ||
end) | ||
end | ||
|
||
local function chat() | ||
end | ||
|
||
return { | ||
load_last_session = load_last_session, | ||
register = register, | ||
login = login, | ||
logout = logout, | ||
generate_one_stage = generate_one_stage, | ||
chat = chat, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,185 @@ | ||
---@class fittencode.Config | ||
local M = {} | ||
|
||
local defaults = {} | ||
---@class fittencode.Config | ||
local defaults = { | ||
action = { | ||
document_code = { | ||
-- Show "Fitten Code - Document Code" in the editor context menu, when you right-click on the code. | ||
show_in_editor_context_menu = true, | ||
}, | ||
edit_code = { | ||
-- Show "Fitten Code - Edit Code" in the editor context menu, when you right-click on the code. | ||
show_in_editor_context_menu = true, | ||
}, | ||
explain_code = { | ||
-- Show "Fitten Code - Explain Code" in the editor context menu, when you right-click on the code. | ||
show_in_editor_context_menu = true, | ||
}, | ||
find_bugs = { | ||
-- Show "Fitten Code - Find Bugs" in the editor context menu, when you right-click on the code. | ||
show_in_editor_context_menu = true, | ||
}, | ||
generate_unit_test = { | ||
-- Show "Fitten Code - Generate UnitTest" in the editor context menu, when you right-click on the code. | ||
show_in_editor_context_menu = true, | ||
}, | ||
optimize_code = { | ||
-- Show "Fitten Code - Optimize Code" in the editor context menu, when you right-click on the code. | ||
show_in_editor_context_menu = true, | ||
}, | ||
start_chat = { | ||
-- Show "Fitten Code - Start Chat" in the editor context menu, when you right-click on the code. | ||
show_in_editor_context_menu = true, | ||
}, | ||
}, | ||
delay_completion = { | ||
-- Delay time for inline completion (in milliseconds). | ||
---@type integer | ||
delaytime = 0, | ||
}, | ||
disable_specific_inline_completion = { | ||
-- Disable auto-completion for some specific file suffixes by entering them below | ||
-- For instances, `suffixes = {'lua', 'cpp'}` | ||
suffixes = {}, | ||
}, | ||
-- Document File | ||
document_file = '', | ||
inline_completion = { | ||
-- Enable inline code completion. | ||
---@type boolean | ||
enable = true, | ||
-- Disable auto completion when the cursor is within the line. | ||
---@type boolean | ||
disable_completion_within_the_line = false, | ||
-- Disable auto completion when pressing Backspace or Delete. | ||
---@type boolean | ||
disable_completion_when_delete = false, | ||
-- Auto triggering completion | ||
---@type boolean | ||
auto_triggering_completion = true, | ||
}, | ||
language_preference = { | ||
-- Language preference when using function "Fitten Code - Document Code". | ||
-- Avaiable options: | ||
-- * 'en' | ||
-- * 'zh-cn' | ||
-- * 'auto' | ||
comment_preference = 'auto', | ||
-- Language preference for display and responses in Fitten Code (excluding "Fitten Code - Document Code" function). | ||
-- Avaiable options: | ||
-- * 'en' | ||
-- * 'zh-cn' | ||
-- * 'auto' | ||
display_preference = 'auto', | ||
}, | ||
-- Show menu as submenu in the editor context menu, when you right-click on the code. | ||
show_submenu = false, | ||
snippet = { | ||
-- The comment / document snippet as the style reference for Fitten Code's Document Code function. | ||
comment = '', | ||
}, | ||
unit_test_framework = { | ||
-- Unit Test Framework for C/C++ | ||
-- Avaiable options: | ||
-- * 'gmock', | ||
-- * 'gtest' | ||
['C/C++'] = 'Not specified', | ||
-- Unit Test Framework for Go | ||
-- Avaiable options: | ||
-- * 'gomock' | ||
-- * 'gotests' | ||
-- * 'testify' | ||
-- * 'monkey' | ||
-- * 'sqlmock' | ||
-- * 'httptest' | ||
['Go'] = 'Not specified', | ||
-- Unit Test Framework for Java | ||
-- Avaiable options: | ||
-- * 'mockito' | ||
-- * 'junit4' | ||
-- * 'junit5' | ||
-- * 'testNG' | ||
-- * 'spock' | ||
-- * 'jmockit' | ||
['Java'] = 'Not specified', | ||
-- Unit Test Framework for JavaScript/TypeScript | ||
-- Avaiable options: | ||
-- * 'mock' | ||
-- * 'jest' | ||
-- * 'tape' | ||
-- * 'mocha' | ||
['JavaScript/Typescript'] = 'Not specified', | ||
-- Unit Test Framework for Python | ||
-- Avaiable options: | ||
-- * 'mock' | ||
-- * 'pytest' | ||
-- * 'doctest' | ||
-- * 'unittest' | ||
['Python'] = 'Not specified', | ||
}, | ||
use_project_completion = { | ||
-- Entire Project Perception based Completion | ||
-- Avaiable options: | ||
-- * 'auto' | ||
-- * 'on' | ||
-- * 'off' | ||
open = 'auto', | ||
}, | ||
use_default_keymaps = true, | ||
-- Default keymaps for Fitten Code. | ||
keymaps = { | ||
inline = { | ||
['<TAB>'] = 'accept_all_suggestions', | ||
['<C-Down>'] = 'accept_line', | ||
['<C-Right>'] = 'accept_word', | ||
['<A-\\>'] = 'triggering_completion', | ||
}, | ||
}, | ||
integration = { | ||
completion = { | ||
-- Enable source completion. | ||
enable = false, | ||
-- Completion engines available: | ||
-- * 'cmp' > https://github.com/hrsh7th/nvim-cmp | ||
-- * 'coc' > https://github.com/neoclide/coc.nvim | ||
-- * 'ycm' > https://github.com/ycm-core/YouCompleteMe | ||
engine = 'cmp', | ||
-- Default trigger characters | ||
trigger_chars = {}, | ||
}, | ||
telescope = { | ||
enable = false, | ||
}, | ||
neotree = { | ||
enable = false, | ||
}, | ||
neogit = { | ||
enable = false, | ||
}, | ||
vgit = { | ||
enable = false, | ||
}, | ||
}, | ||
log = { | ||
level = vim.log.levels.WARN, | ||
}, | ||
} | ||
|
||
local options = {} | ||
---@type fittencode.Config | ||
local options | ||
|
||
---@param opts? fittencode.Config | ||
function M.setup(opts) | ||
vim.api.nvim_create_user_command('FittenCode', function(input) | ||
require('fittencode.command').execute(input) | ||
end, { | ||
nargs = '*', | ||
complete = function(...) | ||
return require('fittencode.command').complete(...) | ||
end, | ||
desc = 'FittenCode', | ||
}) | ||
opts = opts or {} | ||
if opts.use_default_keymaps == false then | ||
defaults.keymaps.inline = {} | ||
end | ||
options = vim.tbl_deep_extend('force', defaults, opts) | ||
end | ||
|
||
return setmetatable(M, { | ||
__index = function(_, key) | ||
return options[key] | ||
end, | ||
__index = function(_, key) | ||
return options[key] | ||
end, | ||
}) |
Empty file.
Oops, something went wrong.