-
Notifications
You must be signed in to change notification settings - Fork 12
/
init.lua
174 lines (157 loc) · 4.95 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
local M = {}
local api = vim.api
local util = require "lspconfig.util"
local tools = require 'quarto.tools'
local otter = require 'otter'
local otterkeeper = require'otter.keeper'
M.defaultConfig = {
debug = false,
closePreviewOnExit = true,
lspFeatures = {
enabled = true,
languages = { 'r', 'python', 'julia', 'bash' },
chunks = 'curly', -- 'curly' or 'all'
diagnostics = {
enabled = true,
triggers = { "BufWritePost" }
},
completion = {
enabled = true,
},
},
keymap = {
hover = 'K',
definition = 'gd'
}
}
function M.quartoPreview()
-- find root directory / check if it is a project
local buffer_path = api.nvim_buf_get_name(0)
local root_dir = util.root_pattern("_quarto.yml")(buffer_path)
local cmd
local mode
if root_dir then
mode = "project"
cmd = 'quarto preview'
else
mode = "file"
cmd = 'quarto preview \'' .. buffer_path .. '\''
end
local quarto_extensions = { ".qmd", ".Rmd", ".ipynb", ".md" }
local file_extension = buffer_path:match("^.+(%..+)$")
if mode == "file" and not file_extension then
vim.notify("Not in a file. exiting.")
return
end
if mode == "file" and not tools.contains(quarto_extensions, file_extension) then
vim.notify("Not a quarto file, ends in " .. file_extension .. " exiting.")
return
end
-- run command in embedded terminal
-- in a new tab and go back to the buffer
vim.cmd('tabedit term://' .. cmd)
local quartoOutputBuf = vim.api.nvim_get_current_buf()
vim.cmd('tabprevious')
api.nvim_buf_set_var(0, 'quartoOutputBuf', quartoOutputBuf)
-- close preview terminal on exit of the quarto buffer
if M.config.closePreviewOnExit then
api.nvim_create_autocmd({ "QuitPre", "WinClosed" }, {
buffer = api.nvim_get_current_buf(),
group = api.nvim_create_augroup("quartoPreview", {}),
callback = function(_, _)
if api.nvim_buf_is_loaded(quartoOutputBuf) then
api.nvim_buf_delete(quartoOutputBuf, { force = true })
end
end
})
end
end
function M.quartoClosePreview()
local success, quartoOutputBuf = pcall(api.nvim_buf_get_var, 0, 'quartoOutputBuf')
if not success then return end
if api.nvim_buf_is_loaded(quartoOutputBuf) then
api.nvim_buf_delete(quartoOutputBuf, { force = true })
end
end
M.enableDiagnostics = function()
local main_nr = api.nvim_get_current_buf()
api.nvim_create_autocmd(M.config.lspFeatures.diagnostics.triggers, {
buffer = main_nr,
group = api.nvim_create_augroup("quartoLSPDiagnositcs", { clear = false }),
callback = function(_, _)
local bufnrs = otterkeeper._otters_attached[main_nr].buffers
otterkeeper.sync_raft(main_nr)
for lang, bufnr in pairs(bufnrs) do
local diag = vim.diagnostic.get(bufnr)
local ns = api.nvim_create_namespace('quarto-lang-' .. lang)
vim.diagnostic.reset(ns, main_nr)
vim.diagnostic.set(ns, main_nr, diag, {})
end
end
})
end
M.quartoHover = otter.ask_hover
M.quartoDefinition = otter.ask_definition
M.searchHelp = function(cmd_input)
local topic = cmd_input.args
local url = 'https://quarto.org/?q=' .. topic .. '&show-results=1'
local sysname = vim.loop.os_uname().sysname
local cmd
if sysname == "Linux" then
cmd = 'xdg-open "' .. url .. '"'
elseif sysname == "Darwin" then
cmd = 'open "' .. url .. '"'
else
print('sorry, I do not know how to make windows open a url with the default browser. This feature currently only works on linux and mac.')
return
end
vim.fn.jobstart(cmd)
end
M.activate = function()
local tsqueries = nil
if M.config.lspFeatures.chunks == 'all' then
tsqueries = {
quarto = [[
(fenced_code_block
(info_string
(language) @lang
)
(code_fence_content) @code (#offset! @code)
)]],
}
elseif M.config.lspFeatures.chunks == 'curly' then
tsqueries = {
quarto = [[
(fenced_code_block
(info_string
(language) @lang
) @info
(#match? @info "{")
(code_fence_content) @code (#offset! @code)
)]],
}
end
otter.activate(M.config.lspFeatures.languages, M.config.lspFeatures.completion.enabled, tsqueries)
end
-- setup
M.setup = function(opt)
M.config = vim.tbl_deep_extend('force', M.defaultConfig, opt or {})
api.nvim_create_autocmd({ "BufReadPost" }, {
pattern = { "*.qmd" },
group = vim.api.nvim_create_augroup('QuartoSetup', {}),
desc = 'set up quarto',
callback = function()
if M.config.lspFeatures.enabled and vim.bo.buftype ~= 'terminal' then
M.activate()
vim.api.nvim_buf_set_keymap(0, 'n', M.config.keymap.definition, ":lua require'quarto'.quartoDefinition()<cr>",
{ silent = true })
vim.api.nvim_buf_set_keymap(0, 'n', M.config.keymap.hover, ":lua require'quarto'.quartoHover()<cr>",
{ silent = true })
if M.config.lspFeatures.diagnostics.enabled then
M.enableDiagnostics()
end
end
end,
})
end
return M