first commit
This commit is contained in:
269
README.md
269
README.md
@@ -1 +1,270 @@
|
||||
# memos.nvim
|
||||
|
||||
English | [简体中文](./README.md#memosnvim-简体中文)
|
||||
|
||||
A Neovim plugin to interact with [Memos](https://github.com/usememos/memos) right inside the editor. List, create, edit, and delete your memos without leaving Neovim.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **List Memos**: View, search, and paginate through your memos in a floating window.
|
||||
- **Create & Edit**: Create new memos or edit existing ones in a dedicated buffer with `markdown` filetype support.
|
||||
- **Delete Memos**: Delete memos directly from the list.
|
||||
- **Customizable**: Configure API endpoints, keymaps, and more.
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
Requires [plenary.nvim](https://github.com/nvim-lua/plenary.nvim).
|
||||
|
||||
Install with [lazy.nvim](https://github.com/folke/lazy.nvim):
|
||||
|
||||
```lua
|
||||
-- lua/plugins/memos.lua
|
||||
|
||||
return {
|
||||
-- Memos.nvim: A plugin to interact with Memos from within Neovim
|
||||
{
|
||||
-- IMPORTANT: Replace with your actual GitHub username/repo
|
||||
"your-github-username/memos.nvim",
|
||||
|
||||
-- Optional, but good for identification in Lazy UI
|
||||
name = "memos.nvim",
|
||||
|
||||
dependencies = { "nvim-lua/plenary.nvim" },
|
||||
|
||||
-- Load the plugin on these commands
|
||||
cmd = { "Memos", "MemosCreate" },
|
||||
|
||||
config = function()
|
||||
require("memos").setup({
|
||||
-- REQUIRED: Your Memos host URL
|
||||
host = "https://your-memos-host.com",
|
||||
|
||||
-- REQUIRED: Your Memos API token (Open API)
|
||||
token = "your-super-secret-token",
|
||||
|
||||
-- Optional: Customize keymaps
|
||||
keymaps = {
|
||||
-- Keymaps for the editing/creating buffer
|
||||
buffer = {
|
||||
save = "<leader>ms", -- Save the current memo
|
||||
},
|
||||
-- Keymaps for the memo list window
|
||||
list = {
|
||||
add_memo = "a", -- Add a new memo
|
||||
edit_memo = "<CR>", -- Edit selected memo
|
||||
-- ... other keymaps can be configured here
|
||||
}
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
|
||||
-- Plenary is a required dependency
|
||||
{
|
||||
"nvim-lua/plenary.nvim",
|
||||
lazy = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 Usage
|
||||
|
||||
### Commands
|
||||
|
||||
- `:Memos`: Opens a floating window to list and search your memos.
|
||||
- `:MemosCreate`: Opens a new buffer to create a new memo.
|
||||
- `:MemosSave`: (Available in the memo buffer) Saves the memo you are currently creating or editing.
|
||||
|
||||
### Default Keymaps
|
||||
|
||||
#### In the Memo List Window
|
||||
|
||||
| Key | Action |
|
||||
| ------------------ | ------------------------------------ |
|
||||
| `a` | Add a new memo |
|
||||
| `d` or `dd` | Delete the selected memo |
|
||||
| `<CR>` | Edit the selected memo |
|
||||
| `<Tab>` | Edit the selected memo in a vsplit |
|
||||
| `s` | Search your memos |
|
||||
| `r` | Refresh the memo list |
|
||||
| `.` | Load the next page of memos |
|
||||
| `q` | Quit the list window |
|
||||
|
||||
#### In the Edit/Create Buffer
|
||||
|
||||
| Key | Action |
|
||||
| ------------------ | ------------------------------------ |
|
||||
| `<leader>ms` | Save the current memo |
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
You can override the default settings by passing a table to the `setup()` function.
|
||||
|
||||
```lua
|
||||
require("memos").setup({
|
||||
-- REQUIRED: Your Memos host URL
|
||||
host = "https://your-memos-host.com",
|
||||
|
||||
-- REQUIRED: Your Memos API token (Open API)
|
||||
token = "your-super-secret-token",
|
||||
|
||||
-- Number of memos to fetch per page
|
||||
pageSize = 50,
|
||||
|
||||
-- Set to false or nil to disable a keymap
|
||||
keymaps = {
|
||||
-- Keymaps for the memo list window
|
||||
list = {
|
||||
add_memo = "a",
|
||||
delete_memo = "d",
|
||||
delete_memo_visual = "dd",
|
||||
edit_memo = "<CR>",
|
||||
vsplit_edit_memo = "<Tab>",
|
||||
search_memos = "s",
|
||||
refresh_list = "r",
|
||||
next_page = ".",
|
||||
quit = "q",
|
||||
},
|
||||
-- Keymaps for the editing/creating buffer
|
||||
buffer = {
|
||||
save = "<leader>ms",
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# memos.nvim (简体中文)
|
||||
|
||||
[English](./README.md#memosnvim) | 简体中文
|
||||
|
||||
一个 Neovim 插件,让你在编辑器内部直接与 [Memos](https://github.com/usememos/memos) 进行交互。无需离开 Neovim 即可列表、创建、编辑和删除你的 memos。
|
||||
|
||||
## ✨ 功能
|
||||
|
||||
- **列表 Memos**: 在浮动窗口中查看、搜索和翻页你的 memos。
|
||||
- **创建与编辑**: 在专用的、支持 `markdown` 文件类型的缓冲区中创建新 memo 或编辑现有 memo。
|
||||
- **删除 Memos**: 直接从列表中删除 memo。
|
||||
- **可定制**: 可配置 API 地址、快捷键等。
|
||||
|
||||
## 📦 安装
|
||||
|
||||
需要 [plenary.nvim](https://github.com/nvim-lua/plenary.nvim) 插件。
|
||||
|
||||
使用 [lazy.nvim](https://github.com/folke/lazy.nvim) 安装:
|
||||
|
||||
```lua
|
||||
-- lua/plugins/memos.lua
|
||||
|
||||
return {
|
||||
-- Memos.nvim: 一个在 Neovim 中与 Memos 交互的插件
|
||||
{
|
||||
-- 重要: 请将这里替换为你的 GitHub 用户名/仓库名
|
||||
"your-github-username/memos.nvim",
|
||||
|
||||
-- 可选,但在 Lazy 管理界面中易于识别
|
||||
name = "memos.nvim",
|
||||
|
||||
dependencies = { "nvim-lua/plenary.nvim" },
|
||||
|
||||
-- 在执行这些命令时加载插件
|
||||
cmd = { "Memos", "MemosCreate" },
|
||||
|
||||
config = function()
|
||||
require("memos").setup({
|
||||
-- 必填: 你的 Memos 服务地址
|
||||
host = "https://your-memos-host.com",
|
||||
|
||||
-- 必填: 你的 Memos API 令牌 (Open API)
|
||||
token = "your-super-secret-token",
|
||||
|
||||
-- 可选: 自定义快捷键
|
||||
keymaps = {
|
||||
-- 编辑/创建窗口的快捷键
|
||||
buffer = {
|
||||
save = "<leader>ms", -- 保存当前 memo
|
||||
},
|
||||
-- memo 列表窗口的快捷键
|
||||
list = {
|
||||
add_memo = "a", -- 新增 memo
|
||||
edit_memo = "<CR>", -- 编辑所选 memo
|
||||
-- ... 其他快捷键也可以在这里配置
|
||||
}
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
|
||||
-- Plenary 是一个必要的依赖
|
||||
{
|
||||
"nvim-lua/plenary.nvim",
|
||||
lazy = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 命令
|
||||
|
||||
- `:Memos`: 打开一个浮动窗口,列出并搜索你的 memos。
|
||||
- `:MemosCreate`: 打开一个新的缓冲区来创建 memo。
|
||||
- `:MemosSave`: (在 memo 编辑缓冲区中可用) 保存你正在创建或编辑的 memo。
|
||||
|
||||
### 默认快捷键
|
||||
|
||||
#### 在 Memo 列表窗口中
|
||||
|
||||
| 按键 | 功能 |
|
||||
| ------------------ | ---------------------------------- |
|
||||
| `a` | 新增一个 memo |
|
||||
| `d` 或 `dd` | 删除所选的 memo |
|
||||
| `<CR>` | 编辑所选的 memo |
|
||||
| `<Tab>` | 在垂直分屏中编辑所选的 memo |
|
||||
| `s` | 搜索你的 memos |
|
||||
| `r` | 刷新 memo 列表 |
|
||||
| `.` | 加载下一页 memos |
|
||||
| `q` | 退出列表窗口 |
|
||||
|
||||
#### 在编辑/创建缓冲区中
|
||||
|
||||
| 按键 | 功能 |
|
||||
| ------------------ | ---------------------------------- |
|
||||
| `<leader>ms` | 保存当前 memo |
|
||||
|
||||
## ⚙️ 配置
|
||||
|
||||
你可以通过向 `setup()` 函数传递一个 table 来覆盖默认设置。
|
||||
|
||||
```lua
|
||||
require("memos").setup({
|
||||
-- 必填: 你的 Memos 服务地址
|
||||
host = "https://your-memos-host.com",
|
||||
|
||||
-- 必填: 你的 Memos API 令牌 (Open API)
|
||||
token = "your-super-secret-token",
|
||||
|
||||
-- 每页获取的 memo 数量
|
||||
pageSize = 50,
|
||||
|
||||
-- 设置为 false 或 nil 可以禁用某个快捷键
|
||||
keymaps = {
|
||||
-- memo 列表窗口的快捷键
|
||||
list = {
|
||||
add_memo = "a",
|
||||
delete_memo = "d",
|
||||
delete_memo_visual = "dd",
|
||||
edit_memo = "<CR>",
|
||||
vsplit_edit_memo = "<Tab>",
|
||||
search_memos = "s",
|
||||
refresh_list = "r",
|
||||
next_page = ".",
|
||||
quit = "q",
|
||||
},
|
||||
-- 编辑/创建窗口的快捷键
|
||||
buffer = {
|
||||
save = "<leader>ms",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
133
doc/memos.nvim.txt
Normal file
133
doc/memos.nvim.txt
Normal file
@@ -0,0 +1,133 @@
|
||||
*memos.nvim.txt* For Neovim | English and 简体中文
|
||||
|
||||
==============================================================================
|
||||
CONTENTS *memos.nvim-contents*
|
||||
|
||||
1. About....................................|memos-about|
|
||||
2. Features.................................|memos-features|
|
||||
3. Installation.............................|memos-installation|
|
||||
4. Usage....................................|memos-usage|
|
||||
5. Configuration............................|memos-configuration|
|
||||
|
||||
==============================================================================
|
||||
1. About *memos-about*
|
||||
|
||||
A Neovim plugin to interact with Memos (https://github.com/usememos/memos)
|
||||
right inside the editor. List, create, edit, and delete your memos without
|
||||
leaving Neovim.
|
||||
|
||||
一个 Neovim 插件,让你在编辑器内部直接与 Memos 进行交互。无需离开 Neovim
|
||||
即可列表、创建、编辑和删除你的 memos。
|
||||
|
||||
==============================================================================
|
||||
2. Features *memos-features*
|
||||
|
||||
- *List Memos*: View, search, and paginate through your memos in a floating
|
||||
window.
|
||||
- *Create & Edit*: Create new memos or edit existing ones in a dedicated
|
||||
buffer with `markdown` filetype support.
|
||||
- *Delete Memos*: Delete memos directly from the list.
|
||||
- *Lazy Loading*: The plugin is loaded only when you run one of its commands.
|
||||
- *Customizable*: Configure API endpoints, keymaps, and more.
|
||||
|
||||
==============================================================================
|
||||
3. Installation *memos-installation*
|
||||
|
||||
Requires |plenary.nvim|.
|
||||
|
||||
Install with |lazy.nvim|:
|
||||
>lua
|
||||
-- lua/plugins/memos.lua
|
||||
return {
|
||||
{
|
||||
"your-github-username/memos.nvim",
|
||||
name = "memos.nvim",
|
||||
dependencies = { "nvim-lua/plenary.nvim" },
|
||||
cmd = { "Memos", "MemosCreate" },
|
||||
config = function()
|
||||
require("memos").setup({
|
||||
host = "https://your-memos-host.com",
|
||||
token = "your-super-secret-token",
|
||||
})
|
||||
end,
|
||||
},
|
||||
{
|
||||
"nvim-lua/plenary.nvim",
|
||||
lazy = true,
|
||||
},
|
||||
}
|
||||
<
|
||||
==============================================================================
|
||||
4. Usage *memos-usage*
|
||||
|
||||
COMMANDS *memos-commands*
|
||||
|
||||
*:Memos*
|
||||
Opens a floating window to list and search your memos.
|
||||
|
||||
*:MemosCreate*
|
||||
Opens a new buffer to create a new memo.
|
||||
|
||||
*:MemosSave*
|
||||
(Available in the memo buffer) Saves the memo you are currently
|
||||
creating or editing.
|
||||
|
||||
DEFAULT KEYMAPS *memos-keymaps*
|
||||
|
||||
*In the Memo List Window:*
|
||||
| Key | Action |
|
||||
|--------------------|--------------------------------------|
|
||||
| `a` | Add a new memo |
|
||||
| `d` or `dd` | Delete the selected memo |
|
||||
| `<CR>` | Edit the selected memo |
|
||||
| `<Tab>` | Edit the selected memo in a vsplit |
|
||||
| `s` | Search your memos |
|
||||
| `r` | Refresh the memo list |
|
||||
| `.` | Load the next page of memos |
|
||||
| `q` | Quit the list window |
|
||||
|
||||
*In the Edit/Create Buffer:*
|
||||
| Key | Action |
|
||||
|--------------------|--------------------------------------|
|
||||
| `<leader>ms` | Save the current memo |
|
||||
|
||||
==============================================================================
|
||||
5. Configuration *memos-configuration*
|
||||
|
||||
You can override the default settings by passing a table to the `setup()`
|
||||
function.
|
||||
|
||||
Default configuration:
|
||||
>lua
|
||||
require("memos").setup({
|
||||
-- REQUIRED: Your Memos host URL
|
||||
host = "https://your-memos-host.com",
|
||||
|
||||
-- REQUIRED: Your Memos API token (Open API)
|
||||
token = "your-super-secret-token",
|
||||
|
||||
-- Number of memos to fetch per page
|
||||
pageSize = 50,
|
||||
|
||||
-- Set to false or nil to disable a keymap
|
||||
keymaps = {
|
||||
-- Keymaps for the memo list window
|
||||
list = {
|
||||
add_memo = "a",
|
||||
delete_memo = "d",
|
||||
delete_memo_visual = "dd",
|
||||
edit_memo = "<CR>",
|
||||
vsplit_edit_memo = "<Tab>",
|
||||
search_memos = "s",
|
||||
refresh_list = "r",
|
||||
next_page = ".",
|
||||
quit = "q",
|
||||
},
|
||||
-- Keymaps for the editing/creating buffer
|
||||
buffer = {
|
||||
save = "<leader>ms",
|
||||
},
|
||||
},
|
||||
})
|
||||
<
|
||||
vim:tw=78:ts=8:ft=help:norl:
|
||||
92
lua/memos/api.lua
Normal file
92
lua/memos/api.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
local Job = require('plenary.job')
|
||||
local config = require('memos').config
|
||||
|
||||
local M = {}
|
||||
|
||||
local function run_curl(args, on_exit)
|
||||
table.insert(args, '-H')
|
||||
table.insert(args, 'Authorization: Bearer ' .. config.token)
|
||||
Job:new({ command = 'curl', args = args, on_exit = on_exit }):start()
|
||||
end
|
||||
|
||||
function M.get_current_user(callback)
|
||||
run_curl({
|
||||
'-s', '--fail', '-X', 'POST', config.host .. '/api/v1/auth/status',
|
||||
}, function(job, return_val)
|
||||
if return_val == 0 then
|
||||
local result_string = table.concat(job:result(), "")
|
||||
local data = vim.json.decode(result_string)
|
||||
callback(data or nil)
|
||||
else
|
||||
vim.schedule(function() vim.notify("Failed to get user info.", vim.log.levels.ERROR) end)
|
||||
callback(nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function M.list_memos(parent, filter, pageSize, pageToken, callback)
|
||||
local list_url = config.host .. '/api/v1/memos'
|
||||
local params = {}
|
||||
table.insert(params, "parent=" .. parent)
|
||||
table.insert(params, "pageSize=" .. tostring(pageSize))
|
||||
if pageToken and pageToken ~= "" then table.insert(params, "pageToken=" .. pageToken) end
|
||||
if filter and filter ~= '' then
|
||||
table.insert(params, 'filter=content.contains("' .. vim.fn.escape(filter, '\\"') .. '")')
|
||||
end
|
||||
list_url = list_url .. "?" .. table.concat(params, "&")
|
||||
|
||||
run_curl({
|
||||
'-s', '--fail', '-X', 'GET', list_url,
|
||||
}, function(job, return_val)
|
||||
if return_val == 0 then
|
||||
local result_string = table.concat(job:result(), "")
|
||||
local data = vim.json.decode(result_string)
|
||||
callback({ memos = data.memos or {}, nextPageToken = data.nextPageToken or "" })
|
||||
else
|
||||
vim.schedule(function() vim.notify("Failed to fetch memos.", vim.log.levels.ERROR) end)
|
||||
callback(nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- 【修改】让 create_memo 的回调函数返回新创建的 memo 对象
|
||||
function M.create_memo(content, callback)
|
||||
local create_url = config.host .. '/api/v1/memos'
|
||||
local json_data = vim.json.encode({ content = content })
|
||||
run_curl({
|
||||
'-s', '--fail', '-X', 'POST', create_url,
|
||||
'-H', 'Content-Type: application/json',
|
||||
'--data', json_data,
|
||||
}, function(job, return_val)
|
||||
if return_val == 0 then
|
||||
local result_string = table.concat(job:result(), "")
|
||||
local new_memo = vim.json.decode(result_string)
|
||||
callback(new_memo)
|
||||
else
|
||||
callback(nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function M.update_memo(memo_name, content, callback)
|
||||
local update_url = config.host .. '/api/v1/' .. memo_name
|
||||
local json_data = vim.json.encode({ content = content })
|
||||
run_curl({
|
||||
'-s', '--fail', '-X', 'PATCH', update_url,
|
||||
'-H', 'Content-Type: application/json',
|
||||
'--data', json_data,
|
||||
}, function(job, return_val)
|
||||
callback(return_val == 0)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.delete_memo(memo_name, callback)
|
||||
local delete_url = config.host .. '/api/v1/' .. memo_name
|
||||
run_curl({
|
||||
'-s', '--fail', '-X', 'DELETE', delete_url,
|
||||
}, function(job, return_val)
|
||||
callback(return_val == 0)
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
43
lua/memos/init.lua
Normal file
43
lua/memos/init.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
local M = {}
|
||||
|
||||
M.config = {
|
||||
host = nil,
|
||||
token = nil,
|
||||
pageSize = 50,
|
||||
keymaps = {
|
||||
-- 在列表窗口中的快捷键
|
||||
list = {
|
||||
add_memo = "a",
|
||||
delete_memo = "d",
|
||||
delete_memo_visual = "dd", -- 和 d 功能一样,为了符合习惯
|
||||
edit_memo = "<CR>",
|
||||
vsplit_edit_memo = "<Tab>",
|
||||
search_memos = "s",
|
||||
refresh_list = "r",
|
||||
next_page = ".",
|
||||
quit = "q",
|
||||
},
|
||||
-- 在编辑和创建窗口中的快捷键
|
||||
buffer = {
|
||||
save = "<leader>ms",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
function M.setup(opts)
|
||||
-- 使用 "force" 策略,并将默认配置放在前面,用户的配置在后面
|
||||
M.config = vim.tbl_deep_extend("force", M.config, opts or {})
|
||||
if not M.config.host or not M.config.token then
|
||||
vim.notify("Memos: `host` and `token` must be configured.", vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
|
||||
function M.create_memo()
|
||||
require("memos.ui").create_memo_in_buffer()
|
||||
end
|
||||
|
||||
function M.show_list()
|
||||
require("memos.ui").show_memos_list()
|
||||
end
|
||||
|
||||
return M
|
||||
251
lua/memos/ui.lua
Normal file
251
lua/memos/ui.lua
Normal file
@@ -0,0 +1,251 @@
|
||||
local api = require('memos.api')
|
||||
local config = require('memos').config
|
||||
|
||||
local M = {}
|
||||
|
||||
-- 存放状态的变量
|
||||
local memos_cache = {}
|
||||
local buf_id = nil
|
||||
local current_page_token = nil
|
||||
local current_user = nil
|
||||
local current_filter = nil
|
||||
|
||||
-- ===================================================================
|
||||
-- 首先定义所有会被其他函数调用的 local "辅助" 函数
|
||||
-- ===================================================================
|
||||
|
||||
-- 渲染 Memos 列表到 buffer
|
||||
local function render_memos(data, append)
|
||||
vim.schedule(function()
|
||||
if not buf_id or not vim.api.nvim_buf_is_valid(buf_id) then return end
|
||||
local new_memos = data.memos or {}
|
||||
current_page_token = data.nextPageToken or ""
|
||||
if append then
|
||||
memos_cache = vim.list_extend(memos_cache, new_memos)
|
||||
else
|
||||
memos_cache = new_memos
|
||||
end
|
||||
local lines = {}
|
||||
local k = config.keymaps.list
|
||||
if #memos_cache == 0 then
|
||||
local help = string.format("No memos found. Press '%s' to refresh, '%s' to add, or '%s' to quit.",
|
||||
k.refresh_list, k.add_memo, k.quit)
|
||||
table.insert(lines, help)
|
||||
else
|
||||
for i, memo in ipairs(memos_cache) do
|
||||
local first_line = memo.content:match("^[^\n]*")
|
||||
local display_time = memo.displayTime:sub(1, 10)
|
||||
table.insert(lines, string.format("%d. [%s] %s", i, display_time, first_line))
|
||||
end
|
||||
end
|
||||
if current_page_token ~= "" then
|
||||
table.insert(lines, "...")
|
||||
table.insert(lines, string.format("(Press '%s' to load more)", k.next_page))
|
||||
end
|
||||
vim.api.nvim_buf_set_option(buf_id, 'modifiable', true)
|
||||
vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines)
|
||||
vim.api.nvim_buf_set_option(buf_id, 'modifiable', false)
|
||||
end)
|
||||
end
|
||||
|
||||
-- 设置编辑 buffer 的通用函数
|
||||
local function setup_buffer_for_editing()
|
||||
vim.bo.buftype = 'nofile'
|
||||
vim.bo.bufhidden = 'wipe'
|
||||
vim.bo.swapfile = false
|
||||
vim.bo.buflisted = true
|
||||
|
||||
vim.bo.filetype = 'markdown'
|
||||
|
||||
local save_key_string = ""
|
||||
if config.keymaps.buffer.save and config.keymaps.buffer.save ~= "" then
|
||||
save_key_string = string.format(" or %s", config.keymaps.buffer.save)
|
||||
end
|
||||
|
||||
if vim.b.memos_memo_name then
|
||||
vim.notify("Editing memo. Use :MemosSave" .. save_key_string .. " to save.")
|
||||
else
|
||||
vim.notify("📝 New memo. Use :MemosSave" .. save_key_string .. " to create.")
|
||||
end
|
||||
|
||||
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
|
||||
vim.api.nvim_buf_set_keymap(0, 'n', config.keymaps.buffer.save, '<Cmd>MemosSave<CR>', { noremap = true, silent = true })
|
||||
end
|
||||
end
|
||||
|
||||
-- 打开一个已存在的 Memo
|
||||
local function open_memo_for_edit(memo, open_cmd)
|
||||
vim.cmd(open_cmd)
|
||||
local first_line = memo.content:match("^[^\n]*")
|
||||
local buffer_name = "memos/" .. memo.name:gsub("memos/", "") .. "/" .. first_line:gsub("[/\\]", "_"):sub(1, 50) .. ".md"
|
||||
|
||||
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.b.memos_memo_name = memo.name
|
||||
setup_buffer_for_editing()
|
||||
end
|
||||
|
||||
-- ===================================================================
|
||||
-- 然后定义所有对外暴露的 M.xxx 函数,确保它们能访问到上面的 local 函数
|
||||
-- ===================================================================
|
||||
|
||||
-- 【修正】将此函数移到 render_memos 定义之后,解决报错
|
||||
function M.refresh_list_silently()
|
||||
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)
|
||||
render_memos(data, false)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.save_or_create_dispatcher()
|
||||
local memo_name = vim.b.memos_memo_name
|
||||
local content = table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n')
|
||||
|
||||
if content == '' then
|
||||
vim.notify("Memo is empty, not sending.", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
if memo_name then
|
||||
api.update_memo(memo_name, content, function(success)
|
||||
if success then
|
||||
vim.schedule(function() vim.notify("✅ Memo updated successfully!") end)
|
||||
M.refresh_list_silently()
|
||||
end
|
||||
end)
|
||||
else
|
||||
api.create_memo(content, function(new_memo)
|
||||
if new_memo and new_memo.name then
|
||||
vim.schedule(function()
|
||||
vim.notify("✅ Memo created successfully!")
|
||||
vim.cmd('bdelete!') -- 强制关闭临时的 new_memo buffer
|
||||
open_memo_for_edit(new_memo, 'enew') -- 用新 memo 的信息打开一个标准的编辑窗口
|
||||
M.refresh_list_silently()
|
||||
end)
|
||||
else
|
||||
vim.schedule(function() vim.notify("❌ Failed to create memo.", vim.log.levels.ERROR) end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function M.create_memo_in_buffer()
|
||||
vim.cmd('enew')
|
||||
vim.b.memos_memo_name = nil
|
||||
vim.api.nvim_buf_set_name(0, "memos/new_memo.md")
|
||||
setup_buffer_for_editing()
|
||||
end
|
||||
|
||||
function M.show_memos_list(filter)
|
||||
current_filter = filter
|
||||
local should_create_buf = true
|
||||
if buf_id and vim.api.nvim_buf_is_valid(buf_id) then
|
||||
should_create_buf = false
|
||||
else
|
||||
buf_id = vim.api.nvim_create_buf(true, true) -- listed = true, scratch = true
|
||||
vim.api.nvim_buf_set_name(buf_id, " Memos")
|
||||
vim.bo[buf_id].buftype = 'nofile'
|
||||
vim.bo[buf_id].swapfile = false
|
||||
vim.bo[buf_id].filetype = 'memos_list'
|
||||
vim.bo[buf_id].modifiable = false
|
||||
end
|
||||
|
||||
-- 【修正】确保跳转到列表窗口,并且是在当前窗口打开
|
||||
local win_id = vim.fn.bufwinid(buf_id)
|
||||
if win_id ~= -1 then
|
||||
vim.api.nvim_set_current_win(win_id)
|
||||
else
|
||||
vim.api.nvim_set_current_buf(buf_id)
|
||||
end
|
||||
|
||||
vim.schedule(function() vim.notify("Getting user info...") end)
|
||||
api.get_current_user(function(user)
|
||||
if user and user.name then
|
||||
current_user = user
|
||||
vim.schedule(function() vim.notify("Fetching memos for " .. user.name .. "...") end)
|
||||
api.list_memos(user.name, current_filter, config.pageSize, nil, function(data)
|
||||
render_memos(data, false)
|
||||
end)
|
||||
else
|
||||
vim.schedule(function() vim.notify("Could not get user, aborting fetch.", vim.log.levels.ERROR) end)
|
||||
end
|
||||
end)
|
||||
|
||||
local function set_keymap(key, command)
|
||||
if key and key ~= "" then
|
||||
vim.api.nvim_buf_set_keymap(buf_id, 'n', key, command, { noremap = true, silent = true })
|
||||
end
|
||||
end
|
||||
|
||||
if config.keymaps and config.keymaps.list then
|
||||
local list_keymaps = config.keymaps.list
|
||||
set_keymap(list_keymaps.edit_memo, '<Cmd>lua require("memos.ui").edit_selected_memo()<CR>')
|
||||
set_keymap(list_keymaps.vsplit_edit_memo, '<Cmd>lua require("memos.ui").edit_selected_memo_in_vsplit()<CR>')
|
||||
set_keymap(list_keymaps.quit, '<Cmd>bdelete!<CR>')
|
||||
set_keymap(list_keymaps.search_memos, '<Cmd>lua require("memos.ui").search_memos()<CR>')
|
||||
set_keymap(list_keymaps.refresh_list, '<Cmd>lua require("memos.ui").show_memos_list()<CR>')
|
||||
set_keymap(list_keymaps.next_page, '<Cmd>lua require("memos.ui").load_next_page()<CR>')
|
||||
set_keymap(list_keymaps.add_memo, '<Cmd>lua require("memos.ui").create_memo_in_buffer()<CR>')
|
||||
set_keymap(list_keymaps.delete_memo, '<Cmd>lua require("memos.ui").confirm_delete_memo()<CR>')
|
||||
set_keymap(list_keymaps.delete_memo_visual, '<Cmd>lua require("memos.ui").confirm_delete_memo()<CR>')
|
||||
end
|
||||
end
|
||||
|
||||
function M.load_next_page()
|
||||
if not current_page_token or current_page_token == "" then
|
||||
vim.notify("No more pages to load.", vim.log.levels.INFO)
|
||||
return
|
||||
end
|
||||
if not current_user or not current_user.name then
|
||||
vim.notify("User info not available.", vim.log.levels.WARN)
|
||||
return
|
||||
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)
|
||||
render_memos(data, true)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.edit_selected_memo()
|
||||
local line_num = vim.api.nvim_win_get_cursor(0)[1]
|
||||
local selected_memo = memos_cache[line_num]
|
||||
if selected_memo then
|
||||
open_memo_for_edit(selected_memo, 'enew')
|
||||
end
|
||||
end
|
||||
|
||||
function M.edit_selected_memo_in_vsplit()
|
||||
local line_num = vim.api.nvim_win_get_cursor(0)[1]
|
||||
local selected_memo = memos_cache[line_num]
|
||||
if selected_memo then
|
||||
open_memo_for_edit(selected_memo, 'vsplit | enew')
|
||||
end
|
||||
end
|
||||
|
||||
function M.confirm_delete_memo()
|
||||
local line_num = vim.api.nvim_win_get_cursor(0)[1]
|
||||
local selected_memo = memos_cache[line_num]
|
||||
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)
|
||||
if choice == 1 then
|
||||
api.delete_memo(selected_memo.name, function(success)
|
||||
if success then
|
||||
vim.schedule(function()
|
||||
vim.notify("✅ Memo deleted.")
|
||||
M.show_memos_list(current_filter)
|
||||
end)
|
||||
else
|
||||
vim.schedule(function() vim.notify("❌ Failed to delete memo.", vim.log.levels.ERROR) end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function M.search_memos()
|
||||
vim.ui.input({ prompt = "Search Memos: " }, function(input)
|
||||
M.show_memos_list(input or "")
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
23
plugin/memos.lua
Normal file
23
plugin/memos.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
-- 创建新 Memo 的命令
|
||||
vim.api.nvim_create_user_command(
|
||||
'MemosCreate',
|
||||
function()
|
||||
require('memos').create_memo()
|
||||
end,
|
||||
{
|
||||
nargs = 0,
|
||||
desc = "Create a new Memos entry"
|
||||
}
|
||||
)
|
||||
|
||||
-- 【新增】查看 Memos 列表的命令
|
||||
vim.api.nvim_create_user_command(
|
||||
'Memos',
|
||||
function()
|
||||
require('memos').show_list()
|
||||
end,
|
||||
{
|
||||
nargs = 0,
|
||||
desc = "List and search your Memos"
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user