HakonHarnes / img-clip.nvim

Effortlessly embed images into any markup language, like LaTeX, Markdown or Typst
MIT License
499 stars 8 forks source link

$FILE_PATH does not match the setting of relative_to_current_file #21

Closed MasouShizuka closed 10 months ago

MasouShizuka commented 10 months ago

Setting:

dir_path = function()
    return "_images_" .. vim.fn.expand("%:t:r")
end,
file_name = "%Y-%m-%d-%H-%M-%S", -- file name format (see lua.org/pil/22.1.html)
relative_to_current_file = true, -- make dir_path relative to current file rather than the cwd
prompt_for_file_name = false,    -- ask user for file name before saving, leave empty to use default
use_cursor_in_template = true,   -- jump to cursor position in template after pasting
insert_mode_after_paste = false, -- enter insert mode after pasting the markup code

Before PasteImage: image

After PasteImage: image

The location where the image is stored is correct, but the location in () does not match the setting of relative_to_current_file. Shouldn't it be ![](_images_test/2024-01-03-19-48-45.png)?

This shows that $FILE_PATH in template does not comply with the relative_to_current_file setting. Maybe some placeholders should be added, such as FILE_PATH_RELATIVE, or template can be assigned to a function like dir_path.

HakonHarnes commented 10 months ago

Does fix/relative-to-current-file-markdown resolve the issue? If you're using Lazy, just set the branch option accordingly and pull the latest changes.

MasouShizuka commented 10 months ago

Setting:

dir_path = function()
    return "_images_" .. vim.fn.expand("%:t:r")
    -- return vim.fn.expand("%:.:h") .. "/_images_" .. vim.fn.expand("%:t:r")
end,
relative_to_current_file = true,  -- make dir_path relative to current file rather than the cwd

After PasteImage: image The result is correct.

Setting:

dir_path = function()
    -- return "_images_" .. vim.fn.expand("%:t:r")
    return vim.fn.expand("%:.:h") .. "/_images_" .. vim.fn.expand("%:t:r")
end,
relative_to_current_file = false,  -- make dir_path relative to current file rather than the cwd

After PasteImage: image The result is wrong with /.

MasouShizuka commented 10 months ago

Strange result with setting:

dir_path = function()
    return "_images_" .. vim.fn.expand("%:t:r")
    -- return vim.fn.expand("%:.:h") .. "/_images_" .. vim.fn.expand("%:t:r")
end,
relative_to_current_file = true,  -- make dir_path relative to current file rather than the cwd

image

Just replace folder temp with VS-Boost: Boosting Visual-Semantic Association for Generalized Zero-Shot Learning.

HakonHarnes commented 10 months ago

The issue is that there is no built in path manipulation in Lua, and the ones provided through the Neovim API seem to only work relative to the current working directory, not the currently opened file. I will have to look into this, but it seems like I'll have to re-implement something like python's relpath in Lua. I'll look into it this week.

For now you can switch back to the main branch and set use_absolute_path = true as a temporary workaround while I look into the issue.

HakonHarnes commented 10 months ago

@MasouShizuka I implemented a more robust solution. Does it work as expected now? Branch is still fix/relative-to-current-file-markdown

HakonHarnes commented 10 months ago

Strange result with setting

That's expected. The path needs to be URL-encoded in markdown, so spaces get replaced with %20. Not sure why the first space is not handled correctly, though. Probably due to the colon.

Edit: I am not able to reproduce the missing %20.

MasouShizuka commented 10 months ago

When I open a new markdown file, the result is correct: image

But when I read the session into a markdown file, for example using neovim-session-manager, it gives strange result: image

By the way, regarding the previous result of VS-Boost: Boosting Visual-Semantic Association for Generalized Zero-Shot Learning, I don’t mean that space is encoded as %20, and the colon is in Chinese:, this is a character and does not contain spaces. After all, the path cannot contain English colons. I mean the result should be _images-test1/2024-01-04-10-04-00.png, not VS-Boost:Boosting%20Visual-Semantic%20Association%20for%20Generalized%20Zero- Shot%20Learning/_images-test1/2024-01-04-10-04-00.png

MasouShizuka commented 10 months ago

By the way, I looked at the code a little bit, and I have a simple question: Why only use file relative paths for the markdown type, but not other file types? Do other file types need to use project relative paths to be valid? For example, the file is project/folder1/file1, the inserted image location is project/folder1/img/image1.jpg, and the relative reference in file1 becomes folder1/img/image1.jpg. In my understanding, shouldn't the references in the file be relative to the current file, that is, img/image1.jpg? This is just a question of mine, I'm not sure about the reference situation of other file types.

If this is the case, I think that in the case of use_absolute_path = false, a placeholder $FILE_RELATIVE_PATH needs to be added, that is, $FILE_PATH corresponds to folder1/img/image1.jpg, and $FILE_RELATIVE_PATH corresponds to img/image1.jpg.

In addition, according to the way the code is written, use_absolute_path seems to be ignored.

HakonHarnes commented 10 months ago

But when I read the session into a markdown file, for example using neovim-session-manager, it gives strange result:

Does neovim-session-manager alter the current working directory or something?

By the way, regarding the previous result of VS-Boost: Boosting Visual-Semantic Association for Generalized Zero-Shot Learning, I don’t mean that space is encoded as %20, and the colon is : in Chinese:, this is a character and does not contain spaces. After all, the path cannot contain English colons.

Thanks for claryfing.

I mean the result should be _images-test1/2024-01-04-10-04-00.png, not VS-Boost:Boosting%20Visual-Semantic%20Association%20for%20Generalized%20Zero- Shot%20Learning/_images-test1/2024-01-04-10-04-00.png

Yes, and that works now, right?

In my understanding, shouldn't the references in the file be relative to the current file, that is, img/image1.jpg?

No, not in LaTeX, at least when compiling locally. pdflatex excepts the figure paths to be relative to the main file, even in subfiles.

In addition, according to the way the code is written, use_absolute_path seems to be ignored.

You're right, I'll fix it!

MasouShizuka commented 10 months ago

I don't know, but when I changed to dfendr/clipboard-image.nvim there was no such problem. The plugin’s settings are:

default = {
     img_dir = function()
         return vim.fn.expand("%:.:h") .. "/_images_" .. vim.fn.expand("%:t:r")
     end,
     img_dir_txt = function()
         return "_images_" .. vim.fn.expand("%:t:r")
     end,
     img_name = function()
         return os.date("%Y-%m-%d-%H-%M-%S")
     end,
     img_handler = function(img) end,
     affix = "%s",
},
asciidoc = {
     affix = "image::%s[]",
},
markdown = {
     affix = "![](%s)",
},

The following is the corresponding session file:

let SessionLoad = 1
let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1
let v:this_session=expand("<sfile>:p")
let NvimTreeSetup =  1 
let NvimTreeRequired =  1 
silent only
silent tabonly
cd D:/Projects/python/hello
if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''
  let s:wipebuf = bufnr('%')
endif
let s:shortmess_save = &shortmess
if &shortmess =~ 'A'
  set shortmess=aoOA
else
  set shortmess=aoO
endif
badd +1 D:/Projects/python/hello/child\ folder/test.md
argglobal
%argdel
edit D:/Projects/python/hello/child\ folder/test.md
argglobal
balt main.py
let s:cpo_save=&cpo
set cpo&vim
inoremap <buffer> <silent> <Plug>MarkdownPreviewToggle :MarkdownPreviewToggle
inoremap <buffer> <silent> <Plug>MarkdownPreviewStop :MarkdownPreviewStop
a
inoremap <buffer> <silent> <Plug>MarkdownPreview :MarkdownPreview
a
nnoremap <buffer> <silent>  ltÞ <Nop>
nnoremap <buffer> <silent>  lÞ <Nop>
xnoremap <buffer> <silent> [[ :exe "normal! gv"|call search('\%(^#\{1,5\}\s\+\S\|^\S.*\n^[=-]\+$\)', "bsW")
nnoremap <buffer> <silent> [[ :call search('\%(^#\{1,5\}\s\+\S\|^\S.*\n^[=-]\+$\)', "bsW")
xnoremap <buffer> <silent> ]] :exe "normal! gv"|call search('\%(^#\{1,5\}\s\+\S\|^\S.*\n^[=-]\+$\)', "sW")
nnoremap <buffer> <silent> ]] :call search('\%(^#\{1,5\}\s\+\S\|^\S.*\n^[=-]\+$\)', "sW")
xnoremap <buffer> <silent> ac <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@class.outer','textobjects','x')
onoremap <buffer> <silent> ac <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@class.outer','textobjects','o')
xnoremap <buffer> <silent> ak <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@block.outer','textobjects','x')
onoremap <buffer> <silent> ak <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@block.outer','textobjects','o')
xnoremap <buffer> <silent> ik <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@block.inner','textobjects','x')
onoremap <buffer> <silent> ik <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@block.inner','textobjects','o')
xnoremap <buffer> <silent> ic <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@class.inner','textobjects','x')
onoremap <buffer> <silent> ic <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@class.inner','textobjects','o')
nnoremap <buffer> <silent> sXÞ <Nop>
nnoremap <buffer> <silent> <Plug>MarkdownPreviewToggle :MarkdownPreviewToggle
noremap <buffer> <silent> <Plug>MarkdownPreviewStop :MarkdownPreviewStop
noremap <buffer> <silent> <Plug>MarkdownPreview :MarkdownPreview
let &cpo=s:cpo_save
unlet s:cpo_save
setlocal keymap=
setlocal noarabic
setlocal autoindent
setlocal backupcopy=
setlocal nobinary
setlocal breakindent
setlocal breakindentopt=
setlocal bufhidden=
setlocal buflisted
setlocal buftype=
setlocal nocindent
setlocal cinkeys=0{,0},0),0],:,0#,!^F,o,O,e
setlocal cinoptions=
setlocal cinscopedecls=public,protected,private
setlocal cinwords=if,else,while,do,for,switch
setlocal colorcolumn=
setlocal comments=fb:*,fb:-,fb:+,n:>
setlocal commentstring=<!--%s-->
setlocal complete=.,w,b,u,t
setlocal completefunc=
setlocal completeslash=
setlocal concealcursor=
setlocal conceallevel=0
setlocal nocopyindent
setlocal nocursorbind
setlocal nocursorcolumn
setlocal cursorline
setlocal cursorlineopt=both
setlocal define=
setlocal dictionary=
setlocal nodiff
setlocal equalprg=
setlocal errorformat=
setlocal expandtab
if &filetype != 'markdown'
setlocal filetype=markdown
endif
setlocal fillchars=eob:\ ,fold:\ ,foldclose:,foldopen:,foldsep:\ 
setlocal fixendofline
setlocal foldcolumn=1
setlocal foldenable
setlocal foldexpr=0
setlocal foldignore=#
setlocal foldlevel=99
setlocal foldmarker={{{,}}}
setlocal foldmethod=manual
setlocal foldminlines=1
setlocal foldnestmax=20
setlocal foldtext=v:lua.require'ufo.main'.foldtext()
setlocal formatexpr=
setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\|^\\s*[-*+]\\s\\+\\|^\\[^\\ze[^\\]]\\+\\]:\\&^.\\{4\\}
setlocal formatoptions=j1tcqln
setlocal formatprg=
setlocal grepprg=
setlocal iminsert=0
setlocal imsearch=-1
setlocal include=
setlocal includeexpr=
setlocal indentexpr=nvim_treesitter#indent()
setlocal indentkeys=0{,0},0),0],:,0#,!^F,o,O,e
setlocal infercase
setlocal iskeyword=@,48-57,_,192-255,-
setlocal keywordprg=
setlocal linebreak
setlocal nolisp
setlocal lispoptions=
setlocal lispwords=
setlocal list
setlocal listchars=
setlocal makeencoding=
setlocal makeprg=
setlocal matchpairs=(:),{:},[:],<:>
setlocal modeline
setlocal modifiable
setlocal nrformats=bin,hex
setlocal number
setlocal numberwidth=4
setlocal omnifunc=v:lua.vim.lsp.omnifunc
setlocal path=
setlocal nopreserveindent
setlocal nopreviewwindow
setlocal quoteescape=\\
setlocal noreadonly
setlocal relativenumber
setlocal norightleft
setlocal rightleftcmd=search
setlocal scrollback=-1
setlocal noscrollbind
setlocal scrolloff=-1
setlocal shiftwidth=4
setlocal showbreak=
setlocal sidescrolloff=-1
setlocal signcolumn=yes
setlocal smartindent
setlocal nosmoothscroll
setlocal softtabstop=4
setlocal spell
setlocal spellcapcheck=[.?!]\\_[\\])'\"\\t\ ]\\+
setlocal spellfile=
setlocal spelllang=en,cjk
setlocal spelloptions=noplainbuffer
setlocal statuscolumn=%{%v:lua.require'heirline'.eval_statuscolumn()%}
setlocal statusline=
setlocal suffixesadd=
setlocal noswapfile
setlocal synmaxcol=3000
if &syntax != ''
setlocal syntax=
endif
setlocal tabstop=4
setlocal tagcase=
setlocal tagfunc=v:lua.vim.lsp.tagfunc
setlocal tags=
setlocal textwidth=0
setlocal thesaurus=
setlocal thesaurusfunc=
setlocal noundofile
setlocal undolevels=-123456
setlocal varsofttabstop=
setlocal vartabstop=
setlocal virtualedit=
setlocal winbar=%{%v:lua.require'heirline'.eval_winbar()%}
setlocal winblend=0
setlocal nowinfixheight
setlocal nowinfixwidth
setlocal winhighlight=
setlocal wrap
setlocal wrapmargin=0
silent! normal! zE
1,1fold
let &fdl = &fdl
let s:l = 1 - ((0 * winheight(0) + 23) / 47)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 1
normal! 0
tabnext 1
if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
  silent exe 'bwipe ' . s:wipebuf
endif
unlet! s:wipebuf
set winheight=1 winwidth=20
let &shortmess = s:shortmess_save
let s:sx = expand("<sfile>:p:r")."x.vim"
if filereadable(s:sx)
  exe "source " . fnameescape(s:sx)
endif
let &g:so = s:so_save | let &g:siso = s:siso_save
set hlsearch
doautoall SessionLoadPost
unlet SessionLoad
" vim: set ft=vim :
HakonHarnes commented 10 months ago

What is the output of:

:lua print(vim.fn.expand("%:p:h"))
:lua print(vim.fn.getcwd()) 

When you:

  1. Open the project folder like "normal".
  2. Use neovim-session-manager.

I was not able to reproduce the issue when manually using :mksession and restoring using :source /path/to/session.vim.

MasouShizuka commented 10 months ago
  1. Without neovim-session-manager: image image
  2. With neovim-session-manager: image image
HakonHarnes commented 10 months ago

vim.fn.expand("%:p:h") differs. The path separators are different. Are you on Windows or Linux?

MasouShizuka commented 10 months ago

I'm on Windows 11.

HakonHarnes commented 10 months ago

I don't know, but when I changed to dfendr/clipboard-image.nvim there was no such problem. The plugin’s settings are:

Yes, it's handled via the img_dir_txt. But I don't see how you would be able to have nested files that all refer to one project folder in this setup. e.g. ../assets/image.png or ../../assets/image.png.

HakonHarnes commented 10 months ago

The output of

:lua print(package.config:sub(1, 1)) 

is "\", correct?

MasouShizuka commented 10 months ago

lua print(package.config:sub(1, 1))

image

HakonHarnes commented 10 months ago

Do you have the same issue if you manually invoke :mksession and source it, rather than using neovim-session-manager?

MasouShizuka commented 10 months ago

Yes, I manually :source the result of this session: image

HakonHarnes commented 10 months ago

Can you see if the latest changes fixes the issue?

MasouShizuka commented 10 months ago

Yes, after a rough test, it should be correct.

However, I would still like this feature could be set rather than hard-coded based on the file type, for example if I want to use a project-relative path in markdown.

HakonHarnes commented 10 months ago

However, I would still like this feature could be set rather than hard-coded based on the file type, for example if I want to use a project-relative path in markdown.

Implemented as relative_template_path option. Is everything working as intended now?

MasouShizuka commented 10 months ago

Ok, maybe that's enough for now, although I couldn't test other file types.

In fact, I think the template can also be set as a function, which can be completely based on the user's needs. The user can add functions by himself. Of course, he can also use those placeholders in the returned string. For example markdown:

template = function()
    return "![$CURSOR]($FILE_PATH)"
end

or

template = function()
    return "![$CURSOR](" .. "_images_" .. vim.fn.expand("%:t:r") .. "/" .. os.date("%Y-%m-%d-%H-%M-%S") .. ".png)"
end
HakonHarnes commented 10 months ago

In fact, I think the template can also be set as a function, which can be completely based on the user's needs.

You're right. In fact, any option can be dynamically generated through functions.