feat: add configurable floating window support for memo list

- Added `window` configuration options (enable_float, width, height, border).
- Implemented LazyVim-style floating window logic in UI.
- Updated README (EN/CN) and help docs with new configuration examples.
This commit is contained in:
Elflare
2025-11-29 14:11:38 +08:00
parent 052120b726
commit b4a381c52c
4 changed files with 161 additions and 98 deletions

View File

@@ -11,6 +11,7 @@ A Neovim plugin to interact with [Memos](https://github.com/usememos/memos) righ
- **Delete Memos**: Delete memos directly from the list. - **Delete Memos**: Delete memos directly from the list.
- **Customizable**: Configure API endpoints, keymaps, and more. - **Customizable**: Configure API endpoints, keymaps, and more.
- **First-time Setup**: On first launch, you will be prompted to enter your Memos host and token. You can choose to save these permanently. - **First-time Setup**: On first launch, you will be prompted to enter your Memos host and token. You can choose to save these permanently.
- **Floating Window**: Optional LazyVim-style floating window for the memo list.
## 📦 Installation ## 📦 Installation
@@ -75,6 +76,13 @@ require("memos").setup({
-- Auto-save the memo when leaving insert mode or holding the cursor. -- Auto-save the memo when leaving insert mode or holding the cursor.
auto_save = false, auto_save = false,
-- Window configuration
window = {
enable_float = false, -- Set to true to open the list in a floating window
width = 0.85, -- Width ratio (0.0 to 1.0)
height = 0.85, -- Height ratio (0.0 to 1.0)
border = "rounded", -- Border style: "single", "double", "rounded", "solid", "shadow"
},
-- Set to false or nil to disable a keymap -- Set to false or nil to disable a keymap
keymaps = { keymaps = {
@@ -117,6 +125,7 @@ require("memos").setup({
- **删除 Memos**: 直接从列表中删除 memo。 - **删除 Memos**: 直接从列表中删除 memo。
- **可定制**: 可配置 API 地址、快捷键等。 - **可定制**: 可配置 API 地址、快捷键等。
- **首次启动引导**: 首次启动时会提示输入 Memos 的 host 和 token并询问是否永久保存。 - **首次启动引导**: 首次启动时会提示输入 Memos 的 host 和 token并询问是否永久保存。
- **浮动窗口**: 可选的 LazyVim 风格浮动窗口来展示 memo 列表。
## 📦 安装 ## 📦 安装
@@ -181,6 +190,13 @@ require("memos").setup({
-- 当离开插入模式或光标静止时,自动保存 memo。 -- 当离开插入模式或光标静止时,自动保存 memo。
auto_save = false, auto_save = false,
-- 窗口配置
window = {
enable_float = false, -- 设置为 true 以在浮动窗口中打开列表
width = 0.85, -- 宽度比例 (0.0 到 1.0)
height = 0.85, -- 高度比例 (0.0 到 1.0)
border = "rounded", -- 边框样式: "single", "double", "rounded", "solid", "shadow"
},
-- 设置为 false 或 nil 可以禁用某个快捷键 -- 设置为 false 或 nil 可以禁用某个快捷键
keymaps = { keymaps = {

View File

@@ -43,6 +43,13 @@ require("memos").setup({
-- Number of memos to fetch per page -- Number of memos to fetch per page
pageSize = 50, pageSize = 50,
auto_save = false, auto_save = false,
-- Window configuration
window = {
enable_float = false, -- Set to true to open the list in a floating window
width = 0.85, -- Width ratio (0.0 to 1.0)
height = 0.85, -- Height ratio (0.0 to 1.0)
border = "rounded", -- Border style: "single", "double", "rounded", "solid", "shadow"
},
-- 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

View File

@@ -5,25 +5,32 @@ M.config = {
token = nil, token = nil,
auto_save = false, auto_save = false,
page_size = 50, page_size = 50,
-- 【新增】窗口配置
window = {
enable_float = false, -- 默认为 false设为 true 则开启浮动窗口
width = 0.85, -- 宽度占屏幕比例
height = 0.85, -- 高度占屏幕比例
border = "rounded", -- 边框样式: "single", "double", "rounded", "solid", "shadow"
},
keymaps = { keymaps = {
start_memos = "<leader>mm", start_memos = "<leader>mm",
-- 在列表窗口中的快捷键 -- 在列表窗口中的快捷键
list = { list = {
add_memo = 'a', add_memo = "a",
delete_memo = 'd', delete_memo = "d",
delete_memo_visual = 'dd', delete_memo_visual = "dd",
edit_memo = '<CR>', edit_memo = "<CR>",
vsplit_edit_memo = '<Tab>', vsplit_edit_memo = "<Tab>",
search_memos = 's', search_memos = "s",
refresh_list = 'r', refresh_list = "r",
next_page = '.', next_page = ".",
quit = 'q' quit = "q",
}, },
-- 在编辑和创建窗口中的快捷键 -- 在编辑和创建窗口中的快捷键
buffer = { buffer = {
save = '<leader>ms' save = "<leader>ms",
} },
} },
} }
local config_dir = vim.fn.stdpath("data") .. "/memos.nvim" local config_dir = vim.fn.stdpath("data") .. "/memos.nvim"
@@ -34,7 +41,7 @@ local function prompt_for_config()
local function prompt_for_token() local function prompt_for_token()
vim.ui.input({ vim.ui.input({
prompt = "Memos Access Token:", prompt = "Memos Access Token:",
hide = true hide = true,
}, function(token) }, function(token)
if token and token ~= "" then if token and token ~= "" then
M.config.token = token M.config.token = token
@@ -44,9 +51,9 @@ local function prompt_for_config()
-- 将 host 和 token 一起存入 JSON 文件 -- 将 host 和 token 一起存入 JSON 文件
local config_to_save = { local config_to_save = {
host = M.config.host, host = M.config.host,
token = M.config.token token = M.config.token,
} }
vim.fn.writefile({vim.json.encode(config_to_save)}, config_file_path) 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
@@ -57,7 +64,7 @@ local function prompt_for_config()
if not M.config.host then if not M.config.host then
vim.ui.input({ vim.ui.input({
prompt = "Memos Host URL (e.g., http://127.0.0.1:5230):" prompt = "Memos Host URL (e.g., http://127.0.0.1:5230):",
}, function(host) }, function(host)
if host and host ~= "" then if host and host ~= "" then
M.config.host = host M.config.host = host
@@ -87,11 +94,11 @@ function M.setup(opts)
end end
-- 3. 加载环境变量 (优先级高于文件) -- 3. 加载环境变量 (优先级高于文件)
local token_from_env = os.getenv('MEMOS_TOKEN') local token_from_env = os.getenv("MEMOS_TOKEN")
if token_from_env and token_from_env ~= "" then if token_from_env and token_from_env ~= "" then
final_config.token = token_from_env final_config.token = token_from_env
end end
local host_from_env = os.getenv('MEMOS_HOST') local host_from_env = os.getenv("MEMOS_HOST")
if host_from_env and host_from_env ~= "" then if host_from_env and host_from_env ~= "" then
final_config.host = host_from_env final_config.host = host_from_env
end end
@@ -113,13 +120,13 @@ end
function M.create_memo() function M.create_memo()
ensure_config(function() ensure_config(function()
require('memos.ui').create_memo_in_buffer() require("memos.ui").create_memo_in_buffer()
end) end)
end end
function M.show_list() function M.show_list()
ensure_config(function() ensure_config(function()
require('memos.ui').show_memos_list() require("memos.ui").show_memos_list()
end) end)
end end

View File

@@ -193,26 +193,59 @@ function M.create_memo_in_buffer()
M.setup_buffer_for_editing() M.setup_buffer_for_editing()
end end
-- 【新增】创建居中浮动窗口的辅助函数
local function create_float_window(buf)
local width = math.floor(vim.o.columns * (config.window.width or 0.8))
local height = math.floor(vim.o.lines * (config.window.height or 0.8))
-- 计算居中位置
local row = math.floor((vim.o.lines - height) / 2)
local col = math.floor((vim.o.columns - width) / 2)
local opts = {
relative = "editor",
row = row,
col = col,
width = width,
height = height,
style = "minimal",
border = config.window.border or "rounded",
title = " Memos ",
title_pos = "center",
}
return vim.api.nvim_open_win(buf, true, opts)
end
function M.show_memos_list(filter) function M.show_memos_list(filter)
current_filter = filter current_filter = filter
local should_create_buf = true local should_create_buf = true
-- 检查 buffer 是否存在且有效
if buf_id and vim.api.nvim_buf_is_valid(buf_id) then if buf_id and vim.api.nvim_buf_is_valid(buf_id) then
should_create_buf = false should_create_buf = false
else else
buf_id = vim.api.nvim_create_buf(true, true) buf_id = vim.api.nvim_create_buf(false, true) -- 改为 false, true (unlisted, scratch)
vim.api.nvim_buf_set_name(buf_id, " Memos") vim.api.nvim_buf_set_name(buf_id, "MemosList")
vim.bo[buf_id].buftype = "nofile" vim.bo[buf_id].buftype = "nofile"
vim.bo[buf_id].swapfile = false vim.bo[buf_id].swapfile = false
vim.bo[buf_id].filetype = "memos_list" vim.bo[buf_id].filetype = "memos_list"
vim.bo[buf_id].modifiable = false vim.bo[buf_id].modifiable = false
end end
-- 检查该 buffer 是否已经在一个窗口中打开
local win_id = vim.fn.bufwinid(buf_id) local win_id = vim.fn.bufwinid(buf_id)
if win_id ~= -1 then if win_id ~= -1 then
vim.api.nvim_set_current_win(win_id) vim.api.nvim_set_current_win(win_id)
else else
-- 【修改】根据配置决定打开方式
if config.window and config.window.enable_float then
create_float_window(buf_id)
else
-- 传统方式:直接切换到该 buffer
vim.api.nvim_set_current_buf(buf_id) vim.api.nvim_set_current_buf(buf_id)
end end
end
vim.schedule(function() vim.schedule(function()
vim.notify("Getting user info...") vim.notify("Getting user info...")