<commit_before>'''This plugin controls a linter meant to work in the background
and to provide information as a file is edited.

It requires that the user setting "sublime_linter" be set to True
to be activated.'''

import os
import time
import thread

import sublime
import sublime_plugin

from sublimelint.loader import Loader
## todo:
# * fix lag (was partially caused by multiple worker threads - evaluate if it's still an issue)

linters = {} # mapping of language name to linter module
queue = {}     # views waiting to be processed by linter
lineMessages = {} # error messages on given line obtained from linter


mod_load = Loader(os.getcwd(), linters)

def run(linter, view):
	'''run a linter on a given view'''
	if not view.settings().get('sublime_linter'):
		return

	vid = view.id()
	text = view.substr(sublime.Region(0, view.size()))

	if view.file_name():
		filename = os.path.split(view.file_name())[-1]
	else:
		filename = 'untitled'

	underline, lines, lineMessages[vid]= linter.run(text, view, filename)
	erase_all_lint(view)

	if underline:
		view.add_regions('lint-underline', underline, 'keyword', sublime.DRAW_EMPTY_AS_OVERWRITE)

	if lines:
		outlines = [view.full_line(view.text_point(lineno, 0)) for lineno in lines]
		view.add_regions('lint-outlines', outlines, 'keyword', sublime.DRAW_OUTLINED)


def erase_all_lint(view):
	'''erase all "lint" error marks from view'''
	view.erase_regions('lint-underline')
	view.erase_regions('lint-outlines')


def select_linter(view):
	'''selects the appropriate linter to use based on language in current view'''
	for language in linters:
		if language in view.settings().get("syntax"):
			return linters[language]
	return None

def queue_linter(view):
	'''Put the current view in a queue to be examined by a linter
	   if it exists'''
	if select_linter(view) is None:
		erase_all_lint(view)# may have changed file type and left marks behind
		return
	queue[view.id()] = view


def background_linter():
	'''An infinite loop meant to periodically
	   update the view after running the linter in a background thread
	   so as to not slow down the UI too much.'''
	while True:
		time.sleep(0.5)
		for vid in dict(queue):
			_view = queue[vid]
			def _update_view():
				linter = select_linter(_view)
				if linter:
					try:
						run(linter, _view)
					except RuntimeError, excp:
						print excp
			sublime.set_timeout(_update_view, 100)
			try:
				del queue[vid]
			except:
				pass

# only start the thread once - otherwise the plugin will get laggy
# when saving it often
if not '__active_linter_thread' in globals():
	__active_linter_thread = True
	thread.start_new_thread(background_linter, ())

class BackgroundLinter(sublime_plugin.EventListener):
	'''This plugin controls a linter meant to work in the background
	and to provide information as a file is edited.
	For all practical purpose, it is possible to turn it off
	via a user-defined settings.
	'''<commit_msg>Started work for non-background linter (i.e. run a linter once). Tested with existing Python linter.<commit_after>'''This plugin controls a linter meant to work in the background
and to provide information as a file is edited.

It requires that the user setting "sublime_linter" be set to True
to be activated.'''

import os
import time
import thread

import sublime
import sublime_plugin

from sublimelint.loader import Loader
## todo:
# * fix lag (was partially caused by multiple worker threads - evaluate if it's still an issue)

linters = {} # mapping of language name to linter module
queue = {}     # views waiting to be processed by linter
lineMessages = {} # error messages on given line obtained from linter


mod_load = Loader(os.getcwd(), linters)

def run(linter, view):
	'''run a linter on a given view if settings is set appropriately'''
	if not view.settings().get('sublime_linter'):
		return
	run_(linter, view)

def run_(linter, view):
	'''run a linter on a given view regardless of user setting'''
	vid = view.id()
	text = view.substr(sublime.Region(0, view.size()))

	if view.file_name():
		filename = os.path.split(view.file_name())[-1]
	else:
		filename = 'untitled'

	underline, lines, lineMessages[vid]= linter.run(text, view, filename)
	erase_lint_marks(view)

	if underline:
		view.add_regions('lint-underline', underline, 'keyword', sublime.DRAW_EMPTY_AS_OVERWRITE)

	if lines:
		outlines = [view.full_line(view.text_point(lineno, 0)) for lineno in lines]
		view.add_regions('lint-outlines', outlines, 'keyword', sublime.DRAW_OUTLINED)


def erase_lint_marks(view):
	'''erase all "lint" error marks from view'''
	view.erase_regions('lint-underline')
	view.erase_regions('lint-outlines')


def select_linter(view):
	'''selects the appropriate linter to use based on language in current view'''
	for language in linters:
		if language in view.settings().get("syntax"):
			return linters[language]
	return None

def queue_linter(view):
	'''Put the current view in a queue to be examined by a linter
	   if it exists'''
	if select_linter(view) is None:
		erase_lint_marks(view)# may have changed file type and left marks behind
		return
	queue[view.id()] = view


def background_linter():
	'''An infinite loop meant to periodically
	   update the view after running the linter in a background thread
	   so as to not slow down the UI too much.'''
	while True:
		time.sleep(0.5)
		for vid in dict(queue):
			_view = queue[vid]
			def _update_view():
				linter = select_linter(_view)
				if linter:
					try:
						run(linter, _view)
					except RuntimeError, excp:
						print excp
			sublime.set_timeout(_update_view, 100)
			try:
				del queue[vid]
			except:
				pass

# only start the thread once - otherwise the plugin will get laggy
# when saving it often
if not '__active_linter_thread' in globals():
	__active_linter_thread = True
	thread.start_new_thread(background_linter, ())

# view.run_command("goto_line", {"line": 7})

class RunLinter(sublime_plugin.TextCommand):
    def __init__(self, view):
        self.view = view

    def run_(self, name):
        saved_ = self.view.settings().get('sublime_linter')
        self.view.settings().set('sublime_linter', False)
        if name in linters:
        	run_(linters[name], self.view)
        else:
        	print "unrecognized linter: %s" % name
        self.view.settings().set('sublime_linter', saved_)
        a = 3

class ClearLintMarks(RunLinter):
	def run_(self, arg):
		erase_lint_marks(self.view)

class BackgroundLinter(sublime_plugin.EventListener):
	'''This plugin controls a linter meant to work in the background
	and to provide information as a file is edited.
	For all practical purpose, it is possible to turn it off
	via a user-defined settings.
	'''
{'fraction_non_alphanumeric': 0.09832635983263599, 'fraction_numerical': 0.0026897788404064557, 'mean_word_length': 4.204510108864697, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '772608', 'n_tokens_mistral': 2256, 'n_tokens_neox': 2099, 'n_words': 744}