Skip to content

Commit 4aba4e2

Browse files
committed
feat: create from selection
1 parent b81152b commit 4aba4e2

File tree

4 files changed

+101
-68
lines changed

4 files changed

+101
-68
lines changed

lua/gist/core/gh.lua

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
local utils = require("gist.core.utils")
12
local M = {}
23

34
--- Creates a Github gist with the specified filename and description
@@ -10,36 +11,37 @@ local M = {}
1011
-- @return number|nil The error of the command
1112
function M.create_gist(filename, content, description, private)
1213
local public_flag = private and "" or "--public"
13-
local escaped_description = vim.fn.shellescape(description)
14-
15-
local cmd = string.format(
16-
"gh gist create %s %s --filename %s -d %s",
17-
vim.fn.expand("%"),
18-
public_flag,
19-
filename,
20-
escaped_description
21-
)
22-
23-
local handle = io.popen(cmd)
24-
25-
-- null check on handle
26-
if handle == nil then
27-
return nil
14+
description = vim.fn.shellescape(description)
15+
16+
local cmd
17+
18+
if content ~= nil then
19+
filename = vim.fn.shellescape(filename)
20+
cmd = string.format("gh gist create -f %s -d %s %s", filename, description, public_flag)
21+
else
22+
-- expand filepath if no content is provided
23+
cmd = string.format(
24+
"gh gist create %s %s --filename %s -d %s",
25+
vim.fn.expand("%"),
26+
public_flag,
27+
filename,
28+
description
29+
)
2830
end
2931

30-
local output = handle:read("*a")
31-
handle:close()
32+
local output = utils.exec(cmd, content)
3233

3334
if vim.v.shell_error ~= 0 then
3435
return output, vim.v.shell_error
3536
end
3637

37-
local url = string.gsub(output, "\n", "")
38+
local url = utils.extract_gist_url(output)
3839

3940
return url, nil
4041
end
4142

4243
--- Reads the configuration from the user's vimrc
44+
--
4345
-- @return table A table with the configuration properties
4446
function M.read_config()
4547
local ok, values = pcall(vim.api.nvim_get_var, { "gist_is_private", "gist_clipboard" })

lua/gist/core/utils.lua

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,82 @@
11
local M = {}
22

3-
function M.get_selection()
4-
local start_line, start_col = unpack(vim.fn.getpos("'<")[2])
5-
local end_line, end_col = unpack(vim.fn.getpos("'>")[2])
6-
7-
-- selection is empty
8-
if start_line == end_line and start_col == end_col then
9-
return nil
3+
local function is_visual()
4+
if vim.fn.mode() ~= "v" and vim.fn.mode() ~= "V" and vim.fn.mode() ~= "<C-V>" then
5+
return false
106
end
117

12-
-- selection is not empty
8+
return true
9+
end
10+
11+
function M.get_current_selection(start_line, end_line)
1312
local bufnr = vim.api.nvim_get_current_buf()
1413

15-
start_line = start_line - 1 -- convert to 0-based line number
16-
end_line = end_line - 1 -- convert to 0-based line number
14+
start_line = start_line - 1 -- Convert to 0-based line number
15+
end_line = end_line - 1 -- Convert to 0-based line number
1716

18-
local lines = vim.api.nvim_buf_get_lines(bufnr, start_line, end_line, false)
17+
local lines = vim.api.nvim_buf_get_lines(bufnr, start_line, end_line + 1, false)
1918

2019
return table.concat(lines, "\n")
2120
end
2221

22+
function M.get_last_selection()
23+
local bufnr = vim.api.nvim_get_current_buf()
24+
25+
-- Save the current cursor position
26+
local saved_cursor = vim.api.nvim_win_get_cursor(0)
27+
28+
-- Get the start and end positions of the visual selection
29+
vim.cmd("normal! gv")
30+
local start_pos = vim.fn.getpos("'<")
31+
local end_pos = vim.fn.getpos("'>")
32+
33+
-- Restore the cursor position
34+
vim.api.nvim_win_set_cursor(0, saved_cursor)
35+
36+
local start_line = start_pos[2] - 1
37+
local end_line = end_pos[2]
38+
local content_lines = vim.api.nvim_buf_get_lines(bufnr, start_line, end_line, false)
39+
local content = table.concat(content_lines, "\n")
40+
41+
return content
42+
end
43+
44+
local function read_file(path)
45+
local file = io.open(path, "rb") -- r read mode and b binary mode
46+
if not file then
47+
return nil
48+
end
49+
local content = file:read("*a") -- *a or *all reads the whole file
50+
file:close()
51+
return content
52+
end
53+
54+
function M.exec(cmd, stdin)
55+
print(string.format("Executing: %s", cmd))
56+
local tmp = os.tmpname()
57+
58+
local pipe = io.popen(cmd .. "> " .. tmp, "w")
59+
60+
if not pipe then
61+
return nil
62+
end
63+
64+
if stdin then
65+
pipe:write(stdin)
66+
end
67+
68+
pipe:close()
69+
70+
local output = read_file(tmp)
71+
os.remove(tmp)
72+
73+
return output
74+
end
75+
76+
function M.extract_gist_url(output)
77+
local pattern = "https://gist.github.com/%S+"
78+
79+
return output:match(pattern)
80+
end
81+
2382
return M

lua/gist/init.lua

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
1+
local utils = require("gist.core.utils")
12
local core = require("gist.core.gh")
23

34
local M = {}
45

5-
function M.create_from_file(args)
6+
function M.create(start_line, end_line)
67
local config = core.read_config()
8+
local content = nil
79

8-
local filename = vim.fn.expand("%:t")
9-
local description = ""
10-
11-
if args[1] ~= nil then
12-
description = args[1]
13-
end
14-
15-
if description == "" or description == nil then
16-
vim.api.nvim_echo({
17-
{ "No description provided" },
18-
}, true, {})
19-
20-
description = vim.fn.input("Description: ")
10+
if start_line ~= end_line then
11+
content = utils.get_current_selection(start_line, end_line)
2112
end
2213

14+
local filename = vim.fn.expand("%:t")
15+
local description = vim.fn.input("Gist description: ")
2316
local is_private = config.is_private or vim.fn.input("Create a private Gist? (y/n): ") == "y"
2417

25-
local url, err = core.create_gist(filename, nil, description, is_private)
18+
local url, err = core.create_gist(filename, content, description, is_private)
2619

2720
if err ~= nil then
2821
vim.api.nvim_err_writeln("Error creating Gist: " .. err)
@@ -32,10 +25,4 @@ function M.create_from_file(args)
3225
end
3326
end
3427

35-
function M.create_from_selection(opts)
36-
vim.api.nvim_echo({
37-
{ "Creating Gist from selection..." .. opts.args, "Identifier" },
38-
}, true, {})
39-
end
40-
4128
return M

plugin/gist.lua

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
local gist = require("gist")
2-
3-
vim.api.nvim_create_user_command("Rawnly", function(args)
4-
vim.api.nvim_echo({
5-
{ "Args: " .. table.concat(args, " "), "Identifier" },
6-
}, true, {})
7-
end, {
8-
nargs = "*",
9-
})
10-
11-
vim.api.nvim_create_user_command("CreateFileGist", gist.create_from_file, {
12-
desc = "Create a new gist from current file",
13-
nargs = "*",
14-
})
15-
16-
vim.api.nvim_create_user_command("CreateGist", gist.create_from_selection, {
17-
desc = "Create a new gist from current selection",
18-
})
1+
vim.cmd([[
2+
command! -range CreateGist :lua require("gist").create(<line1>, <line2>)
3+
]])

0 commit comments

Comments
 (0)