Giter Site home page Giter Site logo

crossbow's Introduction

🏹 Crossbow

image

Crossbow is a plugin for Obsidian.

Boost your Obsidian note-taking workflow with this plugin that offers handy suggestions for links to headings, tags, and files, helping you effortlessly weave a web of interconnected notes and supercharge your note graph.

How to use

Just open the crossbow sidebar by clicking on the crossbow icon in the ribbon. All the suggestions will appear within the sidebar.

Applying suggestions

Clicking on a suggestion in the sidebar will show you a list of occurrences of the word in the current note. Clicking on one of the occurences will scroll to it and show you a list of matched cache items that you can link to. These matches are ranked, based on the quality of the match.

You can apply a match by clicking the appropriate icon next to the match:

image

which will insert the following link:

image

In Obsidian a pipe (|) inside a link denotes the "display text" of the link. This means that the text after the pipe will be shown instead of the link.

Temporarily disabling suggestions

You can temporarily disable suggestions by righ-clicking the crossbow icon of the crossbow view and selecting "Close". This will close the sidebar and disable suggestions. To re-enable suggestions, just click the crossbow icon in the ribbon again.

Under the hood

What is a suggestion?

A suggestion is a word in your active editor (current note) that can be linked to a heading, a tag, or a file in your vault:

mindmap
  root((Suggestion))
    Word in your current note
    Obsidian Vault Cache Item
      Heading
      File
      Tag
Loading

Crossbow leverages Obsidian's internal cache and does not manually parse your vault. To find matches in your current note, it strips the active editors content of any markdown syntax and then searches for suggestion in the stripped content.

A word about how suggestions are matched

Crossbow is opinionated, but also configurable about how it creates suggestions. As of 1.1.1 the process of filtering looks like this:

Initially, it gathers all the words in the active editor (current note) and all the cache items (Identified by their cache key) in the vault. Then, it follows a simple process for each word and cache key to create a suggestion:

graph TD
    START((Start))
    Q_ACT_EDITOR["1. <b>Cache key</b> stems from active editor? <br>Configurable, see setting <i>Make suggestions to items in the same file</i>"]
    Q_EXCT_MATCH["2. Exact match (case sensitive) between <b>word</b> and <b>cache key</b>?"]
    Q_WORD_SHORT["3. <b>Word</b> is too short? (Currently fixed to 3 chars)"]
    Q_CKEY_SHORT["4. <b>Cache key</b> is too short? <br>Configurable, see setting <i>Minimum word length of suggestions</i>"]
    Q_IS_SUBSTRG["5. <b>Word</b> is a substring of <b>cache key</b> or vice versa?"]
    Q_WORD_UCASE["6. <b>Word</b> starts with an uppercase letter? <br>Configurable, see setting <i>Ignore occurrences which start with a lowercase letter</i>"]
    Q_CKEY_UCASE["7. <b>Cache key</b> starts with an uppercase letter? <br>Configurable, see setting <i>Ignore suggestions which start with a lowercase letter</i>"]
    Q_MATCH_INSV["8. Exact match (case insensitive) between <b>word</b> and <b>cache key</b>?"]
    Q_LEN_SIMILR["9. Similarity of less than 20% length-wise between <b>word</b> and <b>cache key</b>?"]

    STOP((STOP))

    SUCCESS_1["Add as very good suggestion (πŸ†)"]
    SUCCESS_2["Add as good suggestion (πŸ₯‡)"]
    SUCCESS_3["Add as mediocre suggestion (πŸ₯ˆ)"]
    SUCCESS_4["Add as 'not-very-good' suggestion (πŸ₯‰)"]


    START --> Q_ACT_EDITOR

    Q_ACT_EDITOR -- Yes --> STOP
    Q_ACT_EDITOR -- No --> Q_EXCT_MATCH

    Q_EXCT_MATCH -- Yes --> SUCCESS_1 --> STOP
    Q_EXCT_MATCH -- No --> Q_WORD_SHORT

    Q_WORD_SHORT -- Yes --> STOP
    Q_WORD_SHORT -- No --> Q_CKEY_SHORT

    Q_CKEY_SHORT -- Yes --> STOP
    Q_CKEY_SHORT -- No --> Q_IS_SUBSTRG

    Q_IS_SUBSTRG -- Yes --> STOP
    Q_IS_SUBSTRG -- No --> Q_WORD_UCASE

    Q_WORD_UCASE -- Yes --> STOP
    Q_WORD_UCASE -- No --> Q_CKEY_UCASE

    Q_CKEY_UCASE -- Yes --> STOP
    Q_CKEY_UCASE -- No --> Q_MATCH_INSV

    Q_MATCH_INSV -- Yes --> SUCCESS_2 --> STOP
    Q_MATCH_INSV -- No --> Q_LEN_SIMILR
    Q_LEN_SIMILR -- Yes --> SUCCESS_4 --> STOP
    Q_LEN_SIMILR -- No --> SUCCESS_3 --> STOP
