Tip for debugging SymPy with PuDB

January 28, 2013

Usually, when I debug SymPy code with PuDB, I create a script that calls the code, then I put a

import pudb; pudb.set_trace()

in the SymPy library code where I want to start debugging. But this is annoying, first because I have to create the script, and second, because I have to modify the library code, and there’s always the risk of accidentally commiting that. Also, if I want to start debugging somewhere else, I have to edit the files and change it.

Well, I just figured out a better way. First, if you haven’t already, add an alias like this in your bash config file (~/.profile or ~/.bashrc):alias pudb='python -m pudb.run. As of this pull request, this is no longer necessary. A pudb script is installed automatically with PuDB.

This will let you run pudb script.py to debug script.py. Next, start PuDB. It doesn’t matter with what. You can just run touch test.py, and then pudb test.py. It occured to me that you can just set the breakpoint when starting isympy with PuDB.

Now, press m, and navigate to where in the library code you want to start debugging. It also helps to use / to search the current file and L to jump to a specific line. When you get to the line where you want to start debugging, press b to set a breakpoint. You can do this in multiple places if you want.

Now, you just have to start isympy from within PuDB. Just run pudb bin/isympy, and immediately press c to jump to the interactive prompt. Now, run whatever code you want to debug. When it gets to the breakpoint, PuDB will open, and you can start debugging. If you type c to continue, it will go back to isympy. But the next time you run something that hits the breakpoint, it will open PuDB again.

This trick works because breakpoints are saved to file (at ~/.config/pudb/saved-breakpoints). In fact, if you want, you can just modify that file in the first step. You can edit your saved breakpoints in the bottom right pane of PuDB.

When you are done and you type Ctrl-D PuDB will pop-up again, asking if you want to quit. That’s because it was running the whole time, underneath isympy. Just press q. Note that you should avoid pressing q while debugging, or else PuDB will quit, and you will be left with just normal isympy (it won’t break at your breakpoints any more). Actually, if you do this, but doing Ctrl-D still opens the PuDB prompt, you can just press “Restart”, and it should start working again. Note that “Restart” will not actually reset isympy: all your saved variables will still be the same, and any changes to the library code will not be reloaded. To do that, you have to completely exit and start over again.

Of course, there is nothing SymPy specific about this trick. As long as you have a script that acts as an entry point to an interactive console for your application, you can use it. If you just use IPython, you can use something like pudb /bin/ipython (replace /bin/ipython with the output of which ipython).

Emacs: One year later

January 1, 2013

As readers of this blog may remember, back in 2011, I decided to move to a command-line based editor. For roughly two weeks in December, 2011, I exclusively used Vim, and for the same amount of time in January, 2012, I used exclusively Emacs. I had used a little of each editor in the past, but this was my first time using them to do true editing work. My experiences are chronicled in my blog posts (parts 1, 2, 3, and 7 months later follow up).

