Skip to content

Commit 178c72d

Browse files
committed
feat: add setup function with improved documentation
Add a proper setup function to initialize the plugin. The setup function creates necessary autocommands and validates API key. Type annotations were updated to improve developer experience: - @Class and @field annotations for Article, Author, FeedArticle - @param and @return annotations for all functions - Changed vim.fn.json_decode to vim.json.decode
1 parent a4c7e8a commit 178c72d

File tree

8 files changed

+239
-75
lines changed

8 files changed

+239
-75
lines changed

lua/devto-nvim/api.lua

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,28 @@ local M = {}
22
local notify = require("devto-nvim.notify")
33
local article = require("devto-nvim.article")
44

5+
--- Get the API key from the environment
6+
--- @return string? The API key, or nil if it is not set
57
function M.key()
68
return vim.env.DEVTO_API_KEY
79
end
810

11+
--- The base URL for the API
912
local BASE_URL = "https://dev.to/api"
1013

1114
---@class Response
1215
---@field status number
1316
---@field body table
1417

18+
---@class CurlOptions
19+
---@field headers table<string, string>?
20+
---@field body table?
21+
1522
---@alias Method "GET" | "POST" | "PUT" | "DELETE"
1623

24+
--- Handle an error response
25+
--- If the response is successful, the `on_success` callback will be called with the response body
26+
--- If the response is an error, the error will be displayed to the user
1727
---@param response Response
1828
---@param on_success fun(body: table)
1929
function M.handle_error(response, on_success)
@@ -33,6 +43,7 @@ function M.handle_error(response, on_success)
3343
end
3444
end
3545

46+
--- Convert a `vim.SystemCompleted` object to a `Response` object
3647
---@param out vim.SystemCompleted
3748
---@return Response
3849
local function system_completed_to_response(out)
@@ -51,7 +62,7 @@ local function system_completed_to_response(out)
5162
-- Only attempt to decode if we have a body
5263
if response_body and response_body ~= "" then
5364
-- Protect against JSON decode errors
54-
body = vim.fn.json_decode(response_body)
65+
body = vim.json.decode(response_body)
5566
end
5667

5768
return {
@@ -60,14 +71,15 @@ local function system_completed_to_response(out)
6071
}
6172
end
6273

63-
---@param method Method
64-
---@param endpoint string
65-
---@param options table
66-
---@param on_exit fun(response: Response)?
74+
--- Make a curl request
75+
---@param method Method The HTTP method to use
76+
---@param endpoint string The endpoint to hit
77+
---@param options CurlOptions Options to pass to curl
78+
---@param on_exit fun(response: Response)? A callback to run when the request is complete, if not provided the request will be synchronous
6779
---@return vim.SystemObj
6880
local function curl(method, endpoint, options, on_exit)
6981
local headers = options.headers or {}
70-
local request_body = options.body and { "-d", vim.fn.json_encode(options.body) } or {}
82+
local request_body = options.body and { "-d", vim.json.encode(options.body) } or {}
7183

7284
local cmd = vim.iter({
7385
"curl",
@@ -91,11 +103,13 @@ local function curl(method, endpoint, options, on_exit)
91103
end)
92104
end
93105

94-
---@param method Method
95-
---@param endpoint string
96-
---@param options table
106+
--- Make a synchronous request to the API
107+
---@param method Method The HTTP method to use
108+
---@param endpoint string The endpoint to hit
109+
---@param options CurlOptions Options to pass to curl
97110
---@return Response
98111
local function request(method, endpoint, options)
112+
---@type CurlOptions
99113
local parameters = vim.tbl_extend(
100114
"force",
101115
{
@@ -114,10 +128,12 @@ local function request(method, endpoint, options)
114128
return response
115129
end
116130

117-
---@param method Method
118-
---@param endpoint string
119-
---@param on_success fun(body: table)
131+
--- Make an asynchronous request to the API
132+
---@param method Method The HTTP method to use
133+
---@param endpoint string The endpoint to hit
134+
---@param on_success fun(body: table) A callback to run when the request is successful
120135
local function request_async(method, endpoint, on_success)
136+
---@type CurlOptions
121137
local options = {
122138
headers = {
123139
"Api-Key: " .. M.key()
@@ -133,8 +149,9 @@ local function request_async(method, endpoint, on_success)
133149
)
134150
end
135151

136-
---@param endpoint string
137-
---@param on_success fun(body: table)
152+
--- Make a asynchronous GET request to the API
153+
---@param endpoint string The endpoint to hit
154+
---@param on_success fun(body: table) A callback to run when the request is successful
138155
local function get(endpoint, on_success)
139156
request_async(
140157
"GET",
@@ -143,27 +160,33 @@ local function get(endpoint, on_success)
143160
)
144161
end
145162

146-
---@param endpoint string
147-
---@param body table
163+
--- Make a synchronous PUT request to the API
164+
---@param endpoint string The endpoint to hit
165+
---@param body table The body of the request
148166
---@return Response
149167
local function put(endpoint, body)
150168
return request("PUT", endpoint, { body = body })
151169
end
152170

153-
---@param endpoint string
154-
---@param body table
171+
--- Make a synchronous POST request to the API
172+
---@param endpoint string The endpoint to hit
173+
---@param body table The body of the request
155174
---@return Response
156175
local function post(endpoint, body)
157176
return request("POST", endpoint, { body = body })
158177
end
159178

160-
---@param on_success fun(body: table)
179+
--- Fetch all articles for the current user
180+
--- The request is asynchronous
181+
---@param on_success fun(body: table) A callback to run when the request is successful
161182
function M.my_articles(on_success)
162183
return get("/articles/me/all", on_success)
163184
end
164185

165-
---@param id number
166-
---@param content string
186+
--- Save an article
187+
--- The request is synchronous
188+
---@param id number The ID of the article to save
189+
---@param content string The new content of the article
167190
---@return Response
168191
function M.save_article(id, content)
169192
return put(
@@ -172,7 +195,9 @@ function M.save_article(id, content)
172195
)
173196
end
174197

175-
---@param title string
198+
--- Create a new article
199+
--- The request is synchronous
200+
---@param title string The title of the new article
176201
---@return Response
177202
function M.new_article(title)
178203
return post(
@@ -181,22 +206,28 @@ function M.new_article(title)
181206
)
182207
end
183208

184-
---@param on_success fun(body: table)
209+
--- Fetch the feed of articles of the current user
210+
--- The request is asynchronous
211+
---@param on_success fun(body: FeedArticle[]) A callback to run when the request is successful
185212
function M.feed(on_success)
186213
get("/articles", on_success)
187214
end
188215

189-
---@param id number
190-
---@param on_success fun(body: table)
216+
--- Fetch an article by ID
217+
--- The request is asynchronous
218+
---@param id number The ID of the article to fetch
219+
---@param on_success fun(body: table) A callback to run when the request is successful
191220
function M.get_article(id, on_success)
192221
get(
193222
"/articles/" .. tostring(id),
194223
on_success
195224
)
196225
end
197226

198-
---@param path string
199-
---@param on_success fun(body: table)
227+
--- Fetch an article by path
228+
--- The request is asynchronous
229+
---@param path string The path of the article to fetch
230+
---@param on_success fun(body: table) A callback to run when the request is successful
200231
function M.get_article_by_path(path, on_success)
201232
get("/articles/" .. path, on_success)
202233
end

lua/devto-nvim/article.lua

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,39 @@
1-
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
21
local M = {}
32

4-
-- TODO: Create class for Article
3+
---@class Article
4+
---@field id number
5+
---@field type_of string
6+
---@field title string
7+
---@field slug string
8+
---@field description string
9+
---@field url string
10+
---@field body_markdown string?
11+
---@field user Author
12+
---@field reading_time_minutes number
13+
---@field tags string[]
14+
---@field positive_reactions_count number
15+
---@field comments_count number
16+
---@field readable_publish_date string
17+
---@field published_at string?
518

19+
---@class Author
20+
---@field name string
21+
---@field username string
22+
23+
--- Get the lines of the body of an article
24+
--- @param article Article
25+
--- @return string[]
626
function M.get_body_lines(article)
727
return vim.split(article.body_markdown or "", "\n")
828
end
929

30+
--- Get the template for a new article
31+
--- @param title string The title of the new article
32+
--- @return string
1033
function M.get_template(title)
11-
return ("---\ntitle: " .. title) ..
12-
"\npublished: false\ndescription:\ntags:\n# cover_image: https://direct_url_to_image.jpg\n# Use a ratio of 100:42 for best results.\n---\n\n"
34+
return string.format(
35+
"---\ntitle: %s\npublished: false\ndescription:\ntags:\n# cover_image: https://direct_url_to_image.jpg\n# Use a ratio of 100:42 for best results.\n---\n\n",
36+
title)
1337
end
1438

1539
return M

lua/devto-nvim/buffer.lua

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ local Article = require("devto-nvim.article")
33
local util = require("devto-nvim.util")
44
local set_locals = util.set_locals
55

6-
M.set_basic_options = function()
6+
--- Set the basic options for a markdown buffer
7+
function M.set_basic_options()
78
set_locals({
89
filetype = "markdown",
910
modified = false
1011
})
1112
end
1213

13-
M.write = function(buffer, lines, offset)
14+
--- Write lines to a buffer
15+
--- @param buffer number The buffer to write to
16+
--- @param lines string[] The lines to write
17+
function M.write(buffer, lines, offset)
1418
local modifiable = vim.opt_local.modifiable:get()
1519
vim.opt_local.modifiable = true
1620
vim.api.nvim_buf_set_lines(
@@ -23,7 +27,9 @@ M.write = function(buffer, lines, offset)
2327
vim.opt_local.modifiable = modifiable
2428
end
2529

26-
M.get_content = function()
30+
--- Get the content of the current buffer
31+
--- @return {content: string, bufnr: number}
32+
function M.get_content()
2733
local buffer = vim.api.nvim_get_current_buf()
2834
local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1, true)
2935
return {
@@ -32,7 +38,9 @@ M.get_content = function()
3238
}
3339
end
3440

35-
M.open_my_article = function(article)
41+
--- Open an article of the current user in a buffer by its ID
42+
--- @param article Article The article to open
43+
function M.open_my_article(article)
3644
vim.cmd(":edit devto://my-article/" .. tostring(article.id))
3745
local buffer = vim.api.nvim_get_current_buf()
3846
M.write(
@@ -43,7 +51,9 @@ M.open_my_article = function(article)
4351
set_locals({ buftype = "acwrite", swapfile = false })
4452
end
4553

46-
M.load_article = function(article)
54+
--- Open an article in a buffer by its title
55+
--- @param article Article The article to open
56+
function M.load_article(article)
4757
vim.cmd(":edit devto://article/" .. article.title)
4858
set_locals({ linebreak = true, textwidth = 80 })
4959
local buffer = vim.api.nvim_get_current_buf()

0 commit comments

Comments
 (0)