From b735d26a4ab8fd7f106561a6d727a2e4ed8a5b2b Mon Sep 17 00:00:00 2001 From: deathaxe Date: Mon, 16 Jan 2023 20:00:25 +0100 Subject: [PATCH 1/8] Prepare CHANGELOG --- messages.json | 3 ++- messages/3.1.9.md | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 messages/3.1.9.md diff --git a/messages.json b/messages.json index 55d95510..f0a249b6 100644 --- a/messages.json +++ b/messages.json @@ -42,5 +42,6 @@ "3.1.5": "messages/3.1.5.md", "3.1.6": "messages/3.1.6.md", "3.1.7": "messages/3.1.7.md", - "3.1.8": "messages/3.1.8.md" + "3.1.8": "messages/3.1.8.md", + "3.1.9": "messages/3.1.9.md" } diff --git a/messages/3.1.9.md b/messages/3.1.9.md new file mode 100644 index 00000000..d7b86fa5 --- /dev/null +++ b/messages/3.1.9.md @@ -0,0 +1,12 @@ +# MarkdownEditing 3.1.9 Changelog + +Your _MarkdownEditing_ plugin is updated. Enjoy new version. For any type of +feedback you can use [GitHub issues][issues]. + +## Bug Fixes + +## New Features + +## Changes + +[issues]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues From 91cc587eb318079567540be7ba6134808d191561 Mon Sep 17 00:00:00 2001 From: deathaxe Date: Sat, 14 Jan 2023 17:10:01 +0100 Subject: [PATCH 2/8] Syntax: Fix name conflict with default Markdown syntax MarkdownEditing's syntaxes are hidden and a Markdown.sublime-package is created in Installed Packages folder to augment ST's default Markdown. It looks as MDE's markdown is the default one so all 3rd-party packages inheriting from it can continue working with a single Markdown syntax in the town. --- messages/3.1.9.md | 8 ++ plugin.py | 7 +- plugins/bootstrap.py | 159 ++++++++++++++------------ syntaxes/Markdown.sublime-syntax | 7 +- syntaxes/MultiMarkdown.sublime-syntax | 1 + 5 files changed, 99 insertions(+), 83 deletions(-) diff --git a/messages/3.1.9.md b/messages/3.1.9.md index d7b86fa5..2522b084 100644 --- a/messages/3.1.9.md +++ b/messages/3.1.9.md @@ -5,8 +5,16 @@ feedback you can use [GitHub issues][issues]. ## Bug Fixes +* Fix duplicate Markdown syntaxes (#717) + ## New Features ## Changes +* MarkdownEditing no longer disables but augoments ST's default Markdown + package. Hence you'll no longer find MarkdownEditing/Markdown syntax. + + This change is required to properly support 3rd-party packages which + extend default Markdown syntax in ST4. + [issues]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues diff --git a/plugin.py b/plugin.py index 7661da7e..77c5ada4 100644 --- a/plugin.py +++ b/plugin.py @@ -110,8 +110,11 @@ ) def plugin_loaded(): - load_logger() - on_after_install() + def worker(): + load_logger() + on_after_install() + + sublime.set_timeout(worker, 10) def plugin_unloaded(): unload_logger() diff --git a/plugins/bootstrap.py b/plugins/bootstrap.py index 0fba5ee2..fc24d1dd 100644 --- a/plugins/bootstrap.py +++ b/plugins/bootstrap.py @@ -8,85 +8,97 @@ BOOTSTRAP_VERSION = "3.0.3" -package_name = "MarkdownEditing" +package_name = __package__.split(".")[0] -def get_ingored_packages(): - settings = sublime.load_settings("Preferences.sublime-settings") - return settings.get("ignored_packages") or [] - - -def save_ingored_packages(ignored_packages): - settings = sublime.load_settings("Preferences.sublime-settings") - settings.set("ignored_packages", ignored_packages) - sublime.save_settings("Preferences.sublime-settings") - - -def disable_native_markdown_package(): - ignored_packages = get_ingored_packages() - if "Markdown" not in ignored_packages: - ignored_packages.append("Markdown") - save_ingored_packages(ignored_packages) - - -def enable_native_markdown_package(): - ignored_packages = get_ingored_packages() - if "Markdown" in ignored_packages: - ignored_packages.remove("Markdown") - save_ingored_packages(ignored_packages) - - def reassign(): - reassign_syntax( - "Markdown.sublime-syntax", - "Packages/Markdown/Markdown.sublime-syntax", - ) - reassign_syntax( - "MultiMarkdown.sublime-syntax", - "Packages/Markdown/MultiMarkdown.sublime-syntax", - ) - - sublime.set_timeout(reassign, 100) - - -def reassign_syntax(current_syntax, new_syntax): - for window in sublime.windows(): - for view in window.views(): - syntax = view.settings().get("syntax") - if syntax and syntax.endswith(current_syntax) and syntax != new_syntax: - view.assign_syntax(new_syntax) +def augment_default_markdown(): + """ + Augment ST's default Markdown.sublime-package with MDE's syntaxes. + As of ST 4134 builtin Markdown syntax can be used as base syntax for various packages. + Hence disabling default package may break at least HAML, Astro, Liquid and probably more. -def bootstrap_syntax_assignments(): + To avoid that from happening, MDE creates a Markdown.sublime-package to completely + override default package instead. This step prevents MarkdownEditing from extending + default Markdown syntax, but it's probably the most safest way to provide all its + benefits (additional fenced code blocks) to all other 3rd-party packages. """ - Reassign syntax to all open Markdown, MultiMarkdown or Plain Text files. - Repair syntax assignments of open views after install or upgrade, in case - old ones no longer exist. - """ - markdown = "Packages/MarkdownEditing/syntaxes/Markdown.sublime-syntax" - multimarkdown = "Packages/MarkdownEditing/syntaxes/MultiMarkdown.sublime-syntax" - - for window in sublime.windows(): - for view in window.views(): - syntax = view.settings().get("syntax") - if syntax: - syntax = os.path.basename(syntax) - if syntax in ("Markdown.tmLanguage", "Markdown.sublime-syntax"): - view.assign_syntax(markdown) - continue - if syntax in ("MultiMarkdown.tmLanguage", "MultiMarkdown.sublime-syntax"): - view.assign_syntax(multimarkdown) - continue - - file_name = view.file_name() - if file_name: - _, ext = os.path.splitext(file_name) - if ext in (".md", ".mdown", ".markdown"): - view.assign_syntax(markdown) + dst_path = os.path.join(sublime.installed_packages_path(), "Markdown.sublime-package") + if os.path.isfile(dst_path): + return + + from textwrap import dedent + from zipfile import ZipFile, ZIP_DEFLATED + + def load_res(syntax): + return ( + sublime.load_resource("/".join(("Packages", package_name, "syntaxes", syntax))) + .replace("\r\n", "\n") + .replace("\r", "\n") + ) + + tmp_path = os.path.join(sublime.installed_packages_path(), "Markdown.tmp") + with ZipFile(tmp_path, "w", compression=ZIP_DEFLATED) as pkg: + # copy unhidden Markdown syntax and assign default file extensions + pkg.writestr( + "Markdown.sublime-syntax", + load_res("Markdown.sublime-syntax").replace( + "\nhidden: true\n", + dedent( + """ + + file_extensions: + - md + - mdown + - markdown + - markdn + """ + ), + ), + ) + # copy unhidden MultiMarkdown syntax + pkg.writestr( + "MultiMarkdown.sublime-syntax", + load_res("MultiMarkdown.sublime-syntax").replace("\nhidden: true\n", "\n"), + ) + pkg.writestr( + "Shell (for Markdown).sublime-syntax", + load_res("Shell (for Markdown).sublime-syntax"), + ) + pkg.writestr( + "README.md", + dedent( + """ + NOTE + ==== + + This file is auto generated by MarkdownEditing + to augment ST's default Markdown syntax. + """ + ).lstrip(), + ) + os.rename(tmp_path, dst_path) + + prefs = sublime.load_settings("Preferences.sublime-settings") + ignored = prefs.get("ignored_packages", []) + if ignored and "Markdown" in ignored: + ignored.remove("Markdown") + prefs.set("ignored_packages", ignored) + sublime.save_settings("Preferences.sublime-settings") + + +def restore_default_markdown(): + try: + os.remove(os.path.join(sublime.installed_packages_path(), "Markdown.sublime-package")) + except OSError: + pass def on_after_install(): - cache_path = os.path.join(sublime.cache_path(), "MarkdownEditing") + augment_default_markdown() + + cache_path = os.path.join(sublime.cache_path(), package_name) bootstrapped = os.path.join(cache_path, "bootstrapped") # Check bootstrapped cookie. @@ -101,8 +113,6 @@ def on_after_install(): os.makedirs(cache_path, exist_ok=True) def async_worker(): - bootstrap_syntax_assignments() - disable_native_markdown_package() clear_invalid_color_schemes() # Update bootstrap cookie. open(bootstrapped, "w").write(BOOTSTRAP_VERSION) @@ -113,11 +123,10 @@ def async_worker(): def on_before_uninstall(): + restore_default_markdown() + if "package_control" in sys.modules: from package_control import events if events.remove(package_name): - # Native package causes some conflicts. - enable_native_markdown_package() - # Remove syntax specific color schemes. clear_color_schemes() diff --git a/syntaxes/Markdown.sublime-syntax b/syntaxes/Markdown.sublime-syntax index f9eb9cab..0d6ab72b 100644 --- a/syntaxes/Markdown.sublime-syntax +++ b/syntaxes/Markdown.sublime-syntax @@ -11,12 +11,7 @@ # to help make this syntax definition easier to maintain. name: Markdown scope: text.html.markdown - -file_extensions: - - md - - mdown - - markdown - - markdn +hidden: true variables: atx_heading: (?:[ ]{,3}[#]{1,6}(?:[ \t]|$)) # between 0 and 3 spaces, followed 1 to 6 hashes, followed by at least one space or tab or by end of the line diff --git a/syntaxes/MultiMarkdown.sublime-syntax b/syntaxes/MultiMarkdown.sublime-syntax index ca9be2d0..d56a3803 100644 --- a/syntaxes/MultiMarkdown.sublime-syntax +++ b/syntaxes/MultiMarkdown.sublime-syntax @@ -2,6 +2,7 @@ --- name: MultiMarkdown scope: text.html.markdown.multimarkdown +hidden: true first_line_match: (?i:^format:\s*complete\s*$) From 8637180538efb93df1c9d02ada0f3ca40ddae7f8 Mon Sep 17 00:00:00 2001 From: deathaxe Date: Sat, 14 Jan 2023 20:42:03 +0100 Subject: [PATCH 3/8] Plugins: Improve Fold/Unfold section key bindings This commit replaces "Toggle Folding Current Section" via `shift+tab` by separate fold/unfold commands bound to default key combinations. - `primary+shift+[` => `mde_fold_section` => fold current section - `primary+shift+]` => `mde_unfold_section` => unfold current section Fixes conflicts with `shift+tab` being also used to unindent text, which caused unexpected folding in various situations. --- Context.sublime-menu | 4 +- Default (Linux).sublime-keymap | 14 ++-- Default (OSX).sublime-keymap | 14 ++-- Default (Windows).sublime-keymap | 14 ++-- Default.sublime-commands | 6 +- docs/usage.md | 18 +++-- messages/3.1.9.md | 4 + plugin.py | 3 +- plugins/folding.py | 126 +++++++++++++++---------------- tests/test_folding.py | 18 ++--- 10 files changed, 112 insertions(+), 109 deletions(-) diff --git a/Context.sublime-menu b/Context.sublime-menu index ed8863dd..ac76a944 100644 --- a/Context.sublime-menu +++ b/Context.sublime-menu @@ -9,11 +9,11 @@ }, { "caption": "Fold Section", - "command": "mde_fold_section_context" + "command": "mde_fold_section" }, { "caption": "Unfold Section", - "command": "mde_unfold_section_context" + "command": "mde_unfold_section" }, { "caption": "-", diff --git a/Default (Linux).sublime-keymap b/Default (Linux).sublime-keymap index 80dadf5c..36831845 100644 --- a/Default (Linux).sublime-keymap +++ b/Default (Linux).sublime-keymap @@ -678,24 +678,20 @@ { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw", "match_all": true } ] }, - { "keys": ["shift+tab"], "command": "mde_fold_section", "context": + { "keys": ["ctrl+shift+["], "command": "mde_fold_section", "context": [ { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw - markup.list", "match_all": true }, { "key": "setting.mde.keymap_disable.fold_section", "operator": "not_equal", "operand": true }, - { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, { "key": "has_prev_field", "operator": "equal", "operand": false }, - { "key": "overlay_visible", "operator": "equal", "operand": false }, - { "key": "preceding_text", "operator": "not_regex_match", "operand": "^\\s+", "match_all": true } + { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, - { "keys": ["shift+tab"], "command": "mde_fold_section", "context": + { "keys": ["ctrl+shift+]"], "command": "mde_unfold_section", "context": [ - { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw - markup.list", "match_all": true }, { "key": "setting.mde.keymap_disable.fold_section", "operator": "not_equal", "operand": true }, - { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }, { "key": "has_prev_field", "operator": "equal", "operand": false }, - { "key": "overlay_visible", "operator": "equal", "operand": false }, - { "key": "text", "operator": "regex_contains", "operand": "^(#{1,6}(?!#))|^(-{3,}|={3,})$"} + { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, { "keys": ["ctrl+shift+tab"], "command": "mde_show_fold_all_sections", "context": diff --git a/Default (OSX).sublime-keymap b/Default (OSX).sublime-keymap index a91df2fb..7b046b58 100644 --- a/Default (OSX).sublime-keymap +++ b/Default (OSX).sublime-keymap @@ -678,24 +678,20 @@ { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw", "match_all": true } ] }, - { "keys": ["shift+tab"], "command": "mde_fold_section", "context": + { "keys": ["super+shift+["], "command": "mde_fold_section", "context": [ { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw - markup.list", "match_all": true }, { "key": "setting.mde.keymap_disable.fold_section", "operator": "not_equal", "operand": true }, - { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, { "key": "has_prev_field", "operator": "equal", "operand": false }, - { "key": "overlay_visible", "operator": "equal", "operand": false }, - { "key": "preceding_text", "operator": "not_regex_match", "operand": "^\\s+", "match_all": true } + { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, - { "keys": ["shift+tab"], "command": "mde_fold_section", "context": + { "keys": ["super+shift+]"], "command": "mde_unfold_section", "context": [ - { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw - markup.list", "match_all": true }, { "key": "setting.mde.keymap_disable.fold_section", "operator": "not_equal", "operand": true }, - { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }, { "key": "has_prev_field", "operator": "equal", "operand": false }, - { "key": "overlay_visible", "operator": "equal", "operand": false }, - { "key": "text", "operator": "regex_contains", "operand": "^(#{1,6}(?!#))|^(-{3,}|={3,})$"} + { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, { "keys": ["ctrl+shift+tab"], "command": "mde_show_fold_all_sections", "context": diff --git a/Default (Windows).sublime-keymap b/Default (Windows).sublime-keymap index 80dadf5c..36831845 100644 --- a/Default (Windows).sublime-keymap +++ b/Default (Windows).sublime-keymap @@ -678,24 +678,20 @@ { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw", "match_all": true } ] }, - { "keys": ["shift+tab"], "command": "mde_fold_section", "context": + { "keys": ["ctrl+shift+["], "command": "mde_fold_section", "context": [ { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw - markup.list", "match_all": true }, { "key": "setting.mde.keymap_disable.fold_section", "operator": "not_equal", "operand": true }, - { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, { "key": "has_prev_field", "operator": "equal", "operand": false }, - { "key": "overlay_visible", "operator": "equal", "operand": false }, - { "key": "preceding_text", "operator": "not_regex_match", "operand": "^\\s+", "match_all": true } + { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, - { "keys": ["shift+tab"], "command": "mde_fold_section", "context": + { "keys": ["ctrl+shift+]"], "command": "mde_unfold_section", "context": [ - { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.raw - markup.list", "match_all": true }, { "key": "setting.mde.keymap_disable.fold_section", "operator": "not_equal", "operand": true }, - { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }, { "key": "has_prev_field", "operator": "equal", "operand": false }, - { "key": "overlay_visible", "operator": "equal", "operand": false }, - { "key": "text", "operator": "regex_contains", "operand": "^(#{1,6}(?!#))|^(-{3,}|={3,})$"} + { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, { "keys": ["ctrl+shift+tab"], "command": "mde_show_fold_all_sections", "context": diff --git a/Default.sublime-commands b/Default.sublime-commands index 321c7862..52864992 100644 --- a/Default.sublime-commands +++ b/Default.sublime-commands @@ -146,9 +146,13 @@ // { - "caption": "MarkdownEditing: Toggle Folding Current Section", + "caption": "MarkdownEditing: Fold Current Section", "command": "mde_fold_section" }, + { + "caption": "MarkdownEditing: Unold Current Section", + "command": "mde_unfold_section" + }, { "caption": "MarkdownEditing: Fold Level 1 Sections", "command": "mde_fold_all_sections", diff --git a/docs/usage.md b/docs/usage.md index d34aa985..c8fe0476 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -133,14 +133,21 @@ Adding or removing `#` at the beginning of lines also modifies heading levels im Irrelevant sections of documents can be folded/collapsed via Command Palette: -* **MarkdownEditing: Toggle Folding Current Section** - Whether child sections are folded or unfolded as well depends on folding level defined by calling one of the following commands. +* **MarkdownEditing: Fold Current Section** + Whether child sections are folded depends on folding level defined by calling one of the following commands. - If `Fold All Sections` was called before _("outline mode" is active)_, the region between current and following sibling or child heading is (un)folded only. + If `Fold All Sections` was called before _("outline mode" is active)_, the region between current and following sibling or child heading is folded only. + + If `Unfold All Sections` was called before, all child sections are folded. + +* **MarkdownEditing: Unfold Current Section** + Whether child sections are unfolded depends on folding level defined by calling one of the following commands. + + If `Fold All Sections` was called before _("outline mode" is active)_, the region between current and following sibling or child heading is unfolded only. If `Fold Level 1-6 Sections` was called before, all child sections with lower level keep folded when unfolding their parent section. - If `Unfold All Sections` was called before, all child sections are (un)folded. + If `Unfold All Sections` was called before, all child sections are unfolded. * **MarkdownEditing: Fold Level 1-6 Sections** Folds all sections of headings of specific level. Also hides lower level headings. @@ -158,7 +165,8 @@ Folding is bound to following keys by default: | Ctrl + k, Ctrl + 0 | + k, + 0 | Unfold all sections | Ctrl + k, Ctrl + 1..6 | + k, + 1..6 | Fold sections by level 1..6 | Ctrl + k, Ctrl + 9 | + k, + 9 | Fold all sections, but keep headings of any level visible -| Shift + Tab | + Tab | Fold/Unfold current section. +| Ctrl + Shift + [ | ^ + + Tab | Fold current section. +| Ctrl + Shift + ] | ^ + + Tab | Unfold current section. | Ctrl + Shift + Tab | ^ + + Tab | Fold all sections under headings of a certain level. ## Automatic Link Url Folding diff --git a/messages/3.1.9.md b/messages/3.1.9.md index 2522b084..568f8cf5 100644 --- a/messages/3.1.9.md +++ b/messages/3.1.9.md @@ -17,4 +17,8 @@ feedback you can use [GitHub issues][issues]. This change is required to properly support 3rd-party packages which extend default Markdown syntax in ST4. +* Replace "Toggle Folding Current Section" via shift+tab by + - "Fold Current Section" via ctrl+shift+[ + - "Unfold Current Section" via ctrl+shift+] + [issues]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues diff --git a/plugin.py b/plugin.py index 77c5ada4..18ce880d 100644 --- a/plugin.py +++ b/plugin.py @@ -32,10 +32,9 @@ MdeFoldLinksCommand, MdeFoldLinksListener, MdeFoldSectionCommand, - MdeFoldSectionContextCommand, MdeShowFoldAllSectionsCommand, MdeUnfoldAllSectionsCommand, - MdeUnfoldSectionContextCommand, + MdeUnfoldSectionCommand, ) from .plugins.footnotes import ( MdeGatherMissingFootnotesCommand, diff --git a/plugins/folding.py b/plugins/folding.py index f5440d9d..ca66c124 100644 --- a/plugins/folding.py +++ b/plugins/folding.py @@ -208,7 +208,7 @@ class MdeFoldSectionCommand(MdeTextCommand): """ This class describes a `mde_fold_section` command. - The command folds or unfolds sections at least one caret is within. + The command folds sections at least one caret is within. It's behavior depends on former call of `mde_fold_all_secitons` command and the active `mde.folding.target_level` setting respectively. @@ -222,98 +222,98 @@ class MdeFoldSectionCommand(MdeTextCommand): keep folded if their parent section is unfolded. """ - def description(self): - return "Toggle fold/unfold on current section" + def is_enabled(self): + view = self.view + target_level = folding_target_level(view) + for sel in view.sel(): + section, _ = section_region_and_level(view, sel.a, target_level) + if section: + return not bool(folded_region(view, section)) + return False def run(self, edit): view = self.view target_level = folding_target_level(view) sections = [] - levels = [] - unfold = False for sel in view.sel(): if any(s.contains(sel) for s in sections): continue - section, level = section_region_and_level(view, sel.begin(), target_level) + section, _ = section_region_and_level(view, sel.begin(), target_level) if not section: continue folded_section = folded_region(view, section) - if folded_section: - if folded_section != section: - level = section_level(view, folded_section.begin()) - sections.append(folded_section) - unfold = True - else: + if not folded_section: sections.append(section) - levels.append(level) - - if unfold: - regions_to_fold = [] - if target_level > -1: - # keep all child sections folded - for section, level in zip(sections, levels): - regions_to_fold.extend( - sections_to_fold(view, section, max(target_level, level + 1)) - ) - else: - for section in sections: - regions_to_fold.extend(sections_to_fold(view, section, -1)) - - view.unfold(sections) - view.fold(regions_to_fold + urls_to_fold(view)) - else: - view.fold(sections) + view.fold(sections) sublime.status_message( - "{} region{} {}folded".format( - len(sections), "s" if len(sections) > 1 else "", "un" if unfold else "" - ) + "{} region{} folded".format(len(sections), "s" if len(sections) > 1 else "") ) -class MdeFoldSectionContextCommand(MdeFoldSectionCommand): +class MdeUnfoldSectionCommand(MdeTextCommand): """ - This class describes a `mde_fold_section_context` command. + This class describes a `mde_unfold_section` command. + + The command unfolds sections at least one caret is within. + + It's behavior depends on former call of `mde_fold_all_secitons` command and + the active `mde.folding.target_level` setting respectively. + + -1: The whole section, including all child sections is folded and unfolded. + The folded region begins after the nearest heading found before a caret's + position and ends with the next heading of same level after the caret. + 0: The region between two the headings enclosing the caret's position + is folded or unfolded. That's the so called outline mode. + >0: Like (-1) but all child sections of higher level then `target_level` + keep folded if their parent section is unfolded. """ - def is_visible(self): - if not super().is_visible(): - return False + def is_enabled(self): view = self.view target_level = folding_target_level(view) - hasSection = False for sel in view.sel(): section, _ = section_region_and_level(view, sel.a, target_level) if section: - folded = folded_region(view, section) - if folded: - return False - else: - hasSection = True - return hasSection + return bool(folded_region(view, section)) + return False - -class MdeUnfoldSectionContextCommand(MdeFoldSectionCommand): - """ - This class describes a `mde_unfold_section_context` command. - """ - - def is_visible(self): - if not super().is_visible(): - return False + def run(self, edit): view = self.view target_level = folding_target_level(view) - hasSection = False + sections = [] + levels = [] for sel in view.sel(): - section, _ = section_region_and_level(view, sel.a, target_level) - if section: - folded = folded_region(view, section) - if folded: - hasSection = True - else: - return False - return hasSection + if any(s.contains(sel) for s in sections): + continue + section, level = section_region_and_level(view, sel.begin(), target_level) + if not section: + continue + folded_section = folded_region(view, section) + if folded_section: + if folded_section != section: + level = section_level(view, folded_section.begin()) + sections.append(folded_section) + levels.append(level) + + regions_to_fold = [] + if target_level > -1: + # keep all child sections folded + for section, level in zip(sections, levels): + regions_to_fold.extend( + sections_to_fold(view, section, max(target_level, level + 1)) + ) + else: + for section in sections: + regions_to_fold.extend(sections_to_fold(view, section, -1)) + + view.unfold(sections) + view.fold(regions_to_fold + urls_to_fold(view)) + + sublime.status_message( + "{} region{} unfolded".format(len(sections), "s" if len(sections) > 1 else "") + ) class MdeShowFoldAllSectionsCommand(MdeTextCommand): diff --git a/tests/test_folding.py b/tests/test_folding.py index 8972e295..4c78d62c 100644 --- a/tests/test_folding.py +++ b/tests/test_folding.py @@ -158,7 +158,7 @@ def _test_fold_section__heading_1(self, row, col): self.assertFoldedRegions([(11, 470)]) # unfold heading - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([(37, 52), (184, 199), (367, 382), (417, 432)]) # setup test @@ -170,7 +170,7 @@ def _test_fold_section__heading_1(self, row, col): self.assertFoldedRegions([(11, 470)]) # unfold heading - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([]) # test folding and unfolding setext heading level 1 @@ -204,7 +204,7 @@ def _test_fold_section__heading_3(self, row, col): self.assertFoldedRegions([(522, 610)]) # unfold heading - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([]) # test folding and unfolding setext heading level 2 @@ -238,7 +238,7 @@ def _test_fold_section__heading_3_1(self, row, col): self.assertFoldedRegions([(547, 567)]) # unfold heading - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([]) # test folding and unfolding by level @@ -466,7 +466,7 @@ def _test_unfold_section__heading_x_with_folding_tartet_level_0(self, row, expec # unfold heading self.setCaretTo(row, 1) - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions(expected_regions) # fold heading @@ -494,7 +494,7 @@ def test_unfold_section__heading_1_with_folding_tartet_level_1(self): # unfold "1 Heading" with caret before folding marker self.setCaretTo(1, 11) - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([ (37, 52), (98, 357), @@ -518,7 +518,7 @@ def test_unfold_section__heading_1_with_folding_tartet_level_1(self): # unfold "1 Heading" with caret after folding marker self.setCaretTo(40, 1) - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([ (37, 52), (98, 357), @@ -532,7 +532,7 @@ def test_unfold_section__heading_1_with_folding_tartet_level_1(self): # unfold "1.1 Heading" self.setCaretTo(9, 9) - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([ (37, 52), (117, 274), @@ -547,7 +547,7 @@ def test_unfold_section__heading_1_with_folding_tartet_level_1(self): # unfold "1.1.2 Heading" self.setCaretTo(25, 9) - self.view.run_command("mde_fold_section") + self.view.run_command("mde_unfold_section") self.assertFoldedRegions([ (37, 52), (117, 274), From 4ccf6b349e5b2b9ffc8d4071991488b76c0f168c Mon Sep 17 00:00:00 2001 From: deathaxe Date: Mon, 16 Jan 2023 18:58:02 +0100 Subject: [PATCH 4/8] Plugins: Fix possible None object access --- plugins/folding.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/folding.py b/plugins/folding.py index ca66c124..ac6060a1 100644 --- a/plugins/folding.py +++ b/plugins/folding.py @@ -322,10 +322,11 @@ class MdeShowFoldAllSectionsCommand(MdeTextCommand): """ def run(self, edit): - view = self.view - view.window().run_command( - "show_overlay", {"overlay": "command_palette", "text": "MarkdownEditing: Fold"} - ) + window = self.view.window() + if window: + window.run_command( + "show_overlay", {"overlay": "command_palette", "text": "MarkdownEditing: Fold"} + ) class MdeFoldAllSectionsCommand(MdeTextCommand): From 8aacaabe9a47bfb1b38aff9da338d6da691a30fd Mon Sep 17 00:00:00 2001 From: deathaxe Date: Sun, 15 Jan 2023 21:18:56 +0100 Subject: [PATCH 5/8] Docs: Add Github link --- mkdocs.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index d391bcf6..8b9e7243 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -45,6 +45,11 @@ markdown_extensions: custom_checkbox: true - pymdownx.progressbar: - pymdownx.arithmatex: + - pymdownx.magiclink: + repo_url_shortener: true + repo_url_shorthand: true + user: SublimeText-Markdown + repo: MarkdownEditing - pymdownx.mark: - pymdownx.tilde: - pymdownx.striphtml: From 44cd51fa2c8727c9d93b5485e1121dca73f0980a Mon Sep 17 00:00:00 2001 From: Luis Puerto Date: Sun, 6 Nov 2022 22:34:51 +0100 Subject: [PATCH 6/8] Remove blank spaces critic markup snippets --- messages/3.1.9.md | 1 + snippets/Critic Addition.sublime-snippet | 2 +- snippets/Critic Comment.sublime-snippet | 2 +- snippets/Critic Deletion.sublime-snippet | 2 +- snippets/Critic Highlight.sublime-snippet | 2 +- snippets/Critic Substitution.sublime-snippet | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/messages/3.1.9.md b/messages/3.1.9.md index 568f8cf5..2f027544 100644 --- a/messages/3.1.9.md +++ b/messages/3.1.9.md @@ -5,6 +5,7 @@ feedback you can use [GitHub issues][issues]. ## Bug Fixes +* Remove blank spaces critic markup snippets (#711) * Fix duplicate Markdown syntaxes (#717) ## New Features diff --git a/snippets/Critic Addition.sublime-snippet b/snippets/Critic Addition.sublime-snippet index b39db20d..b7080252 100644 --- a/snippets/Critic Addition.sublime-snippet +++ b/snippets/Critic Addition.sublime-snippet @@ -1,5 +1,5 @@ - + text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.critic - meta.code-fence - markup.raw - markup.kbd Markdown Critic Addition \ No newline at end of file diff --git a/snippets/Critic Comment.sublime-snippet b/snippets/Critic Comment.sublime-snippet index 1bf92bc4..6c9c249c 100644 --- a/snippets/Critic Comment.sublime-snippet +++ b/snippets/Critic Comment.sublime-snippet @@ -1,5 +1,5 @@ - > ${1:$SELECTION} <<}]]> + >${1:$SELECTION}<<}]]> text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.critic - meta.code-fence - markup.raw - markup.kbd Markdown Critic Comment diff --git a/snippets/Critic Deletion.sublime-snippet b/snippets/Critic Deletion.sublime-snippet index 8d708c9f..19004dce 100644 --- a/snippets/Critic Deletion.sublime-snippet +++ b/snippets/Critic Deletion.sublime-snippet @@ -1,5 +1,5 @@ - + text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.critic - meta.code-fence - markup.raw - markup.kbd Markdown Critic Deletion \ No newline at end of file diff --git a/snippets/Critic Highlight.sublime-snippet b/snippets/Critic Highlight.sublime-snippet index 6ae1d3d1..5cce39ec 100644 --- a/snippets/Critic Highlight.sublime-snippet +++ b/snippets/Critic Highlight.sublime-snippet @@ -1,5 +1,5 @@ - > ${1:comment} <<}]]> + >${1:comment}<<}]]> text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.critic - meta.code-fence - markup.raw - markup.kbd Markdown Critic Highlight \ No newline at end of file diff --git a/snippets/Critic Substitution.sublime-snippet b/snippets/Critic Substitution.sublime-snippet index 07aa7fd3..a71dca9e 100644 --- a/snippets/Critic Substitution.sublime-snippet +++ b/snippets/Critic Substitution.sublime-snippet @@ -1,5 +1,5 @@ - ${1:substitution} ~~}]]> + ${1:substitution}~~}]]> text.html.markdown - meta.frontmatter - meta.disable-markdown - markup.critic - meta.code-fence - markup.raw - markup.kbd Markdown Critic Substitution \ No newline at end of file From 2794ea2ab939239d8bf0ffc0b2a2f382c4933e26 Mon Sep 17 00:00:00 2001 From: deathaxe Date: Mon, 16 Jan 2023 20:19:22 +0100 Subject: [PATCH 7/8] CI: Update workflows --- .github/workflows/ci-lint.yml | 4 ++-- .github/workflows/ci-syntax-tests.yml | 4 ++-- .github/workflows/ci-unit-tests.yml | 4 ++-- .github/workflows/deploy-gh-pages.yml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml index 98ede269..f1ed944b 100644 --- a/.github/workflows/ci-lint.yml +++ b/.github/workflows/ci-lint.yml @@ -31,9 +31,9 @@ jobs: - 'x64' steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python }} architecture: ${{ matrix.arch }} diff --git a/.github/workflows/ci-syntax-tests.yml b/.github/workflows/ci-syntax-tests.yml index 70ee8407..3150bae0 100644 --- a/.github/workflows/ci-syntax-tests.yml +++ b/.github/workflows/ci-syntax-tests.yml @@ -23,7 +23,7 @@ on: jobs: syntax_tests: name: Sublime Text ${{ matrix.build }} - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 15 # default is 6 hours! strategy: matrix: @@ -35,7 +35,7 @@ jobs: - build: latest default_packages: master steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: SublimeText/syntax-test-action@v2 with: build: ${{ matrix.build }} diff --git a/.github/workflows/ci-unit-tests.yml b/.github/workflows/ci-unit-tests.yml index ac41b184..c80431b9 100644 --- a/.github/workflows/ci-unit-tests.yml +++ b/.github/workflows/ci-unit-tests.yml @@ -21,14 +21,14 @@ on: jobs: test: name: Sublime Text ${{ matrix.st-version }} - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 15 # default is 6 hours! strategy: fail-fast: false matrix: st-version: [3, 4] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: SublimeText/UnitTesting/actions/setup@v1 with: sublime-text-version: ${{ matrix.st-version }} diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml index e3eba1b4..24a3c5cc 100644 --- a/.github/workflows/deploy-gh-pages.yml +++ b/.github/workflows/deploy-gh-pages.yml @@ -11,10 +11,10 @@ on: jobs: build: name: Deploy Docs to Github Pages - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Set up Python From d9d5230d16c53178eff49293b6a233b4c45267ff Mon Sep 17 00:00:00 2001 From: deathaxe Date: Fri, 20 Jan 2023 19:24:20 +0100 Subject: [PATCH 8/8] Update release script Publish a single release only! --- make.cmd | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/make.cmd b/make.cmd index eae1a555..1a9429f3 100644 --- a/make.cmd +++ b/make.cmd @@ -52,17 +52,7 @@ goto :usage :RELEASE if "%2"== "" goto :usage - set st3_changelog=release-st3-%2.md - set st4_changelog=release-st4-%2.md - if not exist "messages/%st3_changelog%" ( - echo Missing %st3_changelog% - exit /b 1 - ) - if not exist "messages/%st4_changelog%" ( - echo Missing %st4_changelog% - exit /b 1 - ) git checkout st3176 && git merge st3-develop --no-ff if not errorlevel 0 ( echo Unable to merge st3-develop into st3176! @@ -85,12 +75,29 @@ goto :usage echo Failed to push master! exit /b 1 ) - echo Hit any key to publish release! - pause - : create release for ST3 - gh release create --target st3176 -t "MarkdownEditing %2 (ST3176+)" -F "messages/%st3_changelog%" "3176-%2" - : create release for ST3 - gh release create --target master -t "MarkdownEditing %2 (ST4107+)" -F "messages/%st4_changelog%" "4107-%2" + + for %%d in ("%~dp0.") do set package=%%~nxd + + echo Createing assets for "%package%"... + + :: create downloadable asset for ST4126+ + set build=3176 + set archive=%package%-%2-st%build%.sublime-package + set assets="%archive%#%archive%" + call git tag -f %build%-%2 st%build% + call git archive --format zip -o "%archive%" %build%-%2 + + :: create downloadable asset for ST4134+ + set build=4107 + set archive=%package%-%2-st%build%.sublime-package + set assets=%assets% "%archive%#%archive%" + call git tag -f %build%-%2 master + call git archive --format zip -o "%archive%" %build%-%2 + + :: create the release + call git push --tags --force + gh release create --target master -t "%package% %2" "%2" %assets% + del /f /q *.sublime-package git fetch goto :eof