Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WikiJournal : could not parse journal url #252

Closed
bybor opened this issue Oct 26, 2022 · 17 comments
Closed

WikiJournal : could not parse journal url #252

bybor opened this issue Oct 26, 2022 · 17 comments

Comments

@bybor
Copy link

bybor commented Oct 26, 2022

Description

NOTE: it was introduced with e7ccd5e and is present in every commit that followed.

This issue started happening after today's update, but I didn't update wiki.vim for months.

Neovim, Windows

  1. run Neovim
  2. Type WikiJournal
  3. Expected: open today's file
  4. Actual: text as below
wiki: could not parse journal url!
  URL:       2022-10-26
  Date:      2022-10-26
  Anchor: 

It's even more interesting in gVim (Windows) where it suggests looking for new app in Application Store after I do :WikiJournal<CR>

My settings

let g:wiki_cache_root = '.cache'
let g:wiki_filetypes = ['adoc', 'asciidoc', 'wiki', 'md', 'markdown']
let g:wiki_write_on_nav = 1
let g:wiki_root = '~\vimfiles\vimwiki'
let g:wiki_date_exe = 'wikidate.exe'
let g:wiki_journal = {
    \ 'name': 'diary',
    \ 'frequency': 'daily',
    \ 'date_format': {
    \   'daily' : '%Y-%m-%d',
    \   'weekly' : '%Y_w%V',
    \   'monthly' : '%Y_m%m',
    \ },
    \}
let g:wiki_mappings_use_defaults = 'global'

let g:wiki_link_extension = '.adoc'

let g:wiki_resolver = 'WikiResolver'

I use a custom wiki resolver as you may see above, but I don't think it is called in this particular case.

@lervag
Copy link
Owner

lervag commented Oct 26, 2022

I think it is, actually. Journal urls are converted to wiki links.

You no longer need g:wiki_date_exe, by the way. I figured out how to do all the date parsing within Vim.

I'll look into this when I get the time, as soon as possible. I've made major changes to the journal backend, which is why the error occurs in the first place.

@lervag
Copy link
Owner

lervag commented Oct 26, 2022

My settings: ...

Here's a suggested update to your settings with some comments/questions:

" Is there a reason you don't want to put the cache in a central place?
let g:wiki_cache_root = '.cache'
let g:wiki_filetypes = ['adoc', 'asciidoc', 'wiki', 'md', 'markdown']
let g:wiki_write_on_nav = 1
let g:wiki_root = '~\vimfiles\vimwiki'
" You don't need to specify keys unless you change them from default values
let g:wiki_journal = {'name': 'diary'}
let g:wiki_mappings_use_defaults = 'global'
let g:wiki_link_extension = '.adoc'
let g:wiki_resolver = 'WikiResolver'

Basically, I removed g:wiki_date_exe and adjusted g:wiki_journal.

I use a custom wiki resolver as you may see above, but I don't think it is called in this particular case.

I think it may be relevant to see the definition of WikiResolver.

@lervag
Copy link
Owner

lervag commented Oct 26, 2022

With the following minimal example I have no issue:

test.vim

set nocompatible
set runtimepath^=~/.local/plugged/wiki.vim
filetype plugin indent on
syntax enable

nnoremap q :qall!<cr>

let g:wiki_cache_root = fnamemodify('cache', ':p')
let g:wiki_filetypes = ['adoc', 'asciidoc', 'wiki', 'md', 'markdown']
let g:wiki_write_on_nav = 1
let g:wiki_root = fnamemodify('wiki', ':p')
let g:wiki_journal = { 'name': 'diary' }
let g:wiki_link_extension = '.adoc'

Contents of test directory:

$ tree
.
├── cache/
│   └── capture.json
├── test.vim
└── wiki/
    ├── diary/
    └── index.adoc

3 directories, 3 files

index.adoc is empty. I run nvim --clean -u test.vim, then do \w\w (or :WikiJournal) and I reach the expected destination, as can be seen in this screenshot:

image

@bybor
Copy link
Author

bybor commented Oct 27, 2022

Thank you very much for taking time and providing a mnimal example.

I can reproduce the issue on my end with it, so it's not related to wiki resolver that i've been using.

With Vim it tries to launch something along the lines: cmd /c (rundll32 url.dll, FileProtocolHandler ^"journal:2022-10-27")

With nvim it just outputs the same message as before.

Could you tell where I can put some test (echom) messages to figure it out? I know that you don't have Windows.

Thanks again

@lervag
Copy link
Owner

lervag commented Oct 27, 2022

Thank you very much for taking time and providing a mnimal example.

No problem :)

With Vim it tries to launch something along the lines: cmd /c (rundll32 url.dll, FileProtocolHandler ^"journal:2022-10-27")

I still believe this is somehow related to your WikiResolver. But perhaps I'm wrong.

Could you tell where I can put some test (echom) messages to figure it out? I know that you don't have Windows.

Yes. Ok, so:

  1. Can you ensure you have the latest version, just in case?
  2. You can use unsilent echom ... to check the value of l:date, l:path and l:frq after this line:
    let [l:path, l:frq] = wiki#journal#date_to_node(l:date)
  3. Now, it would be useful to understand where in wiki#journal#date_to_node it returns and why. Again, unsilent echom and possibly :message afterwards could help figure this out. E.g., add unsilent echom l:frq after this line:
    \}, strlen(l:date), '')

At least, that's somewhere to start.

@bybor
Copy link
Author

bybor commented Oct 28, 2022

I still believe this is somehow related to your WikiResolver

I tested it with your minimal example as soon as I had it, so that we have the common ground - we can rule out my custom resolver at least for now.

I followed your instructions and echom-ed almost every variable that was there right after it was assigned. I also added logging in another method - the one that returned timestamp as 0. I wasn't sure if it was OK

image

@lervag
Copy link
Owner

lervag commented Oct 28, 2022

Ok, so it seems the problem is in this function:

function! wiki#date#strptime(format, timestring) abort " {{{1
let l:dd = wiki#date#parse_format(a:timestring, a:format)
if !has_key(l:dd, 'year') | return 0 | endif
if has_key(l:dd, 'week_iso')
return s:strptime_weekly(l:dd.year, l:dd.week_iso)
endif
if !has_key(l:dd, 'month') | return 0 | endif
return strptime('%F',
\ printf('%s-%s-%s', l:dd.year, l:dd.month, get(l:dd, 'day', 1)))
endfunction
" }}}1

Could you echo the various variables there? I think perhaps it is the last line that is problematic, i.e. strptime('%F', ...). Can you change %F into %Y-%m-%d and see if that changes anything?

@bybor
Copy link
Author

bybor commented Oct 28, 2022

Changing %F to %Y-%m-%d doesn't help.

These two lines

let l:timestamp = wiki#date#strptime(s:date_format[l:frq], l:date)
let l:node = l:timestamp > 0
      \ ? strftime(get(g:wiki_journal.date_format, l:frq), l:timestamp)
      \ : ''

The current code returns 0 as seen on the screenshot. I hard-coded l:node to 2022-10-28 and it opened the file.

The documentation tells that strptime() is not portable, but I couldn't find what to use in place.

You probably use strptime to confirm that you have a valid date string. But could we use strftime without that validation?

NOTE: it looks like strptime on Windows may return an empty string b/c it is generally not implemented. strftime is.

vim/vim#6573

@lervag
Copy link
Owner

lervag commented Oct 28, 2022

Changing %F to %Y-%m-%d doesn't help.

Ah, that's annoying.

The documentation tells that strptime() is not portable, but I couldn't find what to use in place.

You probably use strptime to confirm that you have a valid date string. But could we use strftime without that validation?

I was aware that strptime was not portable, but I was not aware it was not at least partly portable. The function converts a date/time in string format into a timestamp (an integer). I think the problem is that, on your side - Windows, it just returns 0 no matter what.

Can you provide some more details:

  • Which Windows version?
  • Which Vim version (or neovim)?
  • What does :echo exists('*strptime') output?
  • What does :echo strptime('%Y', '2022') output?

@bybor
Copy link
Author

bybor commented Oct 28, 2022

  • Windows 10
  • Vim 9.0
    • echo exists('*strptime'): 0
    • echo exists('strptime'): 0
    • echo strptime('%Y', '2022') : Unknown function
  • Neovim 0.7.4
    • echo exists('*strptime'): 1
    • echo exists('strptime'): 0
    • echo strptime('%Y', '2022') : 0

@lervag
Copy link
Owner

lervag commented Oct 28, 2022

Ok, thanks. So, I'll see if I can find an alternative. In the meantime, you may want to revert to the previous version that worked for you. Sorry about the inconvenience!

@lervag
Copy link
Owner

lervag commented Oct 28, 2022

Can we go the other way around? That is, does this work: :echo strftime('%Y-%m-%d %H:%M:%S', 1666562400)? What does it output?

lervag added a commit that referenced this issue Oct 28, 2022
@lervag
Copy link
Owner

lervag commented Oct 28, 2022

I've implemented a solution that I think may work - under the assumption that strftime works as expected also on Windows. Please update and test.

@lervag lervag closed this as completed Oct 28, 2022
@lervag
Copy link
Owner

lervag commented Oct 28, 2022

By the way, I'm quite happy with the implementation:

function! wiki#date#strptime#isodate_implicit(date_target) abort " {{{1
if a:date_target !~# '^\d\d\d\d-\d\d-\d\d$'
call wiki#log#error('Argument error: ' . a:date_target)
return 0
endif
let l:year = a:date_target[:3]
let l:month = a:date_target[5:6]
let l:day = a:date_target[8:]
" Add hour for target to get more precise results
let l:date_target = a:date_target . '-00'
let l:count = 0
let l:current = 1666562400
while l:count < 100
let l:count += 1
let l:date = strftime('%F-%H', l:current)
if l:date ==# l:date_target | return l:current | endif
let l:current += 31536000*(l:year - l:date[:3])
let l:current += 2592000*(l:month - l:date[5:6])
let l:current += 86400*(l:day - l:date[8:9])
let l:current += 3600*l:date[10:]
endwhile
return 0
endfunction
" }}}1

It uses strftime to calculate the strptime for an isodate implicitly.

@bybor
Copy link
Author

bybor commented Oct 28, 2022

I've implemented a solution that I think may work - under the assumption that strftime works as expected also on Windows. Please update and test.

It does, thanks a lot!

@lervag
Copy link
Owner

lervag commented Oct 28, 2022

Glad to hear it! :)

@bybor
Copy link
Author

bybor commented Oct 29, 2022

I got the same issue with strptime in Termux, I will re-open a new github issue for that.

Thanks!

Edit by lervag: reference #253.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants