24 Commits
Author SHA1 Message Date
Seongjae Lee aa641ba695 Prepare 0.10.0 release 2016-04-25 18:47:08 -07:00
Seongjae Lee 6a7e04d177 Merge pull request #48 from jonmagic/patch-1
Update docquery to 1.1.1
2016-04-25 18:43:03 -07:00
Jonathan Hoyt 5aab86660f Update docquery to 1.1.1 2016-04-24 21:49:26 -07:00
Seongjae Lee 6ec1c4c2e8 Prepare 0.9.3 release 2015-10-17 00:14:44 -07:00
Seongjae Lee f582f741ad Merge pull request #38 from xHN35RQ/master
Add Windows/Linux keymap note
2015-10-17 00:14:13 -07:00
Seongjae Lee 6fe704aad1 Prepare 0.9.2 release 2015-10-16 23:49:32 -07:00
Seongjae Lee 669839750c Fix the double padding problem in the search window 2015-10-16 23:49:20 -07:00
Nic 452c34ba36 Add Windows/Linux keymap note 2015-10-16 23:03:11 -07:00
Seongjae Lee ee5dc2a87a Prepare 0.9.1 release 2015-10-16 22:33:32 -07:00
Seongjae Lee bd7d47474c Add interlink menu item 2015-10-16 22:33:11 -07:00
Seongjae Lee 424f2a13d6 Prepare 0.9.0 release 2015-10-16 22:17:43 -07:00
Seongjae Lee 04b7df8676 Update changelog 2015-10-16 22:16:23 -07:00
Seongjae Lee 2d2a070d1e Fix a bug that utility.isNote does not handle symlinks properly 2015-10-07 07:55:36 -07:00
Seongjae Lee 6ae37437be Load nvatom grammar on atom 2015-09-28 21:42:23 -07:00
Seongjae Lee 51f769a017 Apply the interlink extended grammar only on valid notes
To do so, we need to activate the package on Atom startup.
2015-09-28 01:14:39 -07:00
Seongjae Lee ca7c14e3b7 Rename notelink to interlink 2015-09-27 10:45:51 -07:00
Seongjae Lee c5eca919ed Add tests for notelinks 2015-09-27 10:39:03 -07:00
Seongjae Lee 9244b0a0b9 Update readme for interlinks 2015-09-26 10:34:02 -07:00
Seongjae Lee 323fb29e56 Add tests for utility class 2015-09-26 10:27:46 -07:00
Seongjae Lee 6c55f58774 Fix uncaught reference error for not including utility 2015-09-26 07:52:03 -07:00
Seongjae Lee 9c5c4e43da Add interlink highlight and jump features 2015-09-26 00:16:36 -07:00
Seongjae Lee cc8a780436 Prepare 0.8.2 release 2015-09-24 21:25:23 -07:00
Seongjae Lee 431b929208 Merge pull request #33 from lexicalunit/normalize_directory
Normalize nvatom.directory so that ~/... works correctly.
2015-09-24 21:22:32 -07:00
lexicalunit 61d071c15a Normalize nvatom.directory so that ~/... works correctly. 2015-09-24 18:36:59 -05:00
13 changed files with 355 additions and 101 deletions
+3
View File
@@ -1,3 +1,6 @@
## 0.9.0
- Add an interlink feature
## 0.8.0
- Add a feature to delete an empty note automatically when closing its pane
+11
View File
@@ -13,6 +13,7 @@ This Atom package implements the some key features from this amazing app:
- Modeless operation
- Mouseless interaction
- Incremental Search
- Interlinks
Integrated with Atom, we have several advantages:
@@ -47,6 +48,7 @@ Double-quotes also work.
## Key Bindings
- `alt-cmd-l`: Toggles the search view.
- `alt-cmd-o`: Jumps to the referred note when the cursor is on the interlink in the form of [[double-bracketed interlink]].
You can also override `cmd-l` if you want to keep your muscle memory from Notational Velocity and nvALT. Just edit your keymap (Atom menu -> Open Your Keymap) and add the following lines:
@@ -57,6 +59,15 @@ You can also override `cmd-l` if you want to keep your muscle memory from Notati
'cmd-l': 'nvatom:toggle'
```
To set Windows and Linux key binds you can add the following lines to your keymap:
```cson
'atom-workspace':
'alt-ctrl-l': 'nvatom:toggle'
'atom-workspace atom-text-editor':
'alt-ctrl-o': 'nvatom:openInterlink'
```
## Migration
v0.1.0 under published package name `notational-velocity` had a fatal bug that sets the default value of its note directory under package directory. In that case, all notes are deleted once the user updates the package, since package directory is overwritten when the user. For more information, refer [#25][6].
+18
View File
@@ -0,0 +1,18 @@
'name': 'nvAtom Github Markdown'
'scopeName': 'source.gfm.nvatom'
'patterns': [
{
'include': 'source.gfm'
}
{
'match': '(?<!\\[)(\\[\\[)([^\\[\\]\|]+)(\\]\\])(?!\\])'
'name': 'interlink'
'captures':
'1':
'name': 'punctuation.definition.begin.gfm'
'2':
'name': 'markup.underline.link.interlink.gfm'
'3':
'name': 'punctuation.definition.begin.gfm'
}
]
+2
View File
@@ -9,3 +9,5 @@
# https://atom.io/docs/latest/advanced/keymaps
'atom-workspace':
'alt-cmd-l': 'nvatom:toggle'
'atom-workspace atom-text-editor':
'alt-cmd-o': 'nvatom:openInterlink'
+48
View File
@@ -0,0 +1,48 @@
fs = require 'fs-plus'
path = require 'path'
{CompositeDisposable} = require 'atom'
Utility = require './utility'
module.exports =
class Interlink
constructor: ->
Interlink.loadGrammarSync()
@subscriptions = new CompositeDisposable
@subscriptions.add atom.commands.add 'atom-workspace', 'nvatom:openInterlink': => Interlink.openInterlink()
@subscriptions.add atom.workspace.observeTextEditors (editor) ->
if Utility.isNote(editor.getPath())
editor.setGrammar(atom.grammars.grammarForScopeName('source.gfm.nvatom'))
destroy: ->
@subscriptions.dispose()
@loadGrammarSync: ->
unless atom.grammars.grammarForScopeName('source.gfm.nvatom')
grammarPath = path.join(atom.packages.resolvePackagePath('nvatom'), 'grammars', 'nvatom.cson')
atom.grammars.loadGrammarSync(grammarPath)
@openInterlink: ->
editor = atom.workspace.getActiveTextEditor()
return unless editor?
return unless Utility.isNote(editor.getPath())
noteTitle = Interlink.getInterlinkUnderCursor(editor)
return unless noteTitle?
return unless noteTitle.length
notePath = Utility.getNotePath(noteTitle)
unless fs.existsSync(notePath)
fs.writeFileSync(notePath, '')
atom.workspace.open(notePath)
@getInterlinkUnderCursor: (editor) ->
cursorPosition = editor.getCursorBufferPosition()
token = editor.tokenForBufferPosition(cursorPosition)
return unless token
return unless token.value
return unless token.scopes.indexOf('markup.underline.link.interlink.gfm') > -1
interlink = Utility.trim(token.value)
return unless interlink.length
return interlink
+43 -65
View File
@@ -3,14 +3,15 @@ fs = require 'fs-plus'
_ = require 'underscore-plus'
{$, $$, SelectListView} = require 'atom-space-pen-views'
DocQuery = require 'docquery'
Utility = require './utility'
module.exports =
class NotationalVelocityView extends SelectListView
initialize: (state) ->
@initializedAt = new Date()
super
@addClass('nvatom from-top overlay')
@rootDirectory = atom.config.get('nvatom.directory')
@addClass('nvatom')
@rootDirectory = Utility.getNoteDirectory()
unless fs.existsSync(@rootDirectory)
throw new Error("The given directory #{@rootDirectory} does not exist. "
+ "Set the note directory to the existing one from Settings.")
@@ -38,6 +39,33 @@ class NotationalVelocityView extends SelectListView
@prevCursorPosition = currCursorPosition
return isCursorProceeded
selectItem: (filteredItems, filterQuery) ->
isCursorProceeded = @isCursorProceeded()
for item in filteredItems
if item.title.toLowerCase() is filterQuery.toLowerCase()
# autoselect
n = filteredItems.indexOf(item) + 1
@selectItemView(@list.find("li:nth-child(#{n})"))
return
for item in filteredItems
if item.title.toLowerCase().startsWith(filterQuery.toLowerCase()) and isCursorProceeded
# autocomplete
@skipPopulateList = true
editor = @filterEditorView.model
editor.setText(filterQuery + item.title.slice(filterQuery.length))
editor.selectLeft(item.title.length - filterQuery.length)
# autoselect
n = filteredItems.indexOf(item) + 1
@selectItemView(@list.find("li:nth-child(#{n})"))
filter: (filterQuery) ->
if (filterQuery is "") or (filterQuery is undefined)
return @docQuery.documents
return @docQuery.search(filterQuery)
getFilterKey: ->
'filetext'
@@ -63,10 +91,9 @@ class NotationalVelocityView extends SelectListView
confirmSelection: ->
item = @getSelectedItem()
sanitizedQuery = Utility.trim(@getFilterQuery())
calculatedPath = Utility.getNotePath(sanitizedQuery)
filePath = null
sanitizedQuery = @getFilterQuery().replace(/\s+$/, '')
extension = if atom.config.get('nvatom.extensions').length then atom.config.get('nvatom.extensions')[0] else '.md'
calculatedPath = path.join(@rootDirectory, sanitizedQuery + extension)
if item?
filePath = item.filePath
else if fs.existsSync(calculatedPath)
@@ -109,73 +136,24 @@ class NotationalVelocityView extends SelectListView
selectedText = editor.getSelectedText()
return fullText.substring(0, fullText.length - selectedText.length)
filterByTitle: (filterQuery) ->
if (filterQuery is "") or (filterQuery is undefined)
return []
filterQuery = filterQuery.toLowerCase()
matchingNotes = []
filteredNotes = []
for note in @docQuery.documents
title = note.title.toLowerCase()
if title is filterQuery
matchingNotes.push(note)
else if filteredNotes.length < @maxItems and title.startsWith(filterQuery)
filteredNotes.push(note)
notes = matchingNotes.concat(filteredNotes)
if notes.length > @maxItems
notes = notes.slice(0, @maxItems)
return notes
filterByLunr: (filterQuery) ->
notes = []
if (filterQuery is "") or (filterQuery is undefined)
notes = @docQuery.documents
else
notes = @docQuery.search(filterQuery)
if notes.length > @maxItems
notes = notes.slice(0, @maxItems)
return notes
populateList: ->
filterQuery = @getFilterQuery()
notesByTitle = @filterByTitle(filterQuery)
notesByLunr = @filterByLunr(filterQuery)
isCursorProceeded = @isCursorProceeded()
filteredItems = @filter(filterQuery)
@list.empty()
if notesByTitle.length + notesByLunr.length == 0
@setError(@getEmptyMessage(@docQuery.documents.length, 0))
return
if filteredItems.length
@setError(null)
@setError(null)
for note in notesByTitle
itemView = $(@viewForItem(note))
itemView.data('select-list-item', note)
@list.append(itemView)
for i in [0...Math.min(filteredItems.length, @maxItems)]
item = filteredItems[i]
itemView = $(@viewForItem(item))
itemView.data('select-list-item', item)
@list.append(itemView)
if notesByTitle.length
# autoselect
@selectItemView(@list.find("li:nth-child(1)"))
@selectItem(filteredItems, filterQuery)
#autocomplete
note = notesByTitle[0]
if note.title.toLowerCase() is filterQuery.toLowerCase() or isCursorProceeded
@skipPopulateList = true
editor = @filterEditorView.model
editor.setText(filterQuery + note.title.slice(filterQuery.length))
editor.selectLeft(note.title.length - filterQuery.length)
if @list.length >= @maxItems
return
for note in notesByLunr
if @list.length >= @maxItems
break
if filterQuery?.length and note.title.toLowerCase().startsWith(filterQuery.toLowerCase())
continue
itemView = $(@viewForItem(note))
itemView.data('select-list-item', note)
@list.append(itemView)
else
@setError(@getEmptyMessage(@docQuery.documents.length, filteredItems.length))
schedulePopulateList: ->
unless @skipPopulateList
+11 -12
View File
@@ -1,6 +1,8 @@
path = require 'path'
fs = require 'fs-plus'
{CompositeDisposable, Disposable} = require 'atom'
Interlink = require './interlink'
Utility = require './utility'
module.exports =
config:
@@ -22,16 +24,12 @@ module.exports =
type: 'boolean'
default: true
notationalVelocityView: null
activate: (state) ->
@rootDirectory = @ensureNoteDirectory()
# Events subscribed to in atom's system can be easily cleaned up with a
# CompositeDisposable
@subscriptions = new CompositeDisposable
# Register command that toggles this view
@subscriptions.add atom.commands.add 'atom-workspace',
'nvatom:toggle': => @createView(state).toggle()
@@ -49,12 +47,15 @@ module.exports =
@subscriptions.add atom.workspace.onWillDestroyPaneItem ({item}) => @autosave(item) unless @autodelete(item)
@interlink = new Interlink()
deactivate: ->
@subscriptions.dispose()
@notationalVelocityView.destroy()
@interlnk?.destroy()
@notationalVelocityView?.destroy()
serialize: ->
notationalVelocityViewState: @notationalVelocityView.serialize()
notationalVelocityViewState: @notationalVelocityView?.serialize()
createView: (state, docQuery) ->
unless @notationalVelocityView?
@@ -66,16 +67,14 @@ module.exports =
return unless paneItem?.getURI?()?
return unless paneItem?.isModified?()
uri = paneItem.getURI()
return unless uri.indexOf(@rootDirectory) is 0
return unless path.extname(uri) in atom.config.get('nvatom.extensions')
return unless Utility.isNote(uri)
paneItem?.save?()
autodelete: (paneItem) ->
return false unless paneItem?.getURI?()?
uri = paneItem.getURI()
return false unless uri.indexOf(@rootDirectory) is 0
return false unless path.extname(uri) in atom.config.get('nvatom.extensions')
return false unless paneItem?.isEmpty()
return false unless Utility.isNote(uri)
return false unless paneItem.isEmpty()
fs.unlinkSync(uri)
noteName = uri.substring(@rootDirectory.length + 1)
atom.notifications.addInfo("Empty note #{noteName} is deleted.")
@@ -85,7 +84,7 @@ module.exports =
@autosave(paneItem) for paneItem in atom.workspace.getPaneItems()
ensureNoteDirectory: ->
noteDirectory = atom.config.get('nvatom.directory')
noteDirectory = fs.normalize(atom.config.get('nvatom.directory'))
packagesDirectory = path.join(process.env.ATOM_HOME, 'packages')
defaultNoteDirectory = path.join(packagesDirectory, 'nvatom', 'notebook')
+26
View File
@@ -0,0 +1,26 @@
path = require 'path'
fs = require 'fs-plus'
module.exports =
class Utility
@getNotePath: (title) -> path.join(Utility.getNoteDirectory(), Utility.trim(title) + Utility.getPrimaryNoteExtension())
@getNoteDirectory: -> fs.normalize(atom.config.get('nvatom.directory'))
@getPrimaryNoteExtension: -> if atom.config.get('nvatom.extensions').length then atom.config.get('nvatom.extensions')[0] else '.md'
@isNote: (filePath) ->
return false unless path.extname(filePath) in atom.config.get('nvatom.extensions')
filePath = fs.normalize(filePath)
return true if filePath.startsWith(Utility.getNoteDirectory())
return true if filePath.startsWith(fs.realpathSync(Utility.getNoteDirectory()))
return false unless fs.existsSync(filePath)
filePath = fs.realpathSync(filePath)
return true if filePath.startsWith(Utility.getNoteDirectory())
return true if filePath.startsWith(fs.realpathSync(Utility.getNoteDirectory()))
return false
@trim: (str) -> str?.replace /^\s+|\s+$/g, ''
+4
View File
@@ -9,6 +9,10 @@
'label': 'Toggle'
'command': 'nvatom:toggle'
}
{
'label': 'Open Interlink'
'command': 'nvatom:openInterlink'
}
]
]
}
+12 -6
View File
@@ -1,7 +1,7 @@
{
"name": "nvatom",
"main": "./lib/notational-velocity",
"version": "0.8.1",
"version": "0.10.0",
"private": true,
"contributors": [
"Seongjae Lee <seongjae@gmail.com>",
@@ -9,9 +9,13 @@
"Jonathan Hoyt <hoyt@github.com>"
],
"description": "Notational Velocity for Atom",
"activationCommands": {
"atom-workspace": "nvatom:toggle"
},
"keywords": [
"wiki",
"notational velocity",
"nvatom",
"note",
"notetaking"
],
"repository": "https://github.com/seongjaelee/nvatom",
"license": "MIT",
"engines": {
@@ -24,9 +28,11 @@
"dependencies": {
"atom-space-pen-views": "^2.0.3",
"chokidar": "^1.0.5",
"docquery": "^1.1.0",
"docquery": "^1.1.1",
"fs-plus": "2.x",
"underscore-plus": "^1.6.6"
},
"devDependencies": {}
"devDependencies": {
"temp": "0.8.1"
}
}
+105
View File
@@ -0,0 +1,105 @@
fs = require 'fs-plus'
path = require 'path'
temp = require 'temp'
Interlink = require '../lib/interlink'
temp.track()
describe 'Interlink', ->
defaultDirectory = atom.config.get('nvatom.directory')
noteDirectory = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
noteDirectory = temp.mkdirSync()
atom.config.set('nvatom.directory', noteDirectory)
waitsForPromise ->
atom.packages.activatePackage('nvatom')
afterEach ->
atom.config.set('nvatom.directory', defaultDirectory)
describe 'when getInterlinkUnderCursor is called', ->
editor = null
describe 'under the note directory', ->
beforeEach ->
waitsForPromise ->
atom.workspace.open(path.join(noteDirectory, 'Interlink.md')).then (o) -> editor = o
it 'returns a trimmed interlink text', ->
testdata = [
{ position: [0, 2], text: '[[Car]]', expected: 'Car' },
{ position: [0, 2], text: '[[Notational Velocity]]', expected: 'Notational Velocity' },
{ position: [0, 2], text: '[[한글 Alphabet Test]]', expected: '한글 Alphabet Test' },
{ position: [0, 2], text: '[[ Car ]]', expected: 'Car' },
{ position: [0, 2], text: '[[Car/Mini]]', expected: 'Car/Mini' },
]
for testitem in testdata
editor.setText testitem.text
editor.setCursorBufferPosition testitem.position
expect(Interlink.getInterlinkUnderCursor(editor)).toBe testitem.expected
it 'returns undefined for invalid text', ->
testdata = [
{ position: [0, 2], text: '[[]]' },
{ position: [0, 3], text: '[[]]' },
{ position: [0, 2], text: '[[ ]]' },
{ position: [0, 1], text: '[Car]' },
{ position: [0, 2], text: '[[[Car]]]' },
{ position: [0, 2], text: '[[Car]' },
{ position: [0, 2], text: '[[Car]]]' },
{ position: [0, 1], text: 'Car' },
]
for testitem in testdata
editor.setText testitem.text
editor.setCursorBufferPosition testitem.position
expect(Interlink.getInterlinkUnderCursor(editor)).toBe undefined
describe 'under a random directory', ->
beforeEach ->
waitsForPromise ->
atom.workspace.open(path.join(temp.mkdirSync(), 'Interlink.md')).then (o) -> editor = o
it 'does not apply the grammar', ->
editor.setText '[[Car]]'
editor.setCursorBufferPosition [0, 2]
expect(Interlink.getInterlinkUnderCursor(editor)).toBe undefined
describe 'when openInterlink is called', ->
describe 'when the editor path is under the note directory', ->
editor = null
beforeEach ->
waitsForPromise ->
atom.workspace.open(path.join(noteDirectory, 'Interlink.md')).then (o) -> editor = o
it 'opens the referred notes', ->
editor.setText '[[Car]]'
editor.setCursorBufferPosition [0, 2]
editorPromise = Interlink.openInterlink()
expect(editorPromise).not.toBe undefined
waitsForPromise ->
editorPromise
runs ->
expect(atom.workspace.getActiveTextEditor().getPath().endsWith('Car.md')).toBe true
describe 'when the editor path is not under the note directory', ->
editor = null
beforeEach ->
waitsForPromise ->
atom.workspace.open(path.join(temp.mkdirSync(), 'Interlink.md')).then (o) -> editor = o
it 'does nothing', ->
editor.setText '[[Car]]'
editor.setCursorBufferPosition [0, 2]
editorPromise = Interlink.openInterlink()
expect(editorPromise).toBe undefined
+18 -18
View File
@@ -1,4 +1,7 @@
path = require 'path'
temp = require 'temp'
temp.track()
describe "nvAtom", ->
defaultDirectory = atom.config.get('nvatom.directory')
@@ -7,41 +10,38 @@ describe "nvAtom", ->
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
activationPromise = atom.packages.activatePackage('nvatom')
atom.config.set('nvatom.directory', 'testdata')
afterEach ->
atom.config.set('nvatom.directory', defaultDirectory)
describe "when the nvatom:toggle event is triggered", ->
it "attaches and then detaches the view", ->
expect(workspaceElement.querySelector('.nvatom')).not.toExist()
# This is an activation event, triggering it will cause the package to be activated.
atom.commands.dispatch workspaceElement, 'nvatom:toggle'
noteDirectory = path.join(temp.mkdirSync())
atom.config.set('nvatom.directory', noteDirectory)
waitsForPromise ->
activationPromise
atom.packages.activatePackage('nvatom')
runs ->
expect(workspaceElement.querySelector('.nvatom')).toExist()
expect(workspaceElement.querySelector('.nvatom')).not.toExist()
atom.commands.dispatch workspaceElement, 'nvatom:toggle'
expect(workspaceElement.querySelector('.nvatom')).toExist()
expect(workspaceElement.querySelector('.nvatom').parentNode.style.display).not.toBe 'none'
atom.commands.dispatch workspaceElement, 'nvatom:toggle'
expect(workspaceElement.querySelector('.nvatom').parentNode.style.display).toBe 'none'
it "checks if we banned the default directory under packages directory", ->
atom.notifications.clear()
noteDirectory = path.join(process.env.ATOM_HOME, 'packages', 'nvatom', 'notebook')
atom.config.set('nvatom.directory', noteDirectory)
waitsForPromise ->
atom.packages.activatePackage('notifications')
atom.packages.activatePackage('nvatom')
runs ->
noteDirectoryUnderPackageDirectory = path.join(process.env.ATOM_HOME, 'packages', 'nvatom', 'notebook')
atom.config.set('nvatom.directory', noteDirectoryUnderPackageDirectory)
# This is an activation event, triggering it will cause the package to be activated.
atom.commands.dispatch workspaceElement, 'nvatom:toggle'
waitsForPromise ->
activationPromise
atom.packages.activatePackage('notifications')
runs ->
notificationContainer = workspaceElement.querySelector('atom-notifications')
+54
View File
@@ -0,0 +1,54 @@
fs = require 'fs-plus'
path = require 'path'
temp = require 'temp'
Utility = require '../lib/utility'
temp.track()
describe "utility", ->
defaultNoteDirectory = atom.config.get('nvatom.directory')
defaultNoteExtensions = atom.config.get('nvatom.extensions')
afterEach ->
atom.config.set('nvatom.directory', defaultDirectory)
atom.config.set('nvatom.extensions', defaultNoteExtensions)
describe 'trim', ->
expect(Utility.trim(null)).toBe(undefined)
expect(Utility.trim(undefined)).toBe(undefined)
expect(Utility.trim('')).toBe('')
expect(Utility.trim(' ')).toBe('')
expect(Utility.trim(' hello world ')).toBe('hello world')
expect(Utility.trim(' hello world\t\n\r ')).toBe('hello world')
describe 'getPrimaryNoteExtension', ->
atom.config.set('nvatom.extensions', ['.md', '.markdown'])
expect(Utility.getPrimaryNoteExtension()).toBe('.md')
atom.config.set('nvatom.extensions', ['.markdown'])
expect(Utility.getPrimaryNoteExtension()).toBe('.markdown')
atom.config.set('nvatom.extensions', [])
expect(Utility.getPrimaryNoteExtension()).toBe('.md')
describe 'isNote handles symlinks correctly', ->
atom.config.set('nvatom.extensions', ['.md', '.markdown'])
tempDirectoryPath = path.join(temp.mkdirSync())
noteDirectoryPath = path.join(temp.mkdirSync())
noteDirectoryPathSymlink = path.join(tempDirectoryPath, 'note book')
notePath = path.join(noteDirectoryPath, 'note.md')
notePathSymlink = path.join(noteDirectoryPathSymlink, 'note symlink.md')
fs.writeFileSync(notePath, 'dummy')
fs.symlinkSync(noteDirectoryPath, noteDirectoryPathSymlink)
fs.symlinkSync(notePath, notePathSymlink)
expect(fs.existsSync(notePath)).toBe(true)
expect(fs.existsSync(fs.normalize(notePath))).toBe(true)
atom.config.set('nvatom.directory', noteDirectoryPath)
expect(Utility.isNote(notePath)).toBe(true)
expect(Utility.isNote(notePathSymlink)).toBe(true)
atom.config.set('nvatom.directory', noteDirectoryPathSymlink)
expect(Utility.isNote(notePath)).toBe(true)
expect(Utility.isNote(notePathSymlink)).toBe(true)