To summarize, I decided to use Emacs, as I found it to be much more intuitive, and much more user-friendly. Today, January 1, marks the one-year point of my using Emacs as my sole text editor, with some exceptions (notably, I’m currently writing this blog post in the browser). So I’d like to make some observations:

  • Either one of these editors (Vim or Emacs) is going to really suck unless you are willing to make a serious investment in customizing them and installing nice addons. For the second point, Emacs has an advantage, because the philosophy of Vim is to be barebones whereas the philosophy of Emacs is to be featureful, so that in particular many things that were once addons of Emacs are now included in the standard installation. For customization, on the one hand, Emacs is easier, because it has a nice interface (M-x customize), but on the other hand, Vim’s scripting language is much easier to hack on than Emacs lisp (I still can’t code in Lisp to save my life; it’s a very challenging programming language).

    But my point here is that neither has really great defaults. For example, in Emacs, M-space is bound to just-one-space, which is great for programming. What it does is remove all spaces around the cursor, except for one. But to be really useful, it also should include newlines. It doesn’t do this by default. Rather, you have to call it with a negative argument. So to be really useful, you have to add

    (defun just-one-space-with-newline ()
      "Call just-one-space with a negative argument"
      (just-one-space -1))
    (global-set-key (kbd "M-SPC") 'just-one-space-with-newline)

    to your .emacs file.

  • Emacs has great features, but I always have to look them up. Or rather, I have to look up the keyboard shortcuts for them. I only have the keyboard shortcuts memorized for the things I do every day. I even ended up forgetting really important ones, like M-w (Emacs version of copy). And if a feature involves several keystrokes to access, forget about it (for example, rectangular selection, or any features of special modes). If I use a new mode, e.g., for some file type that I rarely edit (like HTML), I might as well not have any of the features, other than the syntax highlighting, because I either don’t know what they are, or even if I know that they should exist (like automatic tag completion for html), I have no idea how to access them.

    There’s really something to be said about GUI editors, which give these things to users in a way that they don’t have to memorize anything. Perhaps I should try to use the menu more. Or maybe authors of addons should aim to make features require as little cognitive user interaction as possible (such as the excellent auto-complete-mode I mentioned in part 3).

    I mention this because it is one of the things I complained about with Vim, that the keybindings were too hard to memorize. Of course, the difference with Vim is that one has to memorize keybindings to do even the most basic of editing tasks, whereas with Emacs one can always fall back to more natural things like Shift-Arrow Key to select text or Delete to delete the character under the cursor (and yes, I know you can rebind this stuff in Vim; I refer you to the previous bullet point).

  • I mentioned at the end of part 3 that Vim might still be useful to learn, as vi is available literally anywhere that you have POSIX. I honestly don’t think I would be able to use vi or vim if I had to, customization or no, unless I had my keyboard cheat sheet and a decent amount of time. If I’m stuck on a barebones system and I can’t do anything about it, I’ll use nano/pico before I use vi. It’s not that I hate vi. I just can’t do anything with it. It is the same to me now as it was before I used it in-depth. I have forgotten all the keyboard shortcuts, except for ESC and i.
  • I don’t use emacsclient any more. Ever since I got my new retina MacBook Pro, I don’t need it any more, because with the solid state drive starting Emacs from scratch is instantaneous. I’m glad to get rid of it, because it had some seriously annoying glitches.
  • Add alias e=emacs to your Bash config file (.profile or .bashrc). It makes life much easier. “emacs” is not an easy word to type, at least on QWERTY keyboards.
  • I still feel like I am not nearly as efficient in Emacs as I could be. On the one hand, I know there are built-in features (like rectangular selection) that I do not take advantage of enough. I have been a bit lazy with customization: there are a handful of things that I do often that require several keystrokes, but I still haven’t created custom keyboard shortcuts for (off the top of my head: copying and pasting to/from the Mac OS X clipboard and rigidly indenting/dedenting a block of text (C-u 4 C-x TAB, actually C-c u 4 C-x TAB, since I did the sensible thing and rebound C-u to clear to the previous newline, and bound universal-argument to C-c u) come to mind).

    I feel as if I were to watch someone who has used Emacs for a long time that I would learn a lot of tricks.

  • I really should learn Emacs lisp. There are a lot of little customizations that I would like to make, but they are really niche, and can only be done programmatically. But who has the time to learn a completely new programming language (plus a whole library, as just knowing Lisp is useless if you don’t know the proper Emacs funtions and variables and coding styles)?
  • I’ve still not found a good visual browser for jumping to function definitions in a file (mostly Python function definitions, but also other kinds of headers for other kinds of files). The best I’ve found is imenu. If you know of anything, please let me know. One thing I really liked about Vim was the tag list extension, which did this perfectly (thanks to commenter Scott for pointing it out to me). I’ve been told that Cedet has something like this, but every time I try to install it, I run into some issues that just seem like way too much work (I don’t remember what they are, it won’t compile or something, or maybe it just wants to do just way too much and I can’t figure out how to disable everything except for the parts I want).
  • If you ever code in C, add the following to your Makefile
    	$(CC) -o nul $(FLAGS) -S $(CHK_SOURCES)

    (and if you don’t use a Makefile, start using one now). This is assuming you have CC and FLAGS defined at the top (generally to something like cc and -Wall, respectively). Also, add the following to your .emacs

    ;; ===== Turn on flymake-mode ====
    (add-hook 'c-mode-common-hook 'turn-on-flymake)
    (defun turn-on-flymake ()
      "Force flymake-mode on. For use in hooks."
      (flymake-mode 1))
    (add-hook 'c-mode-common-hook 'flymake-keyboard-shortcuts)
    (defun flymake-keyboard-shortcuts ()
      "Add keyboard shortcuts for flymake goto next/prev error."
      (local-set-key "\M-n" 'flymake-goto-next-error)
      (local-set-key "\M-p" 'flymake-goto-prev-error))

    The last part adds the useful keyboard shortcuts M-n and M-p to move between errors. Now, errors in your C code will show up automatically as you type. If you use the command line version of emacs like I do, and not the GUI version, you’ll also need to install the flymake-cursor module, which makes the errors show up in the mode line, since otherwise it tries to use mouse popups. You can change the colors using M-x customize-face (search for “flymake”).

  • I never got flymake to work with LaTeX. Does anyone know how to do it? It seems it is hardcoded to use MikTeX, the Windows version of LaTeX. I found some stuff, but none of it worked.

    Actually, what I really would like is not syntax checking (I rarely make syntax mistakes in LaTeX any more), but rather something that automatically builds the PDF constantly as I type. That way, I can just look over at the PDF as I am writing (I use an external monitor for this. I highly recommend it if you use LaTeX, especially one of those monitors that swivels to portrait mode).

  • If you use Mac OS X, you can use the very excellent KeyRemap4MacBook program to make regular Mac OS X programs act more like Emacs. Mac OS X already has many Emacs shortcuts built in (like C-a, C-e, etc.), but that only works in Cocoa apps, and it doesn’t include any meta key shortcuts. This lets you use additional shortcuts literally everywhere (don’t worry, it automatically doesn’t use them in the Terminal), including an emulator for C-space and some C-x commands (like C-x C-s to Command-s). It doesn’t work on context sensitive shortcuts, unfortunately, unless the operating system already supports it with another keyboard shortcut (e.g., it can map M-f to Option-right arrow). For example, it can’t enable moving between paragraphs with C-S-{ and C-S-}. If anyone knows how to do that, let me know.
  • For about a month this summer, I had to use a Linux laptop, because my Mac broke and my new Mac took a month to arrive (the downside to ordering a new computer immediately after it is announced by Apple). At this point, my saving of all my customizations to GitHub really helped a lot. I created a new branch for the Linux computer (because several things in my customizations were Mac specific), and just symlinked the files I wanted. A hint I can give to people using Linux is to use Konsole. The Gnome terminal sucks. One thing I never figured out is how to make Konsole (or any other Terminal for that matter) to send Control-Shift shortcuts to Emacs (see http://superuser.com/q/439961/39697). I don’t use Linux any more at the moment, but if anyone knows what was going on there, add an answer to that question.
  • In part 3 mentioned that predictive mode was cool, but not very useful. What it does is basically add tab completion for every word in the English language. Actually, I’ve found using auto-complete-mode even when editing text (or LaTeX) to be very useful. Unlike predictive mode, it only guesses words that you’ve already typed (it turns out that you tend to type the same words over and over, and doubly so if those words are LaTeX math commands). Also, predictive mode has a set order of words, which supposedly helps to use it with muscle memory, whereas auto-complete-mode tries to learn what words you are more likely to use based on some basic statistical machine-learning. Also, auto-complete-mode has a much better visual UI and smarter defaults than predictive mode. The result is that it’s actually quite useful and makes typing plain text, as well as LaTeX (actually, pretty much anything, as long as you tend to use the same words repeatedly) much faster. I recommend enabling auto-complete-mode almost everywhere using hooks, like
    (add-hook 'latex-mode-hook 'auto-complete-mode)
    (add-hook 'LaTeX-mode-hook 'auto-complete-mode)
    (add-hook 'prog-mode-hook 'auto-complete-mode)
    ;; etc.
  • At the end of the day, I’m pretty happy with Emacs. I’ve managed to fix most of the things that make it annoying, and it is orders of magnitude more powerful than any GUI editor or IDE I’ve ever seen, especially at just basic text editing, which is the most important thing (I can always use another program for other things, like debugging or whatever). The editor uses the basic shortcuts that I am used to, and is quite efficient to write in. Extensions like auto-complete-mode make using it much faster, though I could use some more extensions to make it even better (namely, a better isearch and a better imenu). Regarding Vim vs. Emacs, I’d like to quote something I said back in my first blog post about Vim over a year ago:

    Vim is great for text editing, but not so hot for text writing (unless you always write text perfectly, so that you never need to leave insert mode until you are done typing). Just the simple act of deleting a mistyped word (yes, word, that happens a lot when you are decently fast touch typist) takes several keystrokes, when it should in my opinion only take one (two if you count the meta-key).

    Needless to say, I find Emacs to be great for both text editing and text writing.

  • 2012 in review

    December 30, 2012

    The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.

    Here’s an excerpt:

    4,329 films were submitted to the 2012 Cannes Film Festival. This blog had 20,000 views in 2012. If each view were a film, this blog would power 5 Film Festivals

    Click here to see the complete report.

    Infinitely nested lists in Python

    September 19, 2012

    Readers of this blog know that I sometimes like to write about some strange, unexpected, and unusual things in Python that I stumble across. This post is another one of those.

    First, look at this

    >>> a = []
    >>> a.append(a)
    >>> a

    What am I doing here? I’m creating a list, a, and I’m adding it to itself. What you end up with is an infinitely nested list. The first interesting thing about this is that Python is smart enough to not explode when printing this list. The following should convince you that a does indeed contain itself.

    >>> a[0] is a
    >>> a[0] == a

    Now, if you have programmed in C, or a similar language that uses pointers, this should not come as a surprise to you. Lists in Python, like most things, do not actually contain the items inside them. Rather, they contain references (in C terminology, “pointers”) to the items inside them. From this perspective, there is no issue at all with a containing a pointer to itself.

    The first thing I wondered when I saw this was just how clever the printer was at noticing that the list was infinitely nested. What if we make the cycle a little more complex?

    >>> a = []
    >>> b = []
    >>> a.append(b)
    >>> b.append(a)
    >>> a
    >>> b
    >>> a[0] is b
    >>> b[0] is a

    So it still works. I had thought that maybe repr just catches RuntimeError and falls back to printing ... when the list is nested too deeply, but it turns out that is not true:

    >>> a = []
    >>> for i in range(10000):
    ...     a = [a]
    >>> a
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: maximum recursion depth exceeded while getting the repr of a list

    And by the way, in case you were wondering, it is possible to catch a RuntimeError (using the same a as the previous code block)

    >>> try:
    ...     print(a)
    ... except RuntimeError:
    ...     print("no way")
    no way

    (and you also may notice that this is Python 3. Things behave the same way in Python 2)

    Back to infinitely nested lists, we saw that printing works, but there are some things that don’t work.

    >>> a[0] == b
    >>> a[0] == a
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: maximum recursion depth exceeded in comparison

    a[0] is b holds (i.e., they are exactly the same object in memory), so == is able to short-circuit on them. But to test a[0] == a it has to recursively compare the elements of a and a[0]. Since it is infinitely nested, this leads to a recursion error. Now an interesting question: why does this happen? Is it because == on lists uses a depth first search? If it were somehow possible to compare these two objects, would they be equal?

    One is reminded of Russel’s paradox, and the reason why in axiomatic set theory, sets are not allowed to contain themselves.

    Thinking of this brought me to my final question. Is it possible to make a Python set that contains itself? The answer is obviously no, because set objects can only contain hashable objects, and set is not hashable. But frozenset, set‘s counterpart, is hashable. So can you create a frozenset that contains itself? The same for tuple. The method I used for a above won’t work, because a must be mutable to append it to itself.

    isympy -I: A saner interactive environment

    August 31, 2012

    As promised, here is another post describing a new feature in the upcoming SymPy 0.7.2.

    Automatic Symbol Definition

    While not as ground breaking as the feature I described in my last post, this feature is still quite useful. As you may know, SymPy is inherently a Python library, meaning that it lives by the rules of Python. If you want to use any name, whether it be a Symbol or a function (like cos), you need to define it (in the case of Symbols), or import it (in the case of functions that come with SymPy). We provide the script isympy with SymPy to assist with this. This script automatically runs IPython (if it’s installed), imports all names from sympy (from sympy import *), and defines common symbol names (like x, y, and z).

    But if you want to use a Symbol that is not one of the ones predefined by isympy, you will get something like

    In [1]: r*x
    NameError                                 Traceback (most recent call last)
     in ()
    ----> 1 r*x
    NameError: name 'r' is not defined

    The best solution for this has been either to type var('r'), which will create the Symbol r and inject it into the namespace, or to wrap your text in a string and pass it to sympify(), like sympify("r*x"). Neither of these are very friendly in interactive mode.

    In SymPy 0.7.2, isympy has a new command line option, isympy -a, which will enable a mechanism that will automatically define all undefined names as Symbols for you:

    In [1]: r*x
    Out[1]: r⋅x

    There are some caveats to be aware of when using this feature:

    • Names must be undefined for isympy -a to work. If you type something like S*x, you’ll get:
      In [3]: S*x
      TypeError                                 Traceback (most recent call last)
      <ipython-input-3-6656a97ea7b0> in <module>()
      ----> 1 S*x
      TypeError: unsupported operand type(s) for *: 'SingletonRegistry' and 'Symbol'

      That’s because S is already defined (it’s the SingletonRegistry, and also a shortcut to sympify()). To use a name that’s already defined, either create it manually with var() or delete it using del.

    • This only works on the top level namespace. If you define a function with an undefined name, it will not automatically define that symbol when run.
    • This works by catching NameError, defining the name, and then re-running the expression. If you have a multiline statement, any lines before the undefined name will be run before the NameError will be caught. This usually won’t happen, but it’s a potential side-effect to be aware of. We plan to rewrite it using either ast or tokenize to avoid this issue.
    • Obviously, this is intended for interactive use only. If you copy code and put it in a script, or in some other place where someone might be expected to run it, but not necessarily from isympy -a, you should include symbol definitions.

    Automatic int to Integer Conversion

    A second thing that is annoying with Python and SymPy is that something like 1/2 will be interpreted completely by Python, without any SymPy. This means that something like 1/2 + x will give either 0 + x or 0.5 + x, depending on whether or not __future__.division has been imported. isympy has always ran from __future__ import division, so that you’ll get the latter, but we usually would prefer to get Rational(1, 2). Previously, the best way to do this was again to either run it through sympify() as a string, or to sympify at least one of the numbers (here the S() shortcut to sympify() is useful, because you can type just S(1)/2).

    With SymPy 0.7.2, you can run isympy -i, and it will automatically wrap all integers literals with Integer(). The result is that 1/2 produces Rational(1, 2):

    In [1]: 1/2 + x
    Out[1]: x + 1/2

    Again, there are a couple of caveats:

    • If you want to get Python style division, you just need to wrap both arguments in int():
      In [2]: int(1)/int(2)
      Out[2]: 0.5

      Of course, if you just want a floating point number, you can just use N() or .evalf()

    • This works by parsing the text and wrapping all integer literals with Integer(). This means that if you have a variable set to a Python int, it will still act like a Python int:
      In [6]: a = int(1)
      In [7]: b = int(2)
      In [8]: a/b
      Out[8]: 0.5

      Note that to even do that example, I had to manually make a and b Python ints by wrapping them in int(). If I had just done a = 1, it would have been parsed as a = Integer(1), and I would have gotten a SymPy Integer. But this can be an issue if you use the result of some function that returns an int (again, note that most functions in SymPy that return integers return Integer, not int).

    • The same as before: this will only work interactively. If you want to reuse your code outside of isympy -i, you should take care of any int/int by rewriting it as S(int)/int.

    Since these are both useful features, we’ve added a way that you can get them both at once: by doing isympy -I (the “I” stands for “Interactive”). If we add similar features in the future, we will also add them to the -I shortcut (for example, we may add an option to allow ^ to automatically be replaced with **).

    SymPy Live Sphinx Extension

    August 21, 2012

    I didn’t blog about SymPy all summer, so I thought I would write a post about my favorite feature of the upcoming SymPy 0.7.2 release.  In fact, this feature has got me more excited than any other feature from any version of SymPy.  Yeah, it’s that good.

    The feature is the SymPy Live Sphinx extension.  To start, if you don’t know about it, check out SymPy Live.  This is a console that runs on the App Engine.  We’ve actually had this for quite some time, but this winter, it got a huge upgrade thanks to the contribution of some GCI students.  Basically, SymPy Live lets you try out SymPy in your browser completely for free, because it runs all the code on the App Engine.  Actually, the console is a full Python console, so you can actually run any valid Python command on it.  This past winter, GCI students upgraded the look of the site, added a mobile version (visit live.sympy.org on your phone), and added other neat features like search history and autocompletion.

    Now, Sphinx is the documentation system that we use to generate SymPy’s html documentation. Last year, when I was at the SciPy Conference, Mateusz had an idea at the sprints to create an extension linking SymPy Live and Sphinx, so that the examples in Sphinx could be easily run in SymPy Live.  He didn’t finish the extension, but I’m happy to report that thanks to David Li, who was also one of the aforementioned GCI students, the extension is now complete, and is running live on our development docs.  When SymPy 0.7.2 is released (soon I promise), it will be part of the oficial documentation.

    The best way to see how awesome this is is to visit the website and check it out.  You will need a modern browser (the latest version of Firefox, Safari, or Chrome will work, IE might work too).  Go to a page in the development docs with documentation examples, for example, http://docs.sympy.org/dev/tutorial.html#algebra, and click on one of the examples (or click on one of the green “Run code block in SymPy Live” buttons). You should see a console pop up from the bottom-right of the screen, and run your code.  For example:

    Example of the SymPy Live Sphinx extension at http://docs.sympy.org/dev/tutorial.html#algebra. Click for larger image.


    You can access or hide the console at any time by clicking on the green box at the bottom-right of the page.  If you click on “Settings”, you will see that you can change all the same settings as the regular SymPy Live console, such as the printer type, and the keys for execution and autocompletion.  Additionally, there is a new setting, “Evaluation Mode”, which changes how the Sphinx examples are evaluated.  The default is “Evaluate”.  In this mode, if you click on an example, it is executed immediately.  The other option is “Copy”.  In this mode, if you click an example, it is copied to the console, but not executed right away. This way, you can edit the code to try something different.  Remember, this is a full fledged Python console running SymPy, so you can try literally anything

    So play with this and let us know what you think.  We would love to hear ways that we can improve the experience even further.  In particular, I think we should think about ways to make the “Copy” mode more user-friendly.  Suggestions welcome!  Also, please report any bugs.

    And one word of warning:  even though these are the development docs, SymPy Live is still running SymPy 0.7.1.  So some examples may not work until 0.7.2 is released, at which point we will update SymPy Live.

    I believe that this extension represents the future of interactive documentation. I hope you enjoy.

    Emacs: 7 months later

    July 9, 2012

    In my final post about my switching to Emacs, a commenter, Scott, asked me, “It has been a while since you started using Emacs. I’m just curious. How is your experience so far now that you have more experience and a more complete configuration?” My reply was getting quite long, so I figured it would be best suited as a new post.

    The short answer is, mostly the same since I wrote that Vim vs. Emacs (part 3). Once you use something a lot, you notice all kinds of things that could use improvements. Some of them are just minor annoyances. For example, many interactive commands in Emacs (but not all!) require you to type out “yes” instead of just “y” as a confirmation. Others are more serious, like the need for a real replacement of SuperTab from vim.

    I actually didn’t have much free time to work on configuring Emacs during the school year, and once the summer started, my computer died, and I’ve been working of an old laptop running Linux until I can get a new one. Fortunately, I had the foresight to put all my Emacs configuration online on GitHub, so it was easy to get my configuration again. I’ve noticed that in Linux, the Alt key (i.e., Meta) is used for other things, so it doesn’t work so well in Emacs (e.g., pressing Alt without any other keys sometimes activates a menu that removes the keyboard focus, and also C-M shortcuts don’t seem to work at all).

    I’ve memorized very few keyboard shortcuts, even ones that might be useful to me (e.g., I don’t remember the shortcut to jump to a matching parenthesis). Usually, if I am using some mode or something and I want to know how to do something, I just Google it, and generally find the answer within a few seconds.

    There are several major configuration issues that I’ve yet to address, either due to lack of time or because I couldn’t find a suitable solution. A SuperTab replacement is one. This is actually a big one, because scrolling through a file just to see what’s there is getting older and older, as is searching just to jump to a function definition. If anyone knows of a good way to do this, please let me know. I mainly need it for Python files, but having it other modes as well would be nice. Basically, I just want something that shows me all the class and function definitions in the file, in order, that I can easily select one and jump to it.

    Related to searching, searching in Emacs sucks. I’m using isearch+, which is an improvement, but it still bugs me that search does not wrap around by default. Also, for some reason, pressing delete doesn’t delete the last character you typed, but the last character that it matched. That may sound minor, but I use it a lot, so it’s really gotten on my nerves.

    Regular expression searching in Emacs is useless. I can never get it to work (usually because of differences between () and \(\)). What I really want is an interactive, user friendly, regular expression search/search and replace tool. There’s regexp-builder, but that’s useless because once you build the regular expression, you have to manually copy it and paste it into the real regular expression search function to actually use it. And it doesn’t work with search and replace.

    This last semester I had a semester long project in C. For that, flymake-mode was a godsend. It requires a bit of manual configuration (you have to add something to your Makefile, and you have to add some stuff to .emacs as always to enable it by default), but once you do that, it just works. If you don’t know what this is, basically, it highlights the compiler errors in your source in real time, as you type it. So instead of doing something stupid twenty times, and then compiling and finding them all, you do something stupid once, see the error, and don’t do make the mistake any more. It’s also nice to close your editor and know that your code will compile.

    The Python mode I am mixed about. On the one hand, it’s really awesome how smart it is about indentation. On the other hand, the syntax highlighting is just shy of what I want (granted, it’s pretty good, but I want better than that). For example, I want to be able to color docstrings, single quoted strings, and double quoted strings differently. It would also be awesome to get some coloring in docstrings itself. I’m thinking markdown mode for any text that’s in a docstring, except for doctests, which are colored in Python mode (or some variant).

    Some things I’ve not really cared much about yet because I haven’t used that type of file yet. For example, I’m currently writing this post in Emacs, and just now noticing the deficiencies in html-mode (e.g., I want an easy way to select text and turn it into a link, just like in the WordPress editor).

    Finally, I’ve been trying to write my own theme. That process has been slow and slightly painful. Emacs is currently in the process of moving to themes, though, so this is to be expected. When Emacs 24 is actually released I think it will be fair to judge how well this feature works.

    That’s my wishlist (or most of it anyway). But there are positive things too. auto-complete-mode, which I mentioned at the top of my previous blog post, is absolutely awesome. I think this extension alone has made me more productive.

    Some things I take for granted, like automatic spell checking of strings and comments in Python (not enabled by default, but not hard to configure either). Thanks to someone on an Emacs mailing list, I have the perfect automatic clearing of trailing whitespace, that automatically leaves your whitespace before the cursor in the buffer, but still writes the clear to the file (see my .emacs file from my dotfiles repo linked to above for details).

    I’ve been hoping to learn Emacs lisp, so that I could remedy many of these problems on my own, but so far I haven’t really had the free time. Lisp is a very confusing language, so it’s not easy to jump into (compared to the language vim uses, which I found easy enough to hack on without knowing at all).

    Ultimately, I’m quite pleased with how user friendly Emacs is, and with how easy it is to find out how to do almost anything I want just by Googling it. Configuration is an uphill battle. Emacs has a ton of great packages, many of which are included, but almost none are enabled by default. Just today I discovered Ido mode, thanks to David Li. I feel that in the long term, as I learn Emacs Lisp, I can make it do whatever I want. It provides a good baseline editing experience, and a good framework for configuring it to do whatever you want, and also enough people use it that 99% of the things you want are already done by somebody.


    Get every new post delivered to your Inbox.

    Join 122 other followers

    %d bloggers like this: