RunJS - Obsidian Plugin/Codes

옵시디언 RunJS: 이벤트 다루기 (데일리 노트에 시간 자동 추가)

eoureo 2024. 12. 24. 22:00

 

이 글에서는 옵시디언(Obsidian)RunJS 플러그인을 사용하여 이벤트 핸들러를 설정하고, 데일리 노트 플러그인을 활용하여 오늘 노트의 마지막 줄에 현재 시간을 리스트 항목으로 추가하는 방법을 다룹니다.

이를 통해 간단한 작업을 자동화하고, 옵시디언을 더욱 편리하게 사용할 수 있습니다.

 

 

 

기능 설명

아래 그림과 같이 RunJS 코드를 클릭하면 데일리 노트의 마지막 줄에 "- 08:30" 형식의 현재 시간 리스트 항목이 추가됩니다. 추가된 시간 뒤에는 커서가 위치하므로 이어서 바로 내용을 입력할 수 있습니다. 또한, 옵시디언이 시작할 때 자동으로 이 작업이 실행되도록 이벤트 핸들러를 설정하는 방법도 다룹니다.

 

RunJS 실행 항목 추가하기

1. 소스 코드

아래 코드를 옵시디언의 노트에 복사해 붙여넣으세요. 이 코드는 데일리 노트를 열고 현재 시간을 마지막 줄에 추가하는 역할을 합니다.
소스 코드를 이해가 쉽도록 주석(설명)을 추가했습니다.

```js RunJS="{n:'Daily notes/Add list (HH:MM) to Today',t:'s'}"
// "- 08:30 " 형식으로 지금 시간을 마지막 줄에 넣기

const app = this.app;

// 오늘 노트를 얻기 위해 daily-notes 플러그인의 명령을 실행합니다.
// 오늘 노트가 없으면 새로 만들게 됩니다.
const todayNote = await app.internalPlugins.plugins["daily-notes"].instance.getDailyNote();
// console.log("todayNote:", todayNote); // DevTools에서 확인해 보기 (Ctrl + Shift + i)

let todayLeaf;
let firstDailyNoteLeaf;
let aLeaf = app.workspace.getLeaf();

if (aLeaf.view.file == todayNote) {
	// 지금 활성화된 노트가 오늘 노트이므로 바로 액션!
	todayLeaf = aLeaf;
	doAction();
} else {
	// 열린 노트 탭들 가운데서 데일리 노트 찾기
	app.workspace.iterateAllLeaves(leaf => {
		let filePath = leaf.view?.file?.path ?? leaf.view?.state?.file;
		if (!filePath) return;
		let fileParentPath = filePath?.replace(/\/[^\/]*$/, "");
		
		if (todayLeaf == undefined && filePath == todayNote.path) {
			// 오늘 노트가 열린 탭을 찾음
			todayLeaf = leaf;
		} else if (firstDailyNoteLeaf == undefined && todayNote.parent.path == fileParentPath) {
			// 오늘 노트는 아니지만 데일리 노트가 열린 탭을 찾음
			firstDailyNoteLeaf = leaf;
		}
	});

	if (todayLeaf == undefined && firstDailyNoteLeaf != undefined) {
		// 오늘 노트 열린 탭이 없어 차선으로 다른 날 데일리 노트가 열린 탭에서 오늘 노트를 열기 위해
		todayLeaf = firstDailyNoteLeaf;
	}

	if (todayLeaf) {
		// 데일리 노트가 있는 탭을 활성화한다.
		await app.workspace.setActiveLeaf(todayLeaf);
	}
	else {
		// 활성화되어 있는 현재 탭에서 오늘 노트를 열기 위해
		todayLeaf = aLeaf;
	}

	// 이벤트 핸들러 추가 - 노트 탭에 변화가 있을 때 실행
	let eventRef = this.app.workspace.on("active-leaf-change", async function (leaf) {
		// 오늘 노트가 아니면 다시 오늘 노트 열기 실행
		if (leaf.view?.file?.path != todayNote.path) {
			openToday();
			return;
		}

		// 이 이벤트 핸들러 제거 - 이번 한 번만 실행되어야 하므로
		app.workspace.offref(eventRef);
		
		// Tamplater와 충돌을 피하기 위해 시간(3초)을 소비한 다음 액션!
		await sleep(3000);
		
		doAction();
	});

	// daily-notes 플러그인 명령을 써서 오늘 노트를 연다.
	// 이때 위의 이벤트 핸들러가 작동하여 액션!
	openToday();
}

/**
 * 오늘 노트 열기
 */
function openToday() {
	let commands = app.internalPlugins.plugins["daily-notes"].commands;
	commands.find(c => c.id == "daily-notes")?.callback();
}

/**
 * 지금 시간을 마지막 줄에 넣기
 */
async function doAction() {
	const now = new Date();

	let hours = ("0" + now.getHours()).slice(-2);
	let minutes = ("0" + now.getMinutes()).slice(-2);

	let editor = todayLeaf.view?.editor;
	if (editor) {
		// 편집 모드로 바꾼다.
		let viewState = todayLeaf.getViewState();
		viewState.state.mode = "source";
		todayLeaf.setViewState(viewState);

		let textNew = "- " + hours + ":" + minutes + " ";
		let textNewLength = textNew.length;

		// 오늘 노트의 마지막 줄 번호
		let lastLine = editor.lastLine();
		// 오늘 노트의 마지막 줄의 글을 가져온다.
		let lastLineText = editor.getLine(lastLine);
		
		if (/^\s*\-\s*$/.test(lastLineText)) {
			// 이미 "-"이 들어간 줄이면 그 줄을 활용하기 위해
			textNew = lastLineText.replace(/\-\s*$/, textNew);
			textNewLength = textNew.length;
		} else {
			// 마지막 줄 다음에 추가하기 위해
			lastLine += 1;
			textNew = "\n" + textNew;
		}

		// 마지막 줄에 넣기
		editor.setLine(lastLine, textNew);
		// 커서 위치를 옮긴다.
		editor.setCursor(lastLine + 1, textNewLength);
		editor.focus();
	} else {
		console.log("no editor!")
	}
}

```

 

참고로 다음 소스는 단순히 활성화된 노트에 데일리 노트 플러그인의 명령을 사용하여 오늘 노트를 여는 것입니다.
데일리 노트의 명령을 사용하는 법을 볼 수 있도록 만들어 봤습니다.

```js RunJS="{n:'Daily notes/Today',t:'s'}"
let commands = app.internalPlugins.plugins["daily-notes"].commands;
commands.find(c => c.id == "daily-notes")?.callback();
```

2. 실행 방법

  1. 위 코드(Daily notes/Add list (HH:MM) to Today)를 복사하여 옵시디언의 노트에 붙여 넣습니다.
  2. 그러면 RunJS 코드 목록에 저절로 새 항목이 등록이 됩니다.
  3. 이 항목을 클릭하면 위 코드가 실행됩니다
  4. 그러면 이 코드는 열린 노트 중 오늘 날짜나 다른 날짜의 데일리 노트를 찾습니다. 없을 경우 활성화된 노트에서 오늘 날짜 노트를 엽니다.
  5. 마지막 줄에 "- HH:MM " 형식의 리스트 항목을 추가한 후 커서를 위치시킵니다.
  6. 커서가 리스트 항목 뒤에 바로 위치하므로 내용을 입력하면 됩니다.

 

01
① 소스 코드 추가, ② 실행

 

RunJS 이벤트 핸들러 설정하기

옵시디언이 시작할 때 자동으로 데일리 노트에 현재 시간을 추가하도록 설정하도록 하겠습니다. 아래 슬라이드쇼처럼 다음 단계를 따라하세요:

  1. RunJS의 설정에서 Event handler 섹션으로 이동합니다.
  2. + 버튼을 눌러 새 이벤트를 추가합니다.
  3. 이벤트 설정
    1. 코드 선택: 코드 팔레트에서 "Daily notes/Add list (HH:MM) to Today" 명령을 선택합니다.
    2. 이벤트 오브젝트: "workspace"를 선택합니다.
    3. 이벤트 이름: "layout-ready"를 선택합니다.
    4. 이벤트를 사용(enable)으로 설정합니다.
    옵시디언이 시작한 다음 화면 구성이 끝나야 실행되는 코드이기 때문에 "workspace" - "layout-ready"로 설정해야 합니다
  4. 설정을 완료한 후 옵시디언을 재시작(또는 DevTools에서 Ctrl + R 입력)합니다. 이제 데일리 노트의 마지막 줄에 현재 시간이 자동으로 추가되는 것을 확인할 수 있습니다.

 

012345678
① 이벤트 추가 ② 이벤트 설정 ⑨ 재시작 후 결과 화면

 

추가 팁: 옵시디언 개발자 도구 활용하기

옵시디언의 개발자 도구(Developer Tools)를 열어 플러그인의 내부 구조를 더 깊이 탐구해 보세요. 단축키 Ctrl + Shift + I를 눌러 개발자 도구를 열 수 있습니다. 예를 들어 다음 명령어로 데일리 노트 플러그인의 세부 정보를 확인할 수 있습니다:

살펴볼 주요 오브젝트

다음 글을 복사하여 아래 그림과 같이 개발자 도구에 붙여넣기 해보세요. 또 한 글자씩 직접 입력도 꼭 해보기 바랍니다.

  • app.internalPlugins.plugins["daily-notes"]: 데일리 노트 플러그인 정보 조회
  • app.internalPlugins.plugins["daily-notes"].commands: 위 소스 코드에서 사용한 데일리 노트 명령들
  • app.internalPlugins.plugins["daily-notes"].instance.getDailyNote: 위 소스 코드에서 사용한 데일리 노트 메서드
  • app.internalPlugins.plugins: 옵시디언 내부 플러그인 목록 확인
  • app.plugins.plugins: 설치된 커뮤니티 플러그인 목록 확인. RunJS와 Dataview, Tamplater 등을 볼 수 있네요.

이 정보를 활용하면 RunJS뿐만 아니라 다른 플러그인과의 연동 작업도 가능합니다.

 

Developer Tools

위 그림의 마지막 프레임에서 Daily notes의 commands, getDailyNote를 찾을 수 있습니다.

 

결론

이 글에서는 옵시디언 RunJS를 활용하여 데일리 노트에 현재 시간 리스트 항목을 추가하고, 이를 자동화하는 방법을 알아보았습니다. 이 방법으로 옵시디언 사용을 더욱 효율적으로 만들어 보세요!

이 내용은 GitHub Discussions에서 확인할 수 있습니다.


궁금한 점이나 의견이 있다면 댓글로 남겨 주세요! 😊