add auto_save and fix bugs
This commit is contained in:
@@ -73,7 +73,7 @@ require("memos").setup({
|
|||||||
|
|
||||||
-- Number of memos to fetch per page
|
-- Number of memos to fetch per page
|
||||||
pageSize = 50,
|
pageSize = 50,
|
||||||
|
auto_save = false,
|
||||||
-- Set to false or nil to disable a keymap
|
-- Set to false or nil to disable a keymap
|
||||||
keymaps = {
|
keymaps = {
|
||||||
-- Keymap to open the memos list. Default: <leader>mm
|
-- Keymap to open the memos list. Default: <leader>mm
|
||||||
@@ -176,7 +176,7 @@ require("memos").setup({
|
|||||||
|
|
||||||
-- 每页获取的 memo 数量
|
-- 每页获取的 memo 数量
|
||||||
pageSize = 50,
|
pageSize = 50,
|
||||||
|
auto_save = false,
|
||||||
-- 设置为 false 或 nil 可以禁用某个快捷键
|
-- 设置为 false 或 nil 可以禁用某个快捷键
|
||||||
keymaps = {
|
keymaps = {
|
||||||
-- 用于打开 Memos 列表的快捷键。默认值: <leader>mm
|
-- 用于打开 Memos 列表的快捷键。默认值: <leader>mm
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ local M = {}
|
|||||||
M.config = {
|
M.config = {
|
||||||
host = nil,
|
host = nil,
|
||||||
token = nil,
|
token = nil,
|
||||||
|
auto_save = false,
|
||||||
pageSize = 50,
|
pageSize = 50,
|
||||||
keymaps = {
|
keymaps = {
|
||||||
start_memos = "<leader>mm",
|
start_memos = "<leader>mm",
|
||||||
@@ -31,15 +32,21 @@ local config_file_path = config_dir .. "/memos_config.json"
|
|||||||
-- 【修改】全新的、能处理 host 和 token 的交互式配置函数
|
-- 【修改】全新的、能处理 host 和 token 的交互式配置函数
|
||||||
local function prompt_for_config()
|
local function prompt_for_config()
|
||||||
local function prompt_for_token()
|
local function prompt_for_token()
|
||||||
vim.ui.input({ prompt = "Memos Access Token:", hide = true }, function(token)
|
vim.ui.input({
|
||||||
|
prompt = "Memos Access Token:",
|
||||||
|
hide = true
|
||||||
|
}, function(token)
|
||||||
if token and token ~= "" then
|
if token and token ~= "" then
|
||||||
M.config.token = token
|
M.config.token = token
|
||||||
local choice = vim.fn.confirm("Save host and token for future sessions?", "&Yes\n&No", 2)
|
local choice = vim.fn.confirm("Save host and token for future sessions?", "&Yes\n&No", 2)
|
||||||
if choice == 1 then
|
if choice == 1 then
|
||||||
vim.fn.mkdir(config_dir, "p")
|
vim.fn.mkdir(config_dir, "p")
|
||||||
-- 将 host 和 token 一起存入 JSON 文件
|
-- 将 host 和 token 一起存入 JSON 文件
|
||||||
local config_to_save = { host = M.config.host, token = M.config.token }
|
local config_to_save = {
|
||||||
vim.fn.writefile({ vim.json.encode(config_to_save) }, config_file_path)
|
host = M.config.host,
|
||||||
|
token = M.config.token
|
||||||
|
}
|
||||||
|
vim.fn.writefile({vim.json.encode(config_to_save)}, config_file_path)
|
||||||
vim.notify("Host and token saved permanently.", vim.log.levels.INFO)
|
vim.notify("Host and token saved permanently.", vim.log.levels.INFO)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -49,7 +56,9 @@ local function prompt_for_config()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not M.config.host then
|
if not M.config.host then
|
||||||
vim.ui.input({ prompt = "Memos Host URL (e.g., http://127.0.0.1:5230):" }, function(host)
|
vim.ui.input({
|
||||||
|
prompt = "Memos Host URL (e.g., http://127.0.0.1:5230):"
|
||||||
|
}, function(host)
|
||||||
if host and host ~= "" then
|
if host and host ~= "" then
|
||||||
M.config.host = host
|
M.config.host = host
|
||||||
-- 获取到 host 后,接着获取 token
|
-- 获取到 host 后,接着获取 token
|
||||||
@@ -64,7 +73,6 @@ local function prompt_for_config()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
-- 1. 先加载默认配置
|
-- 1. 先加载默认配置
|
||||||
local final_config = vim.deepcopy(M.config)
|
local final_config = vim.deepcopy(M.config)
|
||||||
|
|||||||
104
lua/memos/ui.lua
104
lua/memos/ui.lua
@@ -17,7 +17,9 @@ local current_filter = nil
|
|||||||
-- 渲染 Memos 列表到 buffer
|
-- 渲染 Memos 列表到 buffer
|
||||||
local function render_memos(data, append)
|
local function render_memos(data, append)
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
if not buf_id or not vim.api.nvim_buf_is_valid(buf_id) then return end
|
if not buf_id or not vim.api.nvim_buf_is_valid(buf_id) then
|
||||||
|
return
|
||||||
|
end
|
||||||
local new_memos = data.memos or {}
|
local new_memos = data.memos or {}
|
||||||
current_page_token = data.nextPageToken or ""
|
current_page_token = data.nextPageToken or ""
|
||||||
if append then
|
if append then
|
||||||
@@ -54,7 +56,6 @@ local function setup_buffer_for_editing()
|
|||||||
vim.bo.bufhidden = 'wipe'
|
vim.bo.bufhidden = 'wipe'
|
||||||
vim.bo.swapfile = false
|
vim.bo.swapfile = false
|
||||||
vim.bo.buflisted = true
|
vim.bo.buflisted = true
|
||||||
|
|
||||||
vim.bo.filetype = 'markdown'
|
vim.bo.filetype = 'markdown'
|
||||||
|
|
||||||
local save_key_string = ""
|
local save_key_string = ""
|
||||||
@@ -70,20 +71,68 @@ local function setup_buffer_for_editing()
|
|||||||
|
|
||||||
vim.api.nvim_buf_create_user_command(0, 'MemosSave', 'lua require("memos.ui").save_or_create_dispatcher()', {})
|
vim.api.nvim_buf_create_user_command(0, 'MemosSave', 'lua require("memos.ui").save_or_create_dispatcher()', {})
|
||||||
if config.keymaps.buffer.save and config.keymaps.buffer.save ~= "" then
|
if config.keymaps.buffer.save and config.keymaps.buffer.save ~= "" then
|
||||||
vim.api.nvim_buf_set_keymap(0, 'n', config.keymaps.buffer.save, '<Cmd>MemosSave<CR>', { noremap = true, silent = true })
|
vim.api.nvim_buf_set_keymap(0, 'n', config.keymaps.buffer.save, '<Cmd>MemosSave<CR>', {
|
||||||
|
noremap = true,
|
||||||
|
silent = true
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 【修改】全新的、更可靠的自动保存逻辑
|
||||||
|
if config.auto_save then
|
||||||
|
local group = vim.api.nvim_create_augroup('MemosAutoSave', {
|
||||||
|
clear = true
|
||||||
|
})
|
||||||
|
|
||||||
|
-- 1. 进入插入模式时,保存当前内容的快照
|
||||||
|
vim.api.nvim_create_autocmd('InsertEnter', {
|
||||||
|
group = group,
|
||||||
|
buffer = 0,
|
||||||
|
callback = function()
|
||||||
|
vim.b.memos_original_content = table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n')
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- 2. 离开插入模式时,比较内容是否发生变化
|
||||||
|
vim.api.nvim_create_autocmd('InsertLeave', {
|
||||||
|
group = group,
|
||||||
|
buffer = 0,
|
||||||
|
callback = function()
|
||||||
|
local current_content = table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n')
|
||||||
|
if vim.b.memos_original_content ~= current_content then
|
||||||
|
require('memos.ui').save_or_create_dispatcher()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 打开一个已存在的 Memo
|
-- 打开一个已存在的 Memo
|
||||||
local function open_memo_for_edit(memo, open_cmd)
|
local function open_memo_for_edit(memo, open_cmd)
|
||||||
vim.cmd(open_cmd)
|
-- 1. 根据 memo 信息,构造一个唯一的 buffer 名称
|
||||||
local first_line = memo.content:match("^[^\n]*")
|
local first_line = memo.content:match("^[^\n]*")
|
||||||
local buffer_name = "memos/" .. memo.name:gsub("memos/", "") .. "/" .. first_line:gsub("[/\\]", "_"):sub(1, 50) .. ".md"
|
local buffer_name = "memos/" .. memo.name:gsub("memos/", "") .. "/" .. first_line:gsub("[/\\]", "_"):sub(1, 50) ..
|
||||||
|
".md"
|
||||||
|
|
||||||
|
-- 2. 检查这个名字的 buffer 是否已经存在
|
||||||
|
local existing_bufnr = vim.fn.bufnr(buffer_name)
|
||||||
|
|
||||||
|
if existing_bufnr ~= -1 and vim.api.nvim_buf_is_loaded(existing_bufnr) then
|
||||||
|
-- 3. 如果已存在,则找到它所在的窗口并跳转过去
|
||||||
|
local win_id = vim.fn.bufwinid(existing_bufnr)
|
||||||
|
if win_id ~= -1 then
|
||||||
|
vim.api.nvim_set_current_win(win_id)
|
||||||
|
else
|
||||||
|
-- 如果窗口已关闭但 buffer 仍在,则在当前窗口打开它
|
||||||
|
vim.api.nvim_set_current_buf(existing_bufnr)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- 4. 如果不存在,才执行我们之前的创建新窗口的逻辑
|
||||||
|
vim.cmd(open_cmd)
|
||||||
vim.api.nvim_buf_set_name(0, buffer_name)
|
vim.api.nvim_buf_set_name(0, buffer_name)
|
||||||
vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(memo.content, '\n'))
|
vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(memo.content, '\n'))
|
||||||
vim.b.memos_memo_name = memo.name
|
vim.b.memos_memo_name = memo.name
|
||||||
setup_buffer_for_editing()
|
setup_buffer_for_editing()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
@@ -92,7 +141,9 @@ end
|
|||||||
|
|
||||||
-- 【修正】将此函数移到 render_memos 定义之后,解决报错
|
-- 【修正】将此函数移到 render_memos 定义之后,解决报错
|
||||||
function M.refresh_list_silently()
|
function M.refresh_list_silently()
|
||||||
if not current_user or not current_user.name then return end
|
if not current_user or not current_user.name then
|
||||||
|
return
|
||||||
|
end
|
||||||
api.list_memos(current_user.name, current_filter, config.pageSize, nil, function(data)
|
api.list_memos(current_user.name, current_filter, config.pageSize, nil, function(data)
|
||||||
render_memos(data, false)
|
render_memos(data, false)
|
||||||
end)
|
end)
|
||||||
@@ -110,7 +161,9 @@ function M.save_or_create_dispatcher()
|
|||||||
if memo_name then
|
if memo_name then
|
||||||
api.update_memo(memo_name, content, function(success)
|
api.update_memo(memo_name, content, function(success)
|
||||||
if success then
|
if success then
|
||||||
vim.schedule(function() vim.notify("✅ Memo updated successfully!") end)
|
vim.schedule(function()
|
||||||
|
vim.notify("✅ Memo updated successfully!")
|
||||||
|
end)
|
||||||
M.refresh_list_silently()
|
M.refresh_list_silently()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
@@ -124,7 +177,9 @@ function M.save_or_create_dispatcher()
|
|||||||
M.refresh_list_silently()
|
M.refresh_list_silently()
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
vim.schedule(function() vim.notify("❌ Failed to create memo.", vim.log.levels.ERROR) end)
|
vim.schedule(function()
|
||||||
|
vim.notify("❌ Failed to create memo.", vim.log.levels.ERROR)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -159,22 +214,31 @@ function M.show_memos_list(filter)
|
|||||||
vim.api.nvim_set_current_buf(buf_id)
|
vim.api.nvim_set_current_buf(buf_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.schedule(function() vim.notify("Getting user info...") end)
|
vim.schedule(function()
|
||||||
|
vim.notify("Getting user info...")
|
||||||
|
end)
|
||||||
api.get_current_user(function(user)
|
api.get_current_user(function(user)
|
||||||
if user and user.name then
|
if user and user.name then
|
||||||
current_user = user
|
current_user = user
|
||||||
vim.schedule(function() vim.notify("Fetching memos for " .. user.name .. "...") end)
|
vim.schedule(function()
|
||||||
|
vim.notify("Fetching memos for " .. user.name .. "...")
|
||||||
|
end)
|
||||||
api.list_memos(user.name, current_filter, config.pageSize, nil, function(data)
|
api.list_memos(user.name, current_filter, config.pageSize, nil, function(data)
|
||||||
render_memos(data, false)
|
render_memos(data, false)
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
vim.schedule(function() vim.notify("Could not get user, aborting fetch.", vim.log.levels.ERROR) end)
|
vim.schedule(function()
|
||||||
|
vim.notify("Could not get user, aborting fetch.", vim.log.levels.ERROR)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function set_keymap(key, command)
|
local function set_keymap(key, command)
|
||||||
if key and key ~= "" then
|
if key and key ~= "" then
|
||||||
vim.api.nvim_buf_set_keymap(buf_id, 'n', key, command, { noremap = true, silent = true })
|
vim.api.nvim_buf_set_keymap(buf_id, 'n', key, command, {
|
||||||
|
noremap = true,
|
||||||
|
silent = true
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -201,7 +265,9 @@ function M.load_next_page()
|
|||||||
vim.notify("User info not available.", vim.log.levels.WARN)
|
vim.notify("User info not available.", vim.log.levels.WARN)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
vim.schedule(function() vim.notify("Loading next page...") end)
|
vim.schedule(function()
|
||||||
|
vim.notify("Loading next page...")
|
||||||
|
end)
|
||||||
api.list_memos(current_user.name, current_filter, config.pageSize, current_page_token, function(data)
|
api.list_memos(current_user.name, current_filter, config.pageSize, current_page_token, function(data)
|
||||||
render_memos(data, true)
|
render_memos(data, true)
|
||||||
end)
|
end)
|
||||||
@@ -226,7 +292,9 @@ end
|
|||||||
function M.confirm_delete_memo()
|
function M.confirm_delete_memo()
|
||||||
local line_num = vim.api.nvim_win_get_cursor(0)[1]
|
local line_num = vim.api.nvim_win_get_cursor(0)[1]
|
||||||
local selected_memo = memos_cache[line_num]
|
local selected_memo = memos_cache[line_num]
|
||||||
if not selected_memo then return end
|
if not selected_memo then
|
||||||
|
return
|
||||||
|
end
|
||||||
local choice = vim.fn.confirm("Delete this memo?\n[" .. selected_memo.content:sub(1, 50) .. "...]", "&Yes\n&No", 2)
|
local choice = vim.fn.confirm("Delete this memo?\n[" .. selected_memo.content:sub(1, 50) .. "...]", "&Yes\n&No", 2)
|
||||||
if choice == 1 then
|
if choice == 1 then
|
||||||
api.delete_memo(selected_memo.name, function(success)
|
api.delete_memo(selected_memo.name, function(success)
|
||||||
@@ -236,14 +304,18 @@ function M.confirm_delete_memo()
|
|||||||
M.show_memos_list(current_filter)
|
M.show_memos_list(current_filter)
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
vim.schedule(function() vim.notify("❌ Failed to delete memo.", vim.log.levels.ERROR) end)
|
vim.schedule(function()
|
||||||
|
vim.notify("❌ Failed to delete memo.", vim.log.levels.ERROR)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.search_memos()
|
function M.search_memos()
|
||||||
vim.ui.input({ prompt = "Search Memos: " }, function(input)
|
vim.ui.input({
|
||||||
|
prompt = "Search Memos: "
|
||||||
|
}, function(input)
|
||||||
M.show_memos_list(input or "")
|
M.show_memos_list(input or "")
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user