I have a ftplugin called markdown.lua and I want to create a mapping that jumps to existing files or create those who does not exist yet, something like this:
vim.keymap.set('n', '<cr>', function()
status_ok, _ = pcall(vim.cmd, "normal gf")
if not status_ok then
print('create command')
end
end,
{ buffer = true, desc = "markdown.lua: open file under the cursor" }
)
The missing part is when the file does not exist, I would like:
1 - Get the word under the cursor and apply lua string.gsub(filename, '(.*)', '[%1](%1.md)')
2 - change the word under the cursor
3 - create the missing file
The final result is: Jump to the file using <CR>
or create the file, change the name and allow me to jump to the file using <CR>
The string.gsub part will transform
word --> [word](word.md)
The idea comes from here: vimscript - How can I get vim to include suffixes in <cfile>? - Vi and Vim Stack Exchange
I came up with a vimscript part but I would like to get opinions and possible a lua version of that:
vim.keymap.set('n', '<cr>', function()
status_ok, _ = pcall(vim.cmd, "normal gf")
if not status_ok then
vim.cmd[[
let dest = expand("<cfile>")
let flink = '[' . dest . '](' . dest . '.md)'
execute "normal ciw".flink
execute 'normal :e ' . dest . '.md' . "\r"
]]
end
end,
{ buffer = true, desc = "markdown.lua: open file under the cursor" }
)
Any other solution, without using a plugin will be well come, we will evaluate what can bring us a better and concise solution.
Here the problem was the '\r'
literal, It needs to be in double quotes. It is working as expected, I only need to convert the vim.cmd to lua and at the moment I don’t know how achieve that.
Here is how I would write it in Lua:
vim.keymap.set('n', '<cr>', function()
local status_ok, _ = pcall(vim.cmd, "normal gf")
if not status_ok then
local dest = vim.fn.expand('<cword>')
local flink = '['..dest..']('..dest..'.md)'
vim.fn.feedkeys('ciw'..flink,'x')
vim.cmd('edit '..dest..'.md')
end
end,
{ buffer = true, desc = "markdown.lua: open file under the cursor" }
)
1 Like
I only had to add vim.cmd('w')
because if the file is not written to the disc the gf
command does not work and then the feedkeys command will change the name each time I press Enter (considering I jump to the file, then jump back and then press Enter once more).
Maybe If I could check if the <cWORD>
is any kind of markdown link: [file](file.md)
we could skip that feedkeys part…
I have added a test, just to check if the word under the cursor <cWORD>
has ]
which means it seems to be a markdown link. So if the file does not exist but already has a markdown link format it will not run the feedkeys
line:
vim.keymap.set('n', '<cr>', function()
local status_ok, _ = pcall(vim.cmd, "normal gf")
if not status_ok then
local dest = vim.fn.expand('<cword>')
if string.match(dest, "%a") then
local flink = '['..dest..']('..dest..'.md)'
local current_word = vim.fn.expand("<cWORD>")
if string.match(current_word,'[[]') then
print("We already have a link here!")
else
print("Creating a link for: ", current_word)
vim.fn.feedkeys('ciw'..flink,'x')
end
vim.cmd('edit '..dest..'.md')
end
end
end,
{ buffer = true, desc = "markdown.lua: open file under the cursor" }
)
if dest
is nill, which means we are not over a word, do nothing