ArianaKhit / text-snippets-obsidian

Snippets plugin for obsidian
190 stars 23 forks source link

Cannot Read Properties of null (reading 'from') #42

Open PeteMichaud opened 2 years ago

PeteMichaud commented 2 years ago

When I try to use a snippet like so:

<< : «

It fails, and throws the exception: Uncaught TypeError: Cannot read properties of null (reading 'from')

Coming from this line: https://github.com/ArianaKhit/text-snippets-obsidian/blob/ed8bd87db1450bf3e88ca98cd2e7306e7e6bafc7/main.ts#L111

Looks like editor.wordAt doesn't like the bracket characters?

PeteMichaud commented 2 years ago

Investigating further, CodeMirror's wordAt function is used to capture the potential snippet name, but it only finds words made of "word characters." The function itself:

function wordAt(cm, pos) {
    var start = pos.ch, end = start, line = cm.getLine(pos.line);
    while (start && CodeMirror.isWordChar(line.charAt(start - 1))) --start;
    while (end < line.length && CodeMirror.isWordChar(line.charAt(end))) ++end;
    return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)};
  }

The relevant call here is isWordChar.

There are 2 options that I can see:

  1. Use a custom implementation of wordAt that removes the call to isWordChar and replaces it with something like isNotWhiteSpaceChar. This would let us use snippets with any characters we wanted, and is my preferred method.
  2. Insert a null check at the offending line linked in the original message of this thread, and potentially do some error checking on the settings screen, alerting the user to a snippet that cannot be processed because it's not made of word characters.

A third option which is not available to us at this time: isWordChar takes an optional parameter of a custom helper to inject logic about what counts as a word character, but wordAt doesn't support passing that through. If it did support passing through we could pass our own logic in without making a custom function at all. I'll go make a feature request in the CodeMirror repo, because I think that would actually be ideal.

rickalex21 commented 2 years ago

I'm getting something similar.

VM361:61 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'view')
    at TextSnippets.eval (eval at <anonymous> (app.js:1:1494667), <anonymous>:61:60)
    at Generator.next (<anonymous>)
    at fulfilled (eval at <anonymous> (app.js:1:1494667), <anonymous>:28:58)

The problem is in the line that contains let editor...

if (this.settings.isWYSISWYG) {
                let editor = this.app.workspace.activeLeaf.view.sourceMode.cmEditor;
                this.settings.isWYSISWYG = (typeof editor.wordAt === 'function');
                this.registerDomEvent(document, 'keydown', (event) => this.handleKeyDown(editor, event));

I can't use 'Tab' , I have it enabled . It automatically inserts an indent. Not sure if I have to unmap it and remap it some how in obsidian.vimrc or something else I have to do?

My plugin does not show up, I think it's cause of this error. I usually just edit the data.json since I can't see the plugin settings.

ArianaKhit commented 2 years ago
  1. Use a custom implementation of wordAt

I preferred this option, now in 0.1.0 "word" is sequence of characters except whitespaces and delimiters.

ArianaKhit commented 2 years ago

I can't use 'Tab'

For some reasons Tab or Space are not working in LivePreview mode.

jeansordes commented 2 years ago

About the "Tab and Space" issue, we found a temporary fix in issue #47