#Obsidian
## 経緯
- [[Jump to link]]プラグインを愛用していたが、[[Live Preview]]で使えない状態が続いている
- [Issue](https://github.com/mrjackphil/obsidian-jump-to-link/issues/27)は作成されている
- ...が作者の[[👤mrjackphil]]氏が忙しそうで対応厳しそう..
- じゃあ動くようにしてみるか
という感じ。1時間でできなかったら諦めるかも。
## メモ
### `TypeError: cmEditor.getViewport is not a function`
- `cmEditor.getViewport()`関数がない
[[Obsidian API]]を見る限り`Editor`クラスにありそう
```ts:44行目のcmEditorにはインスタンスが入っていた
} else if (currentView.getState().mode === 'source') {
const cmEditor: Editor = (currentView as any).sourceMode.cmEditor;
console.log(cmEditor) // e {cm: t}
this.manageSourceLinkHints(cmEditor);
}
```
だけどよく見ると`cm`プロパティでラップされている?
#### 呼び出しメソッドリスト
| メソッド | 可否 | 代替 |
| ------------ | ---- | -------------------------- |
| getViewport | x | `cm.viewState.getViewport` |
| indexFromPos | x | `cm.cm.indexFromPos` |
| getRange | o | - |
| posFromIndex | x | `cm.cm.posFromIndex` |
| addWidget | x | `cm.cm.addOverlay` |
| setCursor | o | - |
いやこれ小手先だと無理な気がする。。
https://www.nikkei.com/article/DGXZQOUC077V70X00C22A1000000/?n_cid=SNSTW001&n_tw=1644670111
### 根本的な設計変更がいる
[[CodeMirror 6]]の設計が[[React]]や[[Vue]]のようなReactive思想になっているので、コマンドが実行されたら[[DOM]]を書き換えるような現設計では厳しい気がする。。
[CodeMirror Decoration Example](https://codemirror.net/6/examples/decoration/) を参考に少し実装してみたが、UIはできてもこの部分はどうしようもない..
```ts
class LetterWidget extends WidgetType {
constructor(readonly letter: string) { super() }
eq(other: LetterWidget) { return other.letter === this.letter }
toDOM() {
const linkHintEl = document.createElement('div');
linkHintEl.addClass('jl');
linkHintEl.addClass('popover');
linkHintEl.innerHTML = this.letter;
return linkHintEl;
}
ignoreEvent() { return false }
}
// letterPluginの実装を変更しようと思って、簡単にはできないことに気づく。。orz
const letterPlugin = ViewPlugin.fromClass(class {
decorations: DecorationSet
constructor(view: EditorView) {
this.decorations = checkboxes(view)
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged)
this.decorations = checkboxes(update.view)
}
}, {
decorations: v => v.decorations,
eventHandlers: {
mousedown: (e, view) => {
let target = e.target as HTMLElement
if (target.nodeName == "INPUT" &&
target.parentElement!.classList.contains("cm-boolean-toggle"))
return toggleBoolean(view, view.posAtDOM(target))
}
}
})
```
## トラブルと解消法
### アクティブペイン以外にも表示されてしまう
動作に実害はないので[[CSS]]で隠す。
```css
.obsidian-quick-jump-plugin__mark {
display: none
}
.mod-active .obsidian-quick-jump-plugin__mark {
display: inherit;
position: absolute;
border: 1px solid white;
border-radius: 10px;
background-color: rgba(0, 0, 0, 0.5);
color: aliceblue;
padding: 0 5px;
margin-top: -10px;
}
```