Sublime Forum

SublimeLint (Realtime lint highlighting)

#14

Nothing happens when I edit my python code. :frowning: I’m using the latest Sublime 2 for Mac.

0 Likes

#15

I’ve hacked the code a bit so that it works for me. Hope that it helps.
sublimeflakes.py.zip (2.8 KB)

0 Likes

#16

oh nice, we can use set_timeout from a thread? I’ll include that in the master version until I craft a better solution.

zeeg: I shot you a PM back, looks like this forum might not send emails for PM notifications

everyone else:
it’s now on github with a few fixes and more updates to come: github.com/lunixbochs/sublimelint

0 Likes

#17

It works! Great! Thanks!

0 Likes

#18

Works great for me too (Ubuntu 10.10 64bit):

cd ~/.Sublime\ Text\ 2/Packages
git clone https://github.com/lunixbochs/sublimelint.git
0 Likes

#19

You can also put it in its own folder: …]/Packages/SublimeFlakes/ instead of …]/Packages/User/

0 Likes

#20

OK this is a seriously awesome plugin.

I decided to extend it to PHP so that it uses the PHP in your path to do a lint check on the source. It doesn’t give you the nice granularity of errors, but it will immediately highlight a line when it has a problem, which is incredibly useful for me (once we can extend the Autocomplete API I’m pretty sure I can make ST2 my full time PHP editor).

Here is my file, I just used your python.py module as an example. It is called php.py

[code]# php.py - sublimelint package for checking php files

start code to actually work with PHP and lint check input

import subprocess, os, tempfile

def check(codeString, filename):
info = None
if os.name == ‘nt’:
info = subprocess.STARTUPINFO()
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = subprocess.SW_HIDE
tmpFile = tempfile.NamedTemporaryFile(delete=False)
tmpFileName = tmpFile.name
tmpFile.write(codeString)
tmpFile.close()
result = subprocess.Popen(‘php’, ‘-l’, tmpFileName], stdout=subprocess.PIPE, startupinfo=info).communicate()[0]
os.unlink(tmpFileName)
return result, tmpFileName

start sublimelint php plugin

import re
all = ‘run’, ‘language’]
language = ‘PHP’

def run(code, view, filename=‘untitled’):
errors, tmpFile = check(code, filename)

lines = set()
underline = ] # leave this here for compatibility with original plugin

errorMessages = {}
def addMessage(lineno, message):
	message = str(message)
	if lineno in errorMessages:
		errorMessages[lineno].append(message)
	else:
		errorMessages[lineno] = [message]

m = re.search(r"on line (\d+)", errors);
if m:
	lineno = int(m.group(1))
	lineno -= 1
	lines.add(lineno)		
	errorLines = errors.splitlines();
	tmpFile = tmpFile.replace("\\", "\\\\")
	m2 = re.search(r"(.*) in " + tmpFile + " on line \d+", errorLines[1])		
	addMessage(lineno, m2.group(1))

return underline, lines, errorMessages, True

[/code]

As well I decided to implement one of your TODO lists, the automatic loading of modules based on their file names. Here is the head of my file (until drawType):

import sublime, sublime_plugin
import os, glob

# todo:
# * fix lag

languages = ]

# fix for __import__ returning 'sublimelint.modules.foo'.split('.')[0] as the module name
def importhelper(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

# auto include our modules
for modfile in glob.glob('sublimelint/modules/*.py') :
	if '__init__' in modfile: continue	
	modname = os.path.basename(modfile).split('.')[0]
	vars()[modname] = importhelper('sublimelint.modules.'+ modname)	
	languages.append(vars()[modname])

also delete line 10 in: github.com/lunixbochs/sublimeli … _plugin.py

and it should work.

Sorry if the code is garbage, this is my first foray ever into Python, definitely an interesting language.

0 Likes

#21

And I just learned how to use hg-git and github, so you have a pull request on github. cool stuff.

0 Likes

#22

Lunixbochs, it would be great if you could bring in support for PHP. Some guys at my company are currently switching to sublime and this would give them another kick :smile:.

0 Likes

#23

will probably have autoloading and my own php plugin in the repo tonight if I don’t get distracted :smile:

edit: both done, along with more updates (coolest new thing is for development: language submodules will automatically reload like normal sublime modules when you save them in st)

0 Likes

#24

lunixbochs: I tried to send you a private email but got an error from the server.

I’ve started working on an “improved” version which can be found at code.google.com/p/py-fun/source/ … _plugin.py
Right now, I’ve focused on refactoring and trying to make it a bit more readable (hopefully!), eliminating some dead code and unneeded declaration (like all the global statements).

Eventually, I’d like to add the possibility to run pylint (instead of pyflakes) and/or pep8, as well as jslint and others…

Anyone can feel free to use any or all or none of the little I did (so far).

André
andre (dot) roberge (at) gmail (dot) com

0 Likes

#25

For those interested, I have created a fork of Ryan’s excellent plugin. You can find my version at github.com/aroberge/sublimelint . I have not changed the readme file nor added any copyright information. I expect Ryan to implement some/all of the new functionality that I have added eventually. I reorganized the code significantly and changed quite a few names so that I could find it easier to read and understand; your mileage may vary.

The main addition, as compared with Ryan’s version is that one can use pylint - but not in realtime. pylint is quite slow, and I have it setup so that it is run on demand. NOTE that you need to have pylint already installed - unlike pyflakes which comes included with the plugin.

Some small differences:

  1. to enable the plugin to work by default, you need to set a user preference “sublime_linter” to true.
  2. you can turn on/off the linter via a command view.run_command(“linter_on”) (or “linter_off”) - even if you have not set a user preference before.
  3. To run a linter “once” (i.e. not always on in the background), you use
    view.run_command(“run_linter”, “linter”) where “linter” is one of “Python”, “PHP” or “pylint”
  4. If you run a linter via a command as in 3. above, the realtime linter is disabled. To reset it to its previous state (on or off…) AND to clear all visible “errors” you use the command
    view.run_command(“reset_linter”)

For some reason, the configuration file for pylint is not read in … I tried various options but could not get it to work. I’ve turned off a couple of things but you may find that pylint reports too many errors to your liking … I’ll try to improve upon it - but suggestions/patches are most welcome.

Also, I found that I simply could not use the subprocess approach used for the php linter (it could not find “pylint” …) and had to resort to importing the pylint module itself. Unfortunately, this means that if you want to work on the pylint plugin itself, you may have to quit Sublime Text and restart to see changes take place (unlike the situation for the other plugins, thanks to some very nice code originally written by Ryan).

0 Likes

#26

I don’t always install plugins, but when I do, they’re awesome like yours.

Great job.

0 Likes

#27

If you’re looking for PEP 8 highlighting, check my fork at github.com/Kronuz/SublimeLint It also improves a few things such as improved (less aggressive, CPU-wise) real time highlighting.

0 Likes

#28

like “goto symbol”?
I’m waiting to do anything really fancy with the python module till I finish switching to my own ast implementation: github.com/lunixbochs/sublimeli … /python.py

0 Likes

#29

I tried it, but it is not doing real time linting of python. I have pylint and pep8 installed. What am I missing?

When I run it from the console, I get the following error:

File "./sublimelint/modules/sublime_pylint.py", line 84, in run ValueError: invalid literal for int() with base 10: '53,0'

0 Likes

#30

@aparajita, instead of pylint, I use pyflakes and the pep8, in the python.py module. The error you’re getting probably comes from a misconfigured pylint (called by sublime_pylint.py)… you can try disabling pylint (and/or deleting the pylint command)

0 Likes

#31

This is working perfectly for me, thanks.

Is there a nicer way to highlighting the errors/text? It only seems to add a border, which is a bit hackish. No way to change the scope of the text and use the theme properly?

0 Likes

#32

There is no way to change the scope of text, that is determined by the syntax. If you pull the latest version of https://github.com/Kronuz/SublimeLint, I added support for setting the background/foreground of the offending lines themselves, not just an outline of the line. You can set those colors yourself by modifying the theme. This makes errors much more obvious. Soon there will also be support for going to the next/previous error.

0 Likes

#33

[quote=“aparajita”]

There is no way to change the scope of text, that is determined by the syntax. If you pull the latest version of https://github.com/Kronuz/SublimeLint, I added support for setting the background/foreground of the offending lines themselves, not just an outline of the line. You can set those colors yourself by modifying the theme. This makes errors much more obvious. Soon there will also be support for going to the next/previous error.[/quote]

Excellent, this is exactly what I was after. Thank you!

Is there a way to turn off the little X?

0 Likes