Skip to content

Commit

Permalink
Adds support for new note_folder_patterns setting.
Browse files Browse the repository at this point in the history
  • Loading branch information
darryllawson committed Jul 30, 2019
1 parent a8ba626 commit 12682bf
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 33 deletions.
44 changes: 27 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
# Notedown for Sublime Text

Notedown lets you use [Sublime Text](http://sublimetext.com/) to manage a collection of notes stored as [Markdown](https://en.wikipedia.org/wiki/Markdown) files.
Notedown lets you use [Sublime Text](http://sublimetext.com/) to manage notes stored as [Markdown](https://en.wikipedia.org/wiki/Markdown) files.

Out of the box, Sublime Text with its built-in Markdown support is already fairly effective for managing notes. However, it lacks one key feature: **linking between notes**.
Out of the box, Sublime Text with its built-in Markdown support, is already pretty good for managing notes. However, it lacks one key feature: **linking between notes**.

Notedown fills this gap. It allows you to link to another note with this syntax:
Notedown fills this gap. It lets you to link to another note with

```text
[[Note title]]
```

Follow a link with **Ctrl + Alt + Left Mouse Button** or **Ctrl + Alt + O** (the *Notedown: Open Link* command).
Follow a link with **Ctrl + Alt + Left Mouse Button** or by positioning the cursor and pressing **Ctrl + Alt + O** or selecting **Notedown: Open Link** in the command palette.

## Feature
## Features

- **Link to other notes** with this syntax: `[[Note title]]`.
- **Note title auto-completion.** Type `[[` and you will be shown a list of notes you can link to.
- **Note renaming.** Change the Markdown Heading on the first line of the note and the note file will automatically be renamed to match.
- **Open a URL** with the same shortcuts you use for opening a note.
- **Note creation.** Click on a link to a note that does not exist and you'll be prompted to create it.
- **Note link validation.** When you save a note, you'll be shown a list of broken note links.
Features provided by Notedown:

- **Link to another note** with `[[Note title]]`.
- **Note title auto-completion.** Type `[[` and you're shown a list of notes you can link to.
- **Note renaming.** Change the Markdown heading and the note file is automatically renamed to match.
- **Open a URL** conforming to the Markdown syntax with the same shortcuts you use for opening a note.
- **Create a new note** by attempting to open a link to a note that does not exist.
- **Note link validation.** On save, you'll be shown a list of broken note links.

Note keeping features built into Sublime Text:

* **Search for a note** with *Goto Anything* (**Command + P** or **Ctrl + P**).
* **Goto a heading within a note** with *Goto Symbol* (**Command + R** or **Ctrl + R**).

## Note links

Expand Down Expand Up @@ -66,19 +73,22 @@ Any common Markdown file extension -- `.md`, `.mdown`, `.markdown`, or `.markdn`

## Commands

Notedown defines two commands:
Notedown provides these Sublime Text commands:

- **notedown_open_link**: Opens the note link or URL under the cursor or mouse selection.

- Default mouse map: **Ctrl + Alt + Left Mouse Button**
- Default keyboard map: **Ctrl + Alt + O**

- **notedown_lint**: Lints the current file. This is run automatically when a Markdown file is saved.
- **notedown_lint**: Lints the current note. This is run automatically when a note is saved.

## Settings

Notedown looks for settings in `Notedown.sublime-settings`.

## User Settings
Notedown supports these settings:

Notedown looks for user settings in `Notedown.sublime-settings`.
- **markdown_extension**: The file extension used when creating new notes. This should not include a leading period (`.`). If not defined, `md` is used. Example: `"markdown_extension": "markdown"`.

Notedown supports a single user setting:
- **note_folder_patterns**: Defines which folders contain *notes* compatible with Notedown. The folder patterns (which may use wildcards compatible with [fnmatch](https://docs.python.org/3/library/fnmatch.html#fnmatch.fnmatch)) are matched against the name of a Markdown file's containing folder to determine if the file should be considered a note. If not defined or an empty list, then all Markdown files are considered to be notes. Example: `"note_folder_patterns": ["Notes"]`.

- **markdown_extension**: Defines the file extension to use when creating new notes. Do not include a leading period (`.`). If not defined, `md` is used.
58 changes: 42 additions & 16 deletions notedown.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
anyway. Perhaps tags can be supported one day.
"""

import fnmatch
import functools
import os
import re
Expand Down Expand Up @@ -79,10 +80,10 @@ def wrapper(*args, **kwargs):
class _NotedownTextCommand(sublime_plugin.TextCommand):

def is_enabled(self):
return _viewing_markdown(self.view)
return _viewing_a_note(self.view)

def is_visible(self):
return _viewing_markdown(self.view)
return _viewing_a_note(self.view)


class NotedownOpenLinkCommand(_NotedownTextCommand):
Expand Down Expand Up @@ -185,25 +186,27 @@ def on_pre_close(self, view):
pass

def on_post_save_async(self, view):
if not _viewing_markdown(view):
if not _viewing_a_note(view):
return

renamed = self._reflect_title_in_filename(view)
if not renamed:
view.run_command('notedown_lint')

def on_query_completions(self, view, prefix, locations):
if not _viewing_a_note(view):
return False

if not self._can_show_completions(view, locations):
return

file_name = view.file_name()
titles = {y for x in _find_notes(view).values() for y, z in x
if not os.path.samefile(z, file_name)}
return [[x + '\tNote', x + ']]'] for x in sorted(titles)]

def _can_show_completions(self, view, locations):
# To show completions, must be a Markdown view, not in raw scope, and
# [[ has been typed.
if not _viewing_markdown(view):
return False
# Show completions if not in raw scope and [[ has been typed.
point = locations[0]
if view.match_selector(point, 'markup.raw'):
return False
Expand Down Expand Up @@ -318,7 +321,7 @@ def _create_note(title, view):
Returns the filename of the new note or None if the user canceled or
there was an error.
"""
basename = '{}.{}'.format(title, _setting('markdown_extension',
basename = '{}.{}'.format(title, _setting('markdown_extension', str,
_DEFAULT_EXTENSION))
text = 'Do you want to create {}?'.format(basename)
if not sublime.ok_cancel_dialog(text, 'Create File'):
Expand Down Expand Up @@ -356,6 +359,37 @@ def _find_link_regions(view):
return regions


def _viewing_a_note(view):
if not view.match_selector(0, 'text.html.markdown'):
return False

note_folder_patterns = _setting('note_folder_patterns', list)
if not note_folder_patterns:
return True
if any(not isinstance(x, str) for x in note_folder_patterns):
_invalid_setting('note_folder_patterns', note_folder_patterns,
'[str, ...]')
return False

note_folder = os.path.basename(os.path.dirname(view.file_name()))
return any(fnmatch.fnmatch(note_folder, x) for x in note_folder_patterns)


def _setting(name, type_, default=None):
value = sublime.load_settings('Notedown.sublime-settings').get(name,
default)
if value is not default and not isinstance(value, type_):
_invalid_setting(name, value, type_)
return default
else:
return value


def _invalid_setting(name, value, type_):
sublime.error_message('Invalid Notedown setting "{}":\n\n{!r}\n\n'
'Must be of type {}.'.format(name, value, type_))


def _debug_log(message):
if _debug_enabled:
_log(message)
Expand All @@ -366,14 +400,6 @@ def _log(message):
sys.stdout.flush()


def _viewing_markdown(view):
return view.match_selector(0, 'text.html.markdown')


def _setting(name, default=None):
return sublime.load_settings('Notedown.sublime-settings').get(name,
default)

_debug_enabled = False
_notes_cache = {} # {path: (mtime, notes dict)}
_link_regions_cache = {} # {buffer id: (change count, regions)}

0 comments on commit 12682bf

Please sign in to comment.