Tag Archives: sublime text

LaTeX plugin: build paths are in!

A long-standing stumbling block for people getting started with ST2 on the Mac was the need to specify the TeX binaries path in a somewhat esoteric (and hidden) OSX plist file.

Well, no more! To make a long story short, my hard disk crashed, so I had to reinstall and reconfigure the OS and software on my Macbook Pro. In particular, my now-virgin system no longer has the .MacOS/environment.plist file correctly set up. I decided to use this opportunity to fix things the right way.

Now, the LaTeX.sublime-build file recognizes a new option, “path”. On the Mac, it is preconfigured so it works with any recent default install of MacTex. You can change it if necessary, but most likely you won’t need to: the build system should now just work.

On Windows, recent versions of MikTex do the right thing and set up the path so no special setting is needed, but the option is available in any case to handle non-standard configurations. (Note: you still need to manually add the Sumatra directory to your path; I plan to fix this next.)

As usual, please pull from GitHub, test, and report any breakage.


LaTeX plugin: Terminating a lengthy build process.

I just pushed a few patches to GitHub. If you get a fresh copy of the LaTeX plugin for Sublime Text 2, you will now be able to stop (Unix: “kill”; Windows: “terminate”) a lengthy build process simply by invoking the build command while a build is ongoing.

To clarify: say you start a build, e.g. by hitting CMD-B on the Mac. Suppose that you are compiling a Beamer presentation, which typically takes a while. Suddenly, you realize that there is a nasty typo in a slide. Instead of waiting for the build to end, you can now issue the build command again (e.g. by hitting CMD-B on the Mac): this will stop the currently running build, and print a message to this effect in the output panel. You can then fix the typo, and launch a new build as usual.

Caveats: this is my first stab at build killing. The required code (in makePDF.py) definitely hits the ceiling of my Python threading abilities. So far, it seems to be working (I’ve been using it myself all day, as I prepare for two upcoming conferences), but please test it yourself and let me know how things are.

Second, I have only tested this on the Mac. The Python code I use is fully cross-platform, but you never know. If you are on Windows, I’m even more curious to know if things work for you.

Final note to self and to fellow Python coders: I initially had quite a bit of trouble, because I used to execute the actual TeX commands via Popen.communicate. Trying to use Popen.kill() on a Popen object did not really work, in the sense that considerable time elapsed between the time the kill() method was called and the time the process actually exited. I am now using Popen.wait() to execute the TeX command, and the process is terminated almost instantaneously. There seems to be some funny business having to do with capturing output going to STDOUT in Popen.communicate(); using Popen.wait() avoids this (although you then have to send output to a temp file, if you need to capture it–which I don’t at the moment).

LaTeX Plugin: Build system activated

This post is a quick update on the revamped LaTeX build system.

If you pull the current master branch from Github, you will now be able to invoke the custom make_pdf command using the default build system: in particular, you can hit Command+B on Mac and F5 on Windows. The temporary ctrl+alt+t shortcut no longer works: on Mac, it does nothing, whereas on Windows it errors out (I’ll fix this soon). So, just don’t use it.

This is achieved by using the “target” option in the LaTeX.sublime-build file. By default (i.e. if no “target” option is provided), the build system invokes the “exec” command. However, you can instruct it to invoke any Python-written ST2 command; in my case, I set “target” to “make_pdf”, and ST2 automagically does the right thing.

In particular, any options in the sublime-build configuration file are passed as named arguments to the make_pdf command. Even better, you can set Windows- and OSX-specific options in the sublime-build file, and make_pdf will automagically receive the settings that are appropriate to your platform!

One final bit of awesomeness. If you open the LaTeX.sublime-build file, you will see that you can pass any configuration options to the latexmk (OSX) or texify (Windows) compiler drivers, IF YOU KNOW WHAT YOU ARE DOING. For instance, on Mac, you can easily change the tex engine from pdflatex to xelatex (it’s not so easy on Windows because texify is not as flexible as latexmk). Now, I was worried that any tweaks to the sublime-build file would be lost every time the user downloads a new version of the plugin. However (and this is the above-mentioned awesomeness), it turns out that you can save a copy of the LaTeX.sublime-build file in the Packages/User directory (rather than Packages/LaTeXTools), then tweak it to your heart’s content: when you invoke the build system, the file in Packages/User will take precedence, so your tweaks will still be there! Thanks jps πŸ™‚

There are two items on my immediate TODO list. First, I want to add an option to the sublime-build file to specify the path of TeX executables (with sane defaults that should work on most systems). This will ensure that, with a minimum of configuration (or no configuration), tex and friends will work even if the PATH is not set (or, on the Mac, you have not created an .MacOSX/environment.plist file, as per this comment). This is the main cause of grief for new users; hopefully this will solve the issue once and for all.

Second, I would like to make the viewer configurable as well. Right now it is not: you must use Skim on the Mac and Sumatra on Windows. There is an issue as to where this setting should be; the sublime-build file does not seem appropriate, strictly speaking, but on the other hand it makes sense to keep all configuration settings in the same file.

One final note: the old sublime-settings file is still available, but I appended an “.OLD” extension to it so it’s not active. However, if you really prefer the old-style build system, you can still use it (remove or rename the new sublime-build file, then remove the “.OLD” extension to the old sublime-build file). In particular, this allows you to set your favorite PDF viewer (on the Mac), although you will lose inverse and forward search.

Comments, are usual, are very welcome!

LaTeX plugin: the new build engine is in!

I have decided to merge my ongoing work on a LaTeX-specific build engine. See my previous post for details on the new goodness. If you now pull the master branch from github, you’ll get the new engine. The relevant file is makePDF.py, but I had to change jumpToPDF.py as well.

A few notes. First, the quality of the code is, er, less than ideal. It works on all the (many!) test cases I have thrown at it, but it’s not pretty to look at. I’ll fix this in time. However, in the meantime, I’d like to get more people to try it out.

Second, the new build engine is bound to ctrl+alt+t (which is control+option+t on the Mac). The old, ST2-based build system is still available and bound to F5 on Windows and Command-B on the Mac (these are the ST2-standard bindings). Eventually, I plan to phase out the old build system, but not yet…

Third, due to the logic of log file parsing, you cannot use file names with parentheses. However, I am happy to report that spaces in file names (and directory names, too) are OK.

Fourth, there is still limited support for multi-file documents. Specifically, the log-file parsing logic is smart enough to pick up errors in different files and place the appropriate lines in the exec panel. However, compilation must be invoked from the master file (i.e. you must switch to the tab containing the master file before invoking compilation). The same is true of the old build system, by the way. Setting master files so you can compile from any file in the project is high on my agenda (together with certain other build and display customizations).

If you see any breakage, please let me know! In particular, if you see the line saying ‘Compiling ‘ in the exec panel, but nothing else happens after a while, hit ctrl+` to bring up the output panel; if you see any Python error messages, that’s breakage! Reports are greatly appreciated.

LaTeX plugin update: new build command, and parsing TeX log files

Once again, I haven’t posted anything in a while… I have been pretty busy at work lately: a couple of trips and PhD admissions took up most of my time. However, I have also made some progress with the Sublime Text 2 (ST2) LaTeX plugin. You can take a look at the current GitHub repository; there have been a few blog-worthy additions to the master branch, but the work I am most excited about has been in the make-pdf branch. Check that out (literally!) and look for yourself if you feel adventurous; however, note that things may be a bit broken, especially on Windows (my main work and dev platform is OSX). In particular, there is (as of today) no keybinding for the new make facility on Windows: take a look at Default (OSX).sublime-keymap to see how to add this on a PC. But, if you are not adventurous enough, read on πŸ™‚

In the master branch, turning your tex file into a PDF file is achieved by using the ST2-standard build framework to invoke the latexmk command on OSX, and the texify command on Windows. In turn, these commands are instructed to launch a viewer. The output from these commands, including any error or warning messages, are sent by ST2 to the so-called "exec panel", i.e. a display area that pops up in the (roughly) bottom third or fourth of your ST2 window, and can be dismissed by pressing ESC if the user so wishes. Furthermore, ST2 provides a "goto next error" command (bound to F4 by default); to configure it, one must provide a regex (regular expression) that captures the file name and line number (and, optionally, column number) where the error occurred.

Using the standard build facility has the advantage of being more, er, Sublime–that is, in line with the philosophy, look, and feel of the ST2 editor. That’s a big plus. However, there are two important minuses. First, the regex approach for error detection works very well with languages, such as C or Java, that produce well-structured output and logs (where, by "well-structured," I mean "sane"). This does not include TeX–by a long shot. I provide some details below, as that’s the main focus of this post, and of my work in the make-pdf branch. The other minus is the fact that, while latexmk and texify can invoke a viewer, it is not possible to instruct said viewers to jump to the current line; the reason is that the build system is controlled by a static configuration file, and has no access to things like the current view (at least as far as I can tell, and as of build 2055). However, the ST2 developer has provided the ability to link the build command to any arbitrary Python script (or, more precisely, any ST2 "command"). This makes it possible to overcome any limitation of the default system. The make-pdf branch of the LaTeX plugin uses just this facility.

Specifically, I implemented a heavily customized version of the ST2 exec command, which is invoked whenever a standard build is initiated. The code is in makePDF.py, and the make_pdf command it defies is currently bound to ctrl+alt+t, the key binding for the old "texify" command in the version 1 plugin (again, this is actually only true for OSX as of today). The overall structure is relatively simple: the system-dependent command line is set up, then invoked in an instance of a worker thread called CmdThread, to avoid blocking. After the compilation command terminates, the log file is parsed (again in the thread), and the results are displayed. Since all output must happen on the main thread, the CmdThread thread issues display commands (basically, adding text to the exec panel) using set_timeout, using callbacks in the make_pdfCommand class. When this is done, the jump_to_pdf command is invoked, which causes the viewer to open the just-compiled PDF file (assuming all went well) and go to the line corresponding to the current cursor position. Notice that right now there is no error checking: the next order of business is to at least check for compilation errors before the viewer is invoked.

The piece de resistance of the make_pdf command, however, is the parseTeXlog function. It, well, parses the TeX log file. This presents five distinct difficulties:

  1. TeX errors are reported over several lines: the first (starting with an exclamation mark) states the type of error, then a few lines of surrounding text are reported, and finally the line where the error occurred is actually indicated. It is possible to force tex to use a file:line:error format like C or Java; however…
  2. …each macro package, beginning with LaTeX, reports warnings in a different format that cannot be forced into file-line-error mode. Thus, you need different regexes to match errors and warnings. I guess in principle one could try to use a single, humongous regex, but I am not sure one could cover all cases, and it would be a nightmare to write and maintain. I live by JWZ’s famous quote on regexes. In any case…
  3. …a regex that catches warnings would not be able to detect which file the warning occurred in—only the line and the warning message. This poses a problem for multi-file documents, which I really want to support (hello book co-authors!). This requires really understanding what the TeX log file is telling you at any given line. In particular, whenever TeX processes a new file (be it a source file, a style file, a class file, or anything else), this is reported on the log file; when processing of that particular file is complete, this, too is indicated. But, to make matters worse…
  4. …TeX "helpfully" breaks lines longer than 79 characters. Why is this a problem? Because certain style and macro files live deep in the texmf tree, so that their full path name easily exceeds 79 charactes. And because, if a user’s account name is RichardJamesDrofnatsTheThird, and he is working on a file called UnexplicableImplicationsOfUnrealisticAssumptionsInEconomicTheory.tex in a directory called CogitationsOfAnUnrepentantEconomist off of his Documents folder, well, that file name will be truncated (as far as I can tell, TeX always displays the full path name of the master file being compiled). And, finally…
  5. …there is no way to know whether a line was truncated or not. You can guess, and you can use heuristics, but there is no specific marker to tell you what TeX actually did with your log file. Fun!

So, here’s what I did. To make sense of this mess, one must start with the last problem: how to reassemble long lines. Again, there is no way to know for sure whether a 79-character line is the beginning of, say, a 90-character line, or if it is a line that just happens to be exactly 79 characters long (In case you were wondering, yes, I have found quite a few such lines in actual log files!). However, there are certain empirical regularities, which I exploit. The code in parseTeXlog joins a 79-character line with the line immediately following it, except under certain conditions. For example, many tex packages output an identification string of the form Package: geometry.sty... as soon as they are loaded. So, if a 79-character line is followed by a line that starts with Package:, I don’t join the two lines. There are other exceptions and heuristics: take a look at the file.

To be sure, I am not certain that I have covered all the cases. However, so far, every log file I have processed has been successfully parsed, and (trust me!) I have processed a lot of files. But, if you find something that breaks the parsing logic, I definitely want to know—thanks!

The next issue is to keep track of the file currently being processed. TeX reports it by printing a ( followed by the path name. Usually, the parenthesis is the first character in the line… but when a macro file loads another macro file, this may not be the case. So, you need logic for that. Whenever I see a new file being processed, I add it to a stack (the files list) and print its name (suitably indented) for debugging purposes (the user does not see this, unless she switches to the Python console).

When TeX is done processing a file, it just prints a closing parenthesis: ). This usually occurs on a line by itself, but for files imported by other packages this may not be the case. Special logic is needed to handle such cases. When I can be reasonably sure that a given file has been fully processed, I "pop" (i.e. remove) it from the stack.

The net result is that, when an error message is encountered, it must refer to the file that is currently at the top of the stack. What’s nice about this approach is that I do not need to know anything about the file being compiled: all the information I need is contained in the log file.

When all this is done, extracting error and warning information is actually easy. I then convert the information into file-line-error format, and tell ST2 to look for errors in that particular guise. This way, the user can hit F4 to navigate through errors. Or, the user can double-click on an error, and—regardless of the file it’s in—ST2 brings up the offending line. Pretty cool! This is actually better than TextMate’s error reporting, I think!

There is still a lot to do. First, as I noted above, I think that the current parsing logic is fairly robust, but it is still full of heuristics and hacks. If you find any problem or issue, please let me know! Second, I need to robustify the support for multi-file documents: there will be a mechanism to invoke compilation of the master file even if the user is editing an included file. Furthermore, there will be logic to only display the PDF output if compilation was successful.

More urgently though, I need to run some tests on Windows. When that is done, I will merge the make-pdf branch with the master branch and make this code the default build system. Comments welcome!

The in-progress LaTeX plugin for Sublime Text 2

EDITED 3/26: fixed URLs to reflect the new ‘official’ SubimeText packages repo / organization.

I have been pretty quiet the last couple of weeks. The main reason is that I was working hard to meet a deadline (which I did, sort of). However, I have also finally begun porting my LaTeX plugin for Sublime Text to the new, awesome, cross-platform v. 2.0 of said amazing text editor. Mind you: Sublime Text 2 (ST2 for short) is still in the alpha stage, and so is my ported plugin. On the other hand, I have been using ST2 as my sole text editor for the past two weeks, tweaking and porting the essential features of the LaTeX plugin as I needed them. It has served me well.

Thus, if you like living on the edge, you can get the ST2 alpha version here; or, if you are really adventurous, grab the latest dev build here. Then, head over to the LaTeXTools public GitHub repository; hit the “Downloads” button to get a .zip file of the current version; you will get a silly name like msiniscalchi-LaTeXTools-38ddb5f.zip (the final part of the file name will change: it’s part of the hash code of the latest commit I pushed to github). Expand this to a folder, which will be aptly called something like msiniscalchi-LaTeXTools-38ddb5f. Rename this folder to something sane, such as LaTeXTools but NOT just LaTeX (read on), and drop it in ST2’s Packages directory, which you can open from ST2 itself by selecting Preferences|Browse Packages (the exact location of these menu items varies by OS).

An important caveat: the new plugin is designed to coexist with, not replace, the existing snippets, language definitions, etc., that can be found in the LaTeX folder that comes with ST2 (in the Packages) directory. This is the reason why the plugin folder must be names something other than LaTeX. Also, of course you must not erase the existing LaTeX folder.

I am pretty excited about the plugin! It’s certainly not complete, and must currently work around limitations imposed by the fact that the ST2 alpha still lacks certain features that ST1 had (for instance, quick panels). On the other hand, ST2 brings a lot to the table, and the plugin attempts to use the built-in features of ST2 whenever possible; the best example is the use of the Completions API to handle references and citations, and of .sublime-completions files to handle quick LaTeX macro insertion. As a guiding principle, whereas the LaTeX plugin for ST1 tried to be very TextMatey, the LaTeX plugin for ST2 will be more… well, Sublime πŸ™‚

I will blog about specific features of the plugin later. However, if you want to kick the tires, so to speak, here’s the bare minimum you need to know.

  • On Windows, the plugin uses MikTeX and the Sumatra PDF previewer, just like ST1. Both must be installed, and Sumatra must be on the PATH. Check your environment variables.
  • Recent versions of Sumatra allow you to set up inverse search from the GUI. You need to do so before you can use this feature. Go to Settings|Options, and under “Set inverse search command line”, enter sublime-text "%f":%l
  • Similarly, on the Mac, you use MacTeX and the Skim previewer. To set up inverse search, go to Preferences, select the Sync tab, choose Custom from the Preset drop-down menu, and enter subl in the Command field and "%file":%line in the Arguments field. Also make sure the Check for file changes box is not checked (same as for TextMate).
  • To compile a tex file, use the ST2 build system, which you invoke with F7 on Windows and Cmd-B on the Mac. The build will start, and if there are n errors the PDF viewer will be shown.
  • When you recompile (again, with the Build command), the PDF file will be automatically refreshed, but will stay in the background.
  • To use forward search (i.e. jump from tex to pdf), use shift+alt+j on Windows and shift+cmd+j on the Mac. For inverse search, double-click (Sumatra) or shift-cmd-click (Skim) at the relevant position in the pdf file.
  • For the time being, after compiling, the PDF file is either opened on page 1, or else refreshed; you do not automatically move to the page corresponding to the current position in the tex file. This is the same behavior as the ST1 LaTeX plugin, but it is different from TextMate’s behavior. I’ll fix this later.
  • Two PDF-viewer caveats: on Windows, if you try to use forward search but haven’t installed Sumatra, ST2 will crash. On the Mac, if you have Skim running without any windows open, and you try to compile a file or view the current PDF file (with ctrl+opt+v), nothing will happen. Close Skim and try again. Again, it’s something I need to fix.
  • Check the .sublime-keymap file for your platform (in the directory where the new LaTeX plugin lives) to figure out other key bindings, or change the existing ones.
  • A quick primer on the new features: references are inserted by typing ref and then hitting ctrl+space (the ST2-standard long completion key combo). This shows a drop-down menu with all possible references. But, if you know the reference you are looking starts with, say, `sec’, you can type ref_sec, then hit ctrl+space: now only references starting with `sec’ will be shown! Citations work similarly: e.g. type cite_myer and all citations with `myer’ either in the key or the title will come up. There are many more features (and a couple of caveats): you can check the comments in the latex-cite-completions.py and latex-ref-completions.py files to get an idea, but again, I’ll blog about them later.
  • In math mode, you have access to many convenient shortcuts (completions): e.g. type a, then hit TAB: you get \alpha. In text mode, you get other completions: e.g. bs expands to \bigskip. Note that, for instance, it expands to \mathit in math mode, and to \textit in text mode. Also, you can cycle among certain LaTeX commands. Check the LaTeX.sublime-completions and LaTeX math.sublime-completions for a human-readable list of available shortcuts.

That’s about it for now. Again, it’s all alpha quality, but I have been using the ST2+Plugin combination as my sole LaTeX editing `solution’ (hate that word…) for a couple of weeks, and it is serving me well so far. How’s that for dogfooding?

A quick note on Sublime Text

Two, really. First, I realized that links to specific pages on the sublimetextwiki.com site no longer work. So, the correct URL for the Sublime Text LaTeX plugin is now this.

The aforelinked (pardon the Gruberism) Web page is automatically generated from the README.txt help file that every Sublime Text plugin must include. Again by convention, the latter file is marked up using, ahem, Markdown; a "style sheet" is then used to convert it to HTML code that can be rendered by Web browsers. Well, it appears that a different style sheet is now being employed. I am not too crazy about the choice of grey text on black background; but, more importantly, text in backquotes, e.g.

the word `this` is in backquotes

is now rendered on a line by itself, like this:

the word
is in backquotes

Previously, it was rendered "in-line", as if using the code tag in HTML. I will have to fix up the help file so it does not look too bad; please bear with me…

…which brings me to the second note. I am seriously thinking about experimenting with the current alpha release of Sublime Text X, the next-generation version. Its main advantage is that it is cross-platform! Yay! This means that I will be able to work on the LaTeX plugin on my Mac, under OS X, without either rebooting or running Parallels.

If I do take the plunge, the first order of business will be to refactor the existing code so that all Windows-specific code (in particular, invoking texify and the Sumatra PDF previewer) is neatly isolated, and can be replaced by the corresponding Mac-specific calls and scripts. This would actually be an improvement over the current structure even beyond cross-platform portability; for instance, it would make it easy(ier) for me to add support for different PDF previewers, and perhaps even TeX distributions.

No promises as to the time frame though… if anyone wishes to help out, let me know!

LaTeX plugin update: threading for fun and profit

I finally bit the bullet and rewrote the "texify" command so as to provide better feedback during compilation. The latest version of the plugin behaves as follows: as soon as you invoke the "texify" command (bound to ctrl+alt+t by default), a quick panel is displayed, initially showing the exact texify command issued. When compilation finishes, errors and warnings are displayed, followed by the contents of the log file. Previously, the quick panel was only shown upon completion of the texify command, so one was left wondering whether compilation had actually started upon hitting ctrl+alt+t. The new behavior is a lot more informative and user-friendly. As was the case previously, you can click on any error message containing a line number to jump to the corresponding line in the source file. The new code also has other niceties related to error detection; I will discuss them in a later post.

Figuring out how to display some text in the quick panel, leave the latter open while an external command runs, and then add more text to the quick panel took me on an interesting, if lengthy trip into Python threading land. Suppose you try the following code:

	class PanelTestCommand(sublimeplugin.WindowCommand):
	   def run(self, window, args):
	      args = ["wait 5 seconds..."]
	      window.showQuickPanel("panel", "", args)
	      print "Wait"
	      import time
	      print "Done"
	      window.showQuickPanel("panel", "", args)

Update: WordPress seems to kill spacing at the beginning of a line… please pretend the above listing and the one below are correctly indented πŸ™‚

Update 2: Actually, there is a nice, easy way to post source code: the sourcecode shortcode! See here for details. The only issue seems to be that quotes are transformed into HTML entities, so when you get back your post from WordPress, it looks a bit messy. I am also worried about round-tripping. But, I’ll look into this later.

For non-SublimeText people, you define a command by subclassing sublimeplugin.WindowCommand and redefining the run method. The showQuickPanel method takes three arguments, the last one being a list of strings to be displayed. The print statement displays text in the console, which is useful for debugging purposes. The rest of the code should be self-explanatory; the 5-second wait is a stand-in for a blocking system call (e.g. to texify). Unfortunately, when you invoke this command, nothing happens for 5 seconds, after which (a) all output is shown in the console, and (b) the quick panel is displayed.

This reply by the Sublime Text author, Jon Skinner, to a post of mine in the tech support forum pointed me in the right direction. Sublime Text works asynchronously, and apparently buffers output as needed. So, to get the intended behavior, you need to do things in a somewhat roundabout way:

  • Spawn a thread that invokes the required command (or, in the case of the above example, waits 5 seconds)
  • Invoke showQuickPanel from the thread, via the sublime.setTimeout method.
  • This reminds me of how you deal with the event dispatch thread in Java Swing; I guess something similar is going on. The bottom line is, I had to learn the bare minimum about threading in Python, and then take care of certain annoyances. This is the relevant portion of the current implementation of the “texify” command:

    	class TexifyCommand(sublimeplugin.WindowCommand):
    		def run(self, window, args):
    			[omitted: set things up]
    			view = window.activeView()
    			texFile, texExt = os.path.splitext(view.fileName())
    			[omitted: create texify command line]
    			pContents = ["Texify executing command:", cmd]
    			window.showQuickPanel("texify", "", pContents)
    			class CmdThread ( threading.Thread ):
    				def __init__ (self, cmd, pContent, texFile, window):
    					self.cmd = cmd
    					self.pContent = pContent
    					self.texFile = texFile
    					self.qp = window.showQuickPanel
    					threading.Thread.__init__ ( self )
    				def run ( self ):
    					[omitted: set things up]
    					p = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True)
    					stdoutdata, stderrdata = p.communicate()
    					pContent = [omitted: define content to be displayed]
    					sublime.setTimeout(functools.partial(self.qp,"texify","gotoTeXError", pContent), 0)
    			CmdThread(cmd, pContents, texFile, window).start()

    Let’s take a close look. When the command is invoked, we do some housecleaning, and then create the texify command line from the name of the file in the current buffer (details omitted); this is stored in the variable named cmd. We then display this information in the quick panel.

    Next, we use the Python threading module. We must subclass threading.Thread; all the action takes place in the run method, which sets things up, invokes the texify command, and then uses sublime.setTimeout to display the results via showQuickPanel.

    While this description is correct, it overlooks an important fact: the CmdThread class does not have access to variables such as cmd or window, and hence to the window.showQuickPanel method. To address this, we use the __init__ method to save copies of the objects we need—including the window.showQuickPanel method, which is stored in self.qp.

    But there is one more wrinkle. The setTimeout method accepts two parameters: the method to be called, and a delay value. In our case, we want to call the self.qp = window.showQuickPanel method… but how can we pass parameters (such as the text to be displayed!) to it? The functools
    Python module comes to the rescue: using functools.partial, we create a new method that works like window.showQuickPanel, but with the parameters we need—in particular, the content to be displayed is in the variable code pContent.

    Voila’! We then finally create our thread object and start it. So, to summarize, the key “tricks” are:

  • Do all blocking work in a thread, and call showQuickPanel from that thread via setTimeout
  • To pass parameters to the thread, including the showQuickPanel method, use the thread object’s __init__ method.
  • To set the parameters of the showQuickPanel call, use functools.partial.
  • Comments and advice is most welcome—I’m still learning this stuff!

    Long time no blog!

    Well, it’s been a really long time since I last blogged! All work and no play, etc.

    In the meantime, a new beta of Sublime Text came out; the most notable change is that the included Python interpreter was bumped up to ver. 2.6. I quickly checked the LaTeX package, and things still seem to work fine. I’ll get back to it when things are a bit less hectic at work. In the meantime, I am really curious to hear from users, ideally via the Sublime text forum.

    Next up: it appears that Android phones have overtaken the iPhone in terms of unit sales. The Mac blogosphere is understandably a bit defensive. Right now, the iPhone is clearly dominant in terms of developer mindshare, but that may well change. Also, Android has some really serious memory limitations which, in particular, pretty much ensure that Android games are pretty lame compared with their iPhone counterparts. This is a big deal for me, as I’d like to get a phone that my kids can play with on long flights. And, in general, Android apps lack the polish of iPhone apps.

    But, in time, these issues will likely be resolved; what then? Will two (or more) mobile platforms coexist, or will it be like PCs vs. Macs all over again? Is there something intrinsically different about smartphones that will prevent this scenario from happening?

    Sublime Text LaTeX plugin: Beamer Slides

    I have updated my LaTeX plugin for the Sublime Text editor with features that make life a bit easier when working on Beamer presentations.

    Continue reading