Loading

Then, suggestions which match the ignored words are removed:

graph TD
    START((START))
    FE["For each result"]
    Q_WORD_IGNOR["Remove if <b>Word</b> is on ignore list (case sensitive) <br>Configurable, see setting <i>Ignored words</i>"]
    STOP((STOP))

    START --> FE
    FE --> Q_WORD_IGNOR
    Q_WORD_IGNOR --> FE
    Q_WORD_IGNOR --> STOP
Loading

Keep in mind that these steps are processed in order. For example, take a look at the length filter in step 9. At this point, the word and cache key are already a substring of each other (step 5), meaning that this step adds things like "donut" and "donut hole punching machine manual". Not things that are in general vastly different to each other, which would create a lot of false positives.

How to install manually

  1. Clone this repo.
  2. npm i or yarn to install dependencies
  3. npm run build to build crossbow.
  4. Copy main.js, styles.css, manifest.json into a folder called crossbow in your vault's .obsidian/plugins/ folder.

If you like this plugin, please consider:

crossbow's People

Contributors

shoedler avatar usernotnull avatar

Stargazers

patrick avatar  avatar Gary Blankenship avatar  avatar Breyden Taylor avatar Dylan Lucero avatar  avatar  avatar  avatar Yoanndp avatar DecafDev avatar Dameon Jensen avatar Kevin BrechbΓΌhl avatar a13ph avatar Adelino Monteiro avatar Andrew Mason avatar  avatar Bolutife Lawrence avatar  avatar Otto avatar Asseel Naji avatar David Gidwani avatar  avatar Zheng PiaoDan avatar  avatar Mike Keller avatar Maxime Deroullers avatar  avatar Quentin Dauprat avatar  avatar ACai avatar TheMattaBase avatar  avatar  avatar  avatar Dexin Qi avatar Anthony Glyadchenko avatar  avatar Ethan Harrison avatar Phillip J. Eby avatar Alex Haddad avatar  avatar Mohammed Makhlouf (Mak) avatar Matthew Conway avatar Jaspal Suri avatar  avatar

Watchers

 avatar  avatar

crossbow's Issues

Bug: Crossbow provides suggestions for Metadata

Hello again,

I noticed there are empty suggestions that are referring to the space before the metadata separators ( --- ).

grafik

I checked the suggested heading and it turned out that it has no text and only consists of the ( # ) symbol.

Disable the replacement of words when inserting the link into a page & jump to line number 😑😘

  1. I tested this out to see how it is, unfortunately when you try and insert a link, it completely replaces the word on the original document, with that link. I know many normally use Obsidian like that, but some of us do not. I wish there was a way to disable that functionality.

  2. Replacing the word is fine, I only ask this because I want to be able to insert more than one link. But it seems that after you insert one link, you lose the capability of inserting other links for that same word. For example if the word was apple, and you find 3 links for it, and you insert one link, the other links cross out and you can't click them to insert them 😞

  3. Another is when clicking on the drop downs in the right sidebar, it automatically goes to the line number!!! Please give the option to disable this function as well πŸ™ƒ

  4. Also having the ability to preview the source by holding command or control.

Solution:
Enable/Disable word replacement and jump to line number.

Additional context
I love you.

CR: Add Filename/Path in Suggestions

Is your feature request related to a problem? Please describe.

In the suggestions list, I see potential headings I could use. However it's frustrating to know where the heading is located, as I have to click on the "Go to Source" on each item to go to it.
My obsidian vault has more than a 1000 file, so with a list of 50 suggested names, each name suggestion links to files that may not even be relevant (see #20), it gets tiring.

Describe the solution you'd like

It's easier to skim through the suggestions if we can see the filename/path so that we quickly decide which suggestions to skip.

Bug: Suggestions Don't Include Aliases

Describe the bug
When suggesting files to link, aliases of a file are not included in the suggestions.

To Reproduce
Steps to reproduce the behavior:

  1. Create a new file with the name Horizon3
  2. Add alias: H3 in the YAML of the file.
  3. Create a new file and add a few lines of text. Have one line contain the word H3 with spaces on either side.

Expected behavior
Expect that H3 will be suggested as something to link to.

Actual behavior
No suggestion for the H3 page is shown.

Desktop (please complete the following information):

  • OS: Ubuntu 22.04
  • Plugin Version 1.3.0
  • Obsidian Version 1.3.7

Feature Request: Exclusion of undesired suggestions

Hello again,

I noticed that there is no way to exclude existing suggestions from the Crossbow list. I think it would be most user-friendly to use a context menu that opens when right-clicking an entry.

Within the context menu, there could be multiple options for excluding an item like this:

  • Exclude suggestions for this line
  • Exclude this suggestion (combination of actual text and backlink title)
  • Allow suggestion (if previously excluded)

It would make the most sense to have a persistent archive for excluded suggestions within the Crossbow pane.

Bug: Error on unloading plugin

Describe the bug

Whenever the plugin gets reactivated (after an update or simply unloading it), the plugin throws the following error about the crossbow-tree-view already being registered.

Afterward, the plugin cannot be used and the settings page also fails to register. A reboot solves this issue.

To Reproduce

Steps to reproduce the behavior:

  1. Disable or update the crossbow plugin
  2. Re-enable the crossbow plugin
  3. Open the Dev console to see the error message

Expected behavior

The plugin should unload the view correctly on unload to be registered again after activation.

Screenshots

image

Software information:

  • OS: Windows
  • Plugin Version: 1.3.0
  • Obsidian Version: 1.3.4

Additional context
This bug has existed before the 1.3.0 release.

Bug: Minimum word length of suggestions not applying to headings and tags

Hello again,

I found that even with the default limitation of minimum 3 characters, there are suggestions with 3 or less letters.

grafik

Crossbow found headings for the respective suggestion.

When strolling through your code, I stumbled upon the indexingService.ts, that only contains the following condition checking for a sufficient word length. If I understood the code correctly it would only apply to filenames and not necessarily to headings or tags.

if (file.basename.length >= this.settingsService.getSettings().minimumSuggestionWordLength)

CR: Add stop word dictionaries

Is your feature request related to a problem? Please describe.

In the default value of Ignored Words there is: image, the, always, some.

This list is none exhaustive and can generate a lot of none pertinent relationships. For example, we have words like with, instance, etc.

Furthermore, since I am French, there is also a lot of french words that can cause none pertinent relationships, likedans (in in English), elles (they in English for women), etc.

Describe the solution you'd like

Add the ability to include common word (dictionary) of one or several language).

Furthermore, add a switch button, to allow case insensitive.

Bug: Does not remove old results on refresh

Clicking on the Scroll into View button does not work most of the time.
I tried to change the theme or Reading/Edit view, but it didn't help.

Same issue with "Go to Source" for the suggestions. It opens the correct file but does not scroll to the occurrence (unless that is by design, but it's hard to know where in the source the word is). The "go to source" should in theory open the file and scroll to the word to find if the occurrence is meaningful.

** Edit: I have pinpointed the issue of the Scroll into View of the first case. Scrolling does not work if the word is found inside a callout quote.

CR: Add "Folders to Ignore"

Is your feature request related to a problem? Please describe.
I have a lot of template files, and unfortunately many are getting picked up as suggestions

Describe the solution you'd like
As below:
image

Bug: It is can't work

Hi, friend. I love the plugin but I can't use it work.
Here is a picture. My ob version is 1.2.3
image

Plugin Settings: Toggle for Enabling/Disabling, Custom Refresh Cycle, and Manual Reload Button

Hello again,

I have a few ideas regarding useful settings for the plugin.

  • Toggle for enabling/disabling the plugin
  • A setting to set a custom refresh cycle (like with dataview)
  • Toggle for enabling/disabling automatic refreshing

The last option then implies a new manual method (like a button in the crossbow view) for reloading the suggestions in the window.

Thanks for the consideration!

CR: Filters for the suggestion pane

Is your feature request related to a problem? Please describe.

Not necessarily.

Describe the solution you'd like

I'd like to have an option in the crossbow pane that lets me select which level of suggestion are filtered and shown in the suggestions.
Currently, there is this medal hierarchy which indicate different levels of accuracy.

I'd like to be able to select the level of accuracy, e.g. the ''πŸ† and above" or the "silver medal and above" level, and only have those shown.

Additional context

grafik
This being the current crossbow pane, I'd expect a dropdown in the top right corner right above the actual accuracy indicators.

Bug: Scroll behavior in Reading View

Describe the bug
I found the bug that I failed to reproduce in another issue: scrolling to a line does not work with "Reading View".

In the editor settings, setting "Default View for new tabs" to "Reading View" will break the "Go to Source" since it won't scroll into the required title when opening the source file in another tab.
Scrolling will also not work in the same open file if press "Scroll into View" if the current view is in "reading mode."

Expected behavior
Either scroll in the "reading mode", or if not possible, let the "Go to Source" and "Scroll into View" buttons switch to Editing mode before scrolling.

Thoughts?

CR: Implement Suggestions from obsidian-releases Merge

As suggested in obsidianmd/obsidian-releases#1827

_currentFile I suggest moving the _currentFile and the event listeners onto your View subclass. That way the plugin doesn't really doing any processing if the view is closed. It also is a better hierarchy since you might want to allow users to pin the view to a specific file and allow multiple views in the future.
prototype please avoid mutating the class prototypes. While it's additive in this case, if another plugin wanted to add a function with the same name, you could run into problems. Similarly, when the user updates your plugin, the old getWordLookup function will still live on the Editor instance meaning you could run into some bugs there if you aren't careful.
tree-item-button you should prefix these classnames to avoid them leaking out of your plugin view. These are very similarly named to Obsidian's tree items if we added a tree-item-button in the core app, you might unexpectedly be overriding those elements.

Bug: Filename suggestions get overridden by heading / tag suggestions in the same file

Describe the bug
From issue #16:

I've actually found a bug in the old cache system. You couldn't have e.g. identical headings in separate files show up in the
suggestions, since the one that was indexed last overrode the previous keys. So I've refactored the cache system some more and
added a subtitle to the suggestions which show the file source.

There's still some minor issues with the new approach. For example, if you have a heading in a file with the same name as the
filename, it'd override the possible suggestion for a file. Same goes for tags. I'll keep it like this until I find a better solution, since
the new implementation is pretty fast.

To Reproduce
Steps to reproduce the behavior:

  1. Create a file named "Testfile"
  2. Create a heading in this file called "Testfile" or a tag called "Testfile"
  3. In another file, write "Testfile" as text
  4. Ony the heading or only the tag will be show as a suggestion

Expected behavior
Two / Three suggestion should be show, one for the file, one for the heading or / and tag

Desktop (please complete the following information):

  • Plugin Version 1.2.1
  • Obsidian Version 1.2.8

Bug: Opacity Issue

Describe the bug
The source file name was a great addition to the results list! The issue is it's hard to read with the color/opacity set in both light and dark themes.
To confirm, I reverted from my custom dark theme to the default theme and tried both light and dark versions, showing the same issue as the screenshots below.

Also notice that in light mode, the "Heading" is even more affected (I'm a dark mode guy but better be thorough πŸ˜„).

Screenshots
image

image

Doc request: how it works

There are lots of plugins that do this, it would be good to know exactly how the plugin suggests notes so that users can see whether this plugin replicates other plugins they have or compliments them.

Performance - incompatible with very large files

Crossbow works well with smaller files but gets really heavy on large documents. I am talking about my specific example of a document of 29205 words.

What happens?
Obsidian freezes but does not crash. Whenever I switch a file by clicking on an open pane, I can unlock Obsidian after waiting a little while.
It does also not matter if the Crossbow pane is active or not.

What could be done?
Crossbow could load and analyze a set amount of words around the cursor position so it doesn't slow down ad infinitum.
It could also deactivate when the pane is not active.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.