Closed ttdduu closed 1 year ago
Hi :)
Apologize, I clicked enter and sent the issue!
Anyway, I have a feature request: If I have page_1
and page_2
, and page_2
has a #section1#section1.1
to which I want to link from page_1
, I think it would be nice to see some kind of symbol in #section1.1
, so I can see that it has been linked elsewhere (and I can see the backlink with wiki-graph-find-backlinks
). For example, having #section1.1
in italics.
That's it! And thank you for all you do. I've been using your plugins basically every day for a long time now.
That's an interesting proposal. I believe it is possible to do this by use of some recent/advanced features e.g. in Neovim. Not sure if it is possible in Vim - perhaps it is. I will need to think about it.
But, to be clear, the proposal or idea is generally to make it clear that a specific header has an incoming link, right?
Perhaps it would be OK to put this indication as a sign in the sign column? Or as virtual text?
Also, I hope you don't mind that I took the liberty of reformatting your updated feature request - it makes it easier for me to fully grasp the intent.
That's it! And thank you for all you do. I've been using your plugins basically every day for a long time now.
<3
But, to be clear, the proposal or idea is generally to make it clear that a specific header has an incoming link, right?
Exactly! Because i may be missing the importance of this header while i parse through the page it is in, as i suggest below.
Perhaps it would be OK to put this indication as a sign in the sign column? Or as virtual text?
I hadn't thought about these options, but either one would look much better than italicizing the header. As an additional feature, maybe this sign could be the actual number of backlinks the section has, since that alone would give a sense of "how important" it is in the wiki. I could then opt to go look for it with wiki-graph-find-backlinks
.
Also, I hope you don't mind that I took the liberty of reformatting your updated feature request - it makes it easier for me to fully grasp the intent.
Of course! Sorry i didn't pay much attention to formatting. I hadn't opened an issue in a long time; i think it shows by the mess i made at the beginning :)
I've pushed some updates that make it easy to add this feature. Right now, you can enable it on your own like this:
augroup MyWikiAutocmds
autocmd!
autocmd User WikiBufferInitialized call ShowIncoming()
augroup END
function! ShowIncoming() abort
call sign_define("wiki-incoming", {
\ 'text': '',
\ 'texthl': 'DiagnosticSignInfo',
\})
let l:id = nvim_create_namespace("wiki.vim")
let l:links_enriched = filter(
\ wiki#graph#get_backlinks_enriched(),
\ 'v:val.target_lnum > 0'
\)
for [l:lnum, l:links] in items(wiki#u#group_by(l:links_enriched, 'target_lnum'))
call sign_place(0, "wiki", "wiki-incoming", "", #{ lnum: l:lnum })
let l:text = len(l:links) > 1
\ ? printf(" incoming (%d links)", len(l:links))
\ : printf(" incoming (from %s)", l:links[0].filename_from)
call nvim_buf_set_extmark(0, l:id, l:lnum - 1, 0, {
\ 'virt_text': [[l:text, "DiagnosticVirtualTextHint"]]
\})
endfor
endfunction
I need to figure out how to implement this in a nice, robust manner with the right amount of user flexibility. It's not fully clear to me yet.
Notice, though, that wiki#graph#get_backlinks_enriched
uses a caching mechanism that is not smart. To get a list of incoming links, we really need to parse all pages in the wiki. This particular step is also cached, but for a large wiki (like mine), the feature will lead to noticable lags.
Great! I pasted this code in my vimrc. I'm afraid the current comment may be unclear or messy. If it is, i could try a different way of illustrating the behaviour i have seen.
Notice, though, that wiki#graph#get_backlinks_enriched uses a caching mechanism that is not smart.
Expected behaviour:
Have the links cache updated such that, every time vimrc is loaded, links that have been removed are not shown in the virtualtext, and links that have been added are shown.
Observed behaviour:
The virtualtext on a header on page1
that has been linked to from page2
and page3
only shows the link from one of the multiple pages. Let's say it is page2
. The virtualtext reads incoming (from page2)
. I think that not showing page3
isn't a big deal, since i would still see it has been linked to from somewhere.
However, the cache is indeed not updated, as shown in any of these scenarios:
A. Deleting the link [[page1#section1]]
in page2
and restarting my vim session. After that, the virtualtext in page1
reads the same: incoming (from page2)
. I would have expected incoming (from page3)
, since would still be showing only one of the multiple filepaths.
B. Doing same as in A, plus removing the code i pasted on my vimrc. Still see incoming (from page2)
.
C. Creating a new link [[page1#section1]]
in a page4
since the first install of wiki.vim: i still get incoming (from page2)
.
D. The same as in C, plus reinstalling wiki.vim.
In addition, calling ShowIncoming() inside the vim session on page1
appends the same virtual text to the existing one.
I hope i was clear enough!
Expected behaviour:
Have the links cache updated such that, every time vimrc is loaded, links that have been removed are not shown in the virtualtext, and links that have been added are shown.
Observed behaviour:
The virtualtext on a header on
page1
that has been linked to frompage2
andpage3
only shows the link from one of the multiple pages. Let's say it ispage2
. The virtualtext readsincoming (from page2)
. I think that not showingpage3
isn't a big deal, since i would still see it has been linked to from somewhere.
This is precisely what I meant about the cache not being smart. And I agree, we need a way to handle this that makes sense.
Currently, you can refresh the cache manually by doing :WikiClearCache links-in
.
The reason I can't be very smart about this is that the cache for incoming links takes quite long to refresh. So we really don't want to refresh it often.
A. Deleting the link
[[page1#section1]]
inpage2
and restarting my vim session. After that, the virtualtext inpage1
reads the same:incoming (from page2)
. I would have expectedincoming (from page3)
, since would still be showing only one of the multiple filepaths.B. Doing same as in A, plus removing the code i pasted on my vimrc. Still see
incoming (from page2)
.C. Creating a new link
[[page1#section1]]
in apage4
since the first install of wiki.vim: i still getincoming (from page2)
.D. The same as in C, plus reinstalling wiki.vim.
Yes, this is currently expected behaviour for the reasons given.
In addition, calling ShowIncoming() inside the vim session on
page1
appends the same virtual text to the existing one.
Yes, the current function is a proof of concept and does not properly handle things. This is work in progress! :)
There are two main tasks here, IMHO:
Considering that the solution I've provided already works, I think the best thing to do first is to look into 1. If I can find a good way to do the cache, then perhaps the resulting feature will be fast enough to be "always active". Also, it could be useful with a statusline indicator that shows the number of incoming links total (including links that are not "anchored").
I've now updated the caching mechanism: There's now a fast cache update process that more or less solves my mentioned problem. However, it is still quite slow to update the cache for large wikis. E.g., in my own wiki the cache files are about 8 MB each and just the process of reading and writing these files takes 0.2 seconds. And even the fast cache method needs to write the cache. I've therefore added a threshold for the fast cache update as well, which is currently at 30 seconds.
If you update and use the same code as before, you should notice that the signs and virtual texts are updated - but only if you wait 30 seconds.
Here's an updated function that 1) disables the fast cache delay (with the nudge option) and 2) clears the existing signs and virtual texts:
function! ShowIncoming() abort
call sign_define("wiki-incoming", {
\ 'text': '',
\ 'texthl': 'DiagnosticSignInfo',
\})
call sign_unplace("wiki.vim")
let l:id = nvim_create_namespace("wiki.vim")
call nvim_buf_clear_namespace(0, l:id, 0, -1)
let l:toc = wiki#u#associate_by(wiki#toc#gather_entries(), 'anchor')
let l:graph = wiki#graph#builder#get()
let l:links_enriched = l:graph.get_links_to(expand('%:p'), #{nudge: v:true})
for l:link in l:links_enriched
let l:section = get(l:toc, remove(l:link, 'anchor'), {})
let l:link.target_lnum = get(l:section, 'lnum', 0)
endfor
call filter(l:links_enriched, 'v:val.target_lnum > 0')
for [l:lnum, l:links] in items(wiki#u#group_by(l:links_enriched, 'target_lnum'))
call sign_place(0, "wiki.vim", "wiki-incoming", "", #{ lnum: l:lnum })
let l:text = len(l:links) > 1
\ ? printf(" incoming (%d links)", len(l:links))
\ : printf(" incoming (from %s)", l:links[0].filename_from)
call nvim_buf_set_extmark(0, l:id, l:lnum - 1, 0, {
\ 'virt_text': [[l:text, "DiagnosticVirtualTextHint"]]
\})
endfor
endfunction
Let me know what you think so far.
I've pushed the above function as an API function: wiki#buffer#refresh_incoming_links
. Thus, with the following you would get something semi useful without much personal config:
augroup MyWikiAutocmds
autocmd!
autocmd User WikiBufferInitialized call wiki#buffer#refresh_incoming_links()
augroup END
There is still quite a lot of work to make this more robust and fine tuned and to make it auto update as needed.
I believe, though, that this should not be added as a "standard" feature except behind a command or a mapping. That is, I believe we want to add a command/mapping that refreshes the "incoming links view" with proper documentation. I also want to document the function API and to show how to make it automatic by use of autocommands.
I've made more update snow. I've added two commands and mappings:
WikiLinkIncomingToggle
(mapped to <leader>wli
by default)
WikiLinkIncomingHover
(mapped to <leader>wlI
by default)
I think this ended up being quite good. You can still activate the display similar to before, but now you must use this (because I renamed the function):
augroup MyWikiAutocmds
autocmd!
autocmd User WikiBufferInitialized call wiki#link#incoming_display()
augroup END
It remains to add some documentation.
Hi! Feature request: make headers that have been backlinked in another page italic (maybe for wiki-ft instead of wiki.vim).