Code snippet: extract note

Gif presention

Warning

:warning: This script doesn’t tested enough and will change the content inside of notes. Please, do a backup before using this extension.

Info

This script will get current selection, create a note, and post content inside of it.

  • First line of selected text will be a filename.
  • All others - content

Usage

!function() {
	async function extractSelection() {
			const doc = app.workspace.activeLeaf.view.sourceMode.cmEditor.doc
			const selectedText = doc.getSelection()

			if (!selectedText) { return }

			const [header, ...contentArr] = selectedText.split('\n')

			const rootFolder = app.vault.getRoot()

			const file = await app.fileManager.createNewMarkdownFile(rootFolder, header)
			app.vault.modify(file, contentArr.join('\n'))

			doc.replaceSelection('[[' + header + ']]')
	}

	app.commands.addCommand({
	    id: 'app:extract-selection',
	    name: 'Extract selection',
	    callback: extractSelection,
	    hotkeys: []
	})
}()

After script execution:

  1. Select the text which you want to extract
  2. Run command palette (Ctrl+Shift+P) and find Extract selection

Related

2 Likes

There are only some points i found while testing:

  1. if the title/filename is already belong to another file. The the 1st note file remain. In the reading file, the content of the new snip is being replaced by the [[link]] while its content is deleted (no warning of existing note ).
  2. For people who are are new to markdown, the definition of next line maybe a bit fuzzy when text is wrapped. If you select text within the line, then it just turn that highlighted selection into new link
  3. Should alert people on choosing new default location for new notes (instead of main vault). Cause the vault fill up quite fast when you snip (especially with hotkey)
  4. Always make a copy of the original note (either alert reminder or auto copy feature). (because after reading and snip, the original file is shredded with [[link title]]. most of the important points are already being shorten/cut/snipped away)

Also:

  1. If the title of the note contain symbols and OS block file creation, then Obsidian do nothing (great!).

Recommend features:

  • If note heading already exist, give alert for new name OR auto adding a number behind new notes. maybe also 1 option to name the new notes as foldername_# (# to make it unique)

I made some tweaks to your code. Thanks for the nice snippet!

These changes limit the characters in the filename, save in the default note folder, link to the actual basename (in case of existing file) and doesn’t delete the text but rather leaves it as a selection so you can choose to delete it yourself.

!function() {
  async function extractSelection() {
    const doc = app.workspace.activeLeaf.view.sourceMode.cmEditor.doc
    const selectedText = doc.getSelection()

    if (!selectedText) { return }

    const [header, ...contentArr] = selectedText.split('\n')
    const reAlphanum = /[^\w\s_-]+/g
    const rootFolder = app.fileManager.getNewFileParent()
    const title = header.replace(reAlphanum, '').substring(0, 252)
    const file = await app.fileManager.createNewMarkdownFile(rootFolder, title)
    var selHead = doc.getCursor("anchor")
    var selEnd = doc.getCursor("end")
    app.vault.modify(file, header + contentArr.join('\n'))
    doc.replaceSelection('[[' + file.basename + ']]\n' + selectedText)
    selHead.line = selHead.line + 1
    selEnd.line = selEnd.line + 1
    doc.setSelection(selHead, selEnd)
  }

  app.commands.addCommand({
    id: 'app:extract-selection',
    name: 'Extract selection',
    callback: extractSelection,
    hotkeys: []
  })
}()

i tried implementing your code but it show this error:

app.js:1 Uncaught (in promise) TypeError: Cannot read property 'lastIndexOf' of undefined
    at K (app.js:1)
    at e.getNewFileParent (app.js:1)
    at Object.extractSelection [as callback] (<anonymous>:10:40)
    at N (app.js:1)
    at e.executeCommandById (app.js:1)
    at e.onTrigger (app.js:1)
    at e.handleKey (app.js:1)
    at e.onKeyEvent (app.js:1)

That’s strange, it’s coming from the getNewFileParent call which is the inbuilt function - not something to do with that snippet.

What happens if you run app.fileManager.getNewFileParent() directly in the console?
This is what I get:

I got the same too:
app.fileManager.getNewFileParent()
t {vault: t, path: “WORK”, name: “WORK”, children: Array(15), parent: t}

But currently, there is a plugin for this function already, if you are interested in contacting the author and do PR?

Sounds good, I’ll try the plugin, was there the same/similar error? Or it just works™?