<commit_before>import os.path
import sublime
import sublime_plugin

from functools import partial

from .markdown2html import markdown2html
from .utils import *

MARKDOWN_VIEW_INFOS = "markdown_view_infos"
PREVIEW_VIEW_INFOS = "preview_view_infos"
# FIXME: put this as a setting for the user to choose?
DELAY = 100 # ms

def get_resource(resource):
    path = 'Packages/MarkdownLivePreview/resources/' + resource
    abs_path = os.path.join(sublime.packages_path(), '..', path)
    if os.path.isfile(abs_path):
        with open(abs_path, 'r') as fp:
            return fp.read()
    return sublime.load_resource(path)

resources = {}

def plugin_loaded():
    resources["base64_loading_image"] = get_resource('loading.base64')
    resources["base64_404_image"] = get_resource('404.base64')
    resources["stylesheet"] = get_resource('stylesheet.css')

# try to reload the resources if we save this file
try:
    plugin_loaded()
except OSError:
    pass

# Terminology
# original_view: the view in the regular editor, without it's own window
# markdown_view: the markdown view, in the special window
# preview_view: the preview view, in the special window
# original_window: the regular window
# preview_window: the window with the markdown file and the preview

class MdlpInsertCommand(sublime_plugin.TextCommand):

    def run(self, edit, point, string):
        self.view.insert(edit, point, string)

class OpenMarkdownPreviewCommand(sublime_plugin.TextCommand):

    def run(self, edit):

        """ If the file is saved exists on disk, we close it, and reopen it in a new
        window. Otherwise, we copy the content, erase it all (to close the file without
        a dialog) and re-insert it into a new view into a new window """

        original_view = self.view
        original_window_id = original_view.window().id()
        file_name = original_view.file_name()

        syntax_file = original_view.settings().get('syntax')

        if file_name:
            original_view.close()
        else:
            # the file isn't saved, we need to restore the content manually
            total_region = sublime.Region(0, original_view.size())
            content = original_view.substr(total_region)
            original_view.erase(edit, total_region)
            original_view.close()
            # FIXME: save the document to a temporary file, so that if we crash,
            #        the user doesn't lose what he wrote

        sublime.run_command('new_window')
        preview_window = sublime.active_window()

        preview_window.run_command('set_layout', {
            'cols': [0.0, 0.5, 1.0],
            'rows': [0.0, 1.0],
            'cells': [[0, 0, 1, 1], [1, 0, 2, 1]]
        })

        preview_window.focus_group(1)
        preview_view = preview_window.new_file()
        preview_view.set_scratch(True)
        preview_view.settings().set(PREVIEW_VIEW_INFOS, {})


        preview_window.focus_group(0)
        if file_name:
            markdown_view = preview_window.open_file(file_name)
        else:
            markdown_view = preview_window.new_file()
            markdown_view.run_command('mdlp_insert', {'point': 0, 'string': content})
            markdown_view.set_scratch(True)

        markdown_view.set_syntax_file(syntax_file)
        markdown_view.settings().set(MARKDOWN_VIEW_INFOS, {
            "original_window_id": original_window_id
        })

    def is_enabled(self):
        # FIXME: is this the best way there is to check if the current syntax is markdown?
        #        should we only support default markdown?
        #        what about "md"?
        # FIXME: what about other languages, where markdown preview roughly works?
        return 'markdown' in self.view.settings().get('syntax').lower()

class MarkdownLivePreviewListener(sublime_plugin.EventListener):

    phantom_sets = {
        # markdown_view.id(): phantom set
    }

    # we schedule an update for every key stroke, with a delay of DELAY
    # then, we update only if now() - last_update > DELAY
    last_update = 0

    # FIXME: maybe we shouldn't restore the file in the original window...

    def on_pre_close(self, markdown_view):
        """ Close the view in the preview window, and store information for the on_close
        listener (see doc there)
        """
        if not markdown_view.settings().get(MARKDOWN_VIEW_INFOS):
            return

        self.markdown_view = markdown_view
        self.preview_window = markdown_view.window()
        self.file_name = markdown_view.file_name()

        if self.file_name is None:
            total_region = sublime.Region(0, markdown_view.size())
            self.content = markdown_view.substr(total_region)
            markdown_view.erase(edit, total_region)
        else:
            self.content = None

    def on_load_async(self, markdown_view):
        infos = markdown_view.settings().get(MARKDOWN_VIEW_INFOS)
        if not infos:
            return

        preview_view = markdown_view.window().active_view_in_group(1)

        # FIXME: set the preview title
        self.phantom_sets[markdown_view.id()] = sublime.PhantomSet(preview_view)
        self._update_preview(markdown_view)

    def on_close(self, markdown_view):
        """ Use the information saved to restore the markdown_view as an original_view
        """
        infos = markdown_view.settings().get(MARKDOWN_VIEW_INFOS)
        if not infos:
            return

        assert markdown_view.id() == self.markdown_view.id(), \
        "pre_close view.id() != close view.id()"

        del self.phantom_sets[markdown_view.id()]

        self.preview_window.run_command('close_window')

        # find the window with the right id
        original_window = next(window for window in sublime.windows() \
                               if window.id() == infos['original_window_id'])
        if self.file_name:
            original_window.open_file(self.file_name)
        else:<commit_msg>Set the preview's name (in the tab)<commit_after>import os.path
import sublime
import sublime_plugin

from functools import partial

from .markdown2html import markdown2html
from .utils import *

MARKDOWN_VIEW_INFOS = "markdown_view_infos"
PREVIEW_VIEW_INFOS = "preview_view_infos"
# FIXME: put this as a setting for the user to choose?
DELAY = 100 # ms

def get_resource(resource):
    path = 'Packages/MarkdownLivePreview/resources/' + resource
    abs_path = os.path.join(sublime.packages_path(), '..', path)
    if os.path.isfile(abs_path):
        with open(abs_path, 'r') as fp:
            return fp.read()
    return sublime.load_resource(path)

resources = {}

def plugin_loaded():
    resources["base64_loading_image"] = get_resource('loading.base64')
    resources["base64_404_image"] = get_resource('404.base64')
    resources["stylesheet"] = get_resource('stylesheet.css')

# try to reload the resources if we save this file
try:
    plugin_loaded()
except OSError:
    pass

# Terminology
# original_view: the view in the regular editor, without it's own window
# markdown_view: the markdown view, in the special window
# preview_view: the preview view, in the special window
# original_window: the regular window
# preview_window: the window with the markdown file and the preview

class MdlpInsertCommand(sublime_plugin.TextCommand):

    def run(self, edit, point, string):
        self.view.insert(edit, point, string)

class OpenMarkdownPreviewCommand(sublime_plugin.TextCommand):

    def run(self, edit):

        """ If the file is saved exists on disk, we close it, and reopen it in a new
        window. Otherwise, we copy the content, erase it all (to close the file without
        a dialog) and re-insert it into a new view into a new window """

        original_view = self.view
        original_window_id = original_view.window().id()
        file_name = original_view.file_name()

        syntax_file = original_view.settings().get('syntax')

        if file_name:
            original_view.close()
        else:
            # the file isn't saved, we need to restore the content manually
            total_region = sublime.Region(0, original_view.size())
            content = original_view.substr(total_region)
            original_view.erase(edit, total_region)
            original_view.close()
            # FIXME: save the document to a temporary file, so that if we crash,
            #        the user doesn't lose what he wrote

        sublime.run_command('new_window')
        preview_window = sublime.active_window()

        preview_window.run_command('set_layout', {
            'cols': [0.0, 0.5, 1.0],
            'rows': [0.0, 1.0],
            'cells': [[0, 0, 1, 1], [1, 0, 2, 1]]
        })

        preview_window.focus_group(1)
        preview_view = preview_window.new_file()
        preview_view.set_scratch(True)
        preview_view.settings().set(PREVIEW_VIEW_INFOS, {})
        preview_view.set_name('Preview')


        preview_window.focus_group(0)
        if file_name:
            markdown_view = preview_window.open_file(file_name)
        else:
            markdown_view = preview_window.new_file()
            markdown_view.run_command('mdlp_insert', {'point': 0, 'string': content})
            markdown_view.set_scratch(True)

        markdown_view.set_syntax_file(syntax_file)
        markdown_view.settings().set(MARKDOWN_VIEW_INFOS, {
            "original_window_id": original_window_id
        })

    def is_enabled(self):
        # FIXME: is this the best way there is to check if the current syntax is markdown?
        #        should we only support default markdown?
        #        what about "md"?
        # FIXME: what about other languages, where markdown preview roughly works?
        return 'markdown' in self.view.settings().get('syntax').lower()

class MarkdownLivePreviewListener(sublime_plugin.EventListener):

    phantom_sets = {
        # markdown_view.id(): phantom set
    }

    # we schedule an update for every key stroke, with a delay of DELAY
    # then, we update only if now() - last_update > DELAY
    last_update = 0

    # FIXME: maybe we shouldn't restore the file in the original window...

    def on_pre_close(self, markdown_view):
        """ Close the view in the preview window, and store information for the on_close
        listener (see doc there)
        """
        if not markdown_view.settings().get(MARKDOWN_VIEW_INFOS):
            return

        self.markdown_view = markdown_view
        self.preview_window = markdown_view.window()
        self.file_name = markdown_view.file_name()

        if self.file_name is None:
            total_region = sublime.Region(0, markdown_view.size())
            self.content = markdown_view.substr(total_region)
            markdown_view.erase(edit, total_region)
        else:
            self.content = None

    def on_load_async(self, markdown_view):
        infos = markdown_view.settings().get(MARKDOWN_VIEW_INFOS)
        if not infos:
            return

        preview_view = markdown_view.window().active_view_in_group(1)

        self.phantom_sets[markdown_view.id()] = sublime.PhantomSet(preview_view)
        self._update_preview(markdown_view)

    def on_close(self, markdown_view):
        """ Use the information saved to restore the markdown_view as an original_view
        """
        infos = markdown_view.settings().get(MARKDOWN_VIEW_INFOS)
        if not infos:
            return

        assert markdown_view.id() == self.markdown_view.id(), \
        "pre_close view.id() != close view.id()"

        del self.phantom_sets[markdown_view.id()]

        self.preview_window.run_command('close_window')

        # find the window with the right id
        original_window = next(window for window in sublime.windows() \
                               if window.id() == infos['original_window_id'])
        if self.file_name:
            original_window.open_file(self.file_name)
        else:
{'fraction_non_alphanumeric': 0.09202145491116326, 'fraction_numerical': 0.0073751257123700975, 'mean_word_length': 2.7513360578434454, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '882527', 'n_tokens_mistral': 3612, 'n_tokens_neox': 3426, 'n_words': 935}