On the off-chance anyone turns up here with something to say, we’ll do this on the Auster model: email me your name, URL, and the substance of your comment, and I’ll add it through the dashboard.
I’ve been using Emacs for a couple of years, and I’m still discovering new capabilities almost daily. Recently, I’ve become aware of etags, which is awesome, but which for me presented a considerable difficulty: the generation of tag files is handled not within Emacs but by a separate program, which means that if you, like me, give each of your major projects a virtual machine of its own, then you have no easy way to keep your tag files up to date. (For the purpose of this discussion, installing Emacs on each VM, or digging the etags source and any dependencies out of the Emacs distribution and building it once per VM, do not count as “easy”.)
Of course, this is not to be borne; I still find it surprising that there’s no Tramp-aware mechanism by which to generate and update tag files, but that didn’t stop me from writing some code to do the job — not that I’m done; what I have is a working first draft written in Perl, while the final result will probably be an Elisp module suitable for tossing into ~/.emacs.d/site-lisp and calling via (etags-update “/host:/path/to/codebase” “language”) or similar.
That said, I wanted to put the first draft up in case anyone might find it useful; rough as it is, it does the job it should, however inefficiently. In short, it connects via SSH to the remote host with the code, invokes find with configurable codebase root and filename glob to locate the source files to be analyzed, and then invokes the local etags binary once for each such file and collects the result into an array which is eventually written back out to a file ‘TAGS’ in the codebase root. Then, back in Emacs, you just
M-x visit-tags-table and point to the freshly written TAGS file, and thereafter
M-.) does what it’s supposed to. A few notes:
- Since sketch.pl relies on the Net::OpenSSH library, it can take advantage of your ~/.ssh/config or equivalent, which can save a lot of effort. (Eventually, assuming I don’t just drop the draft and switch over to Elisp implementation, I’ll probably update the script to take command line arguments after the fashion of the command-line SSH client.)
- The Net::OpenSSH dependency also means this script cannot run under Cygwin, because Cygwin does not support the OpenSSH ControlMaster option; to do so requires passing open file descriptors over Unix sockets, which Cygwin currently cannot do. (Cygwin Emacs Tramp doesn’t support the scpc: and rsyncc: protocols, for the same reason.) Note: I haven’t actually tested this under Cygwin 1.7, and I can’t find a recent reference online to the problem still existing, so it may be that current versions of Cygwin no longer suffer this handicap. If you can use Tramp’s scpc: protocol in your Cygwin Emacs, then you can probably use this script too.
- The safe_open3() function defined in sketch.pl is a disgustingly comprehensive wrapper around the IPC::Open3 ‘open3′ function. I originally wrote it to support my ongoing (and so far surprisingly successful) effort toward a 100% accurate PHP dependency graphing tool, and it has found more general applicability; you are more than welcome to make whatever use of it you will, and, as with anything you find here, I’d be pleased to know your opinion of it, especially as regards potential improvements.
Update: While this script may still be useful for simpler projects, vanilla
etags isn’t sufficiently context-aware to handle class methods, so that if I have three classes which all define a method
new(), the resulting tags file doesn’t include a class name or any other means by which I can specify which
new() I’m looking for when I issue
find-tag. I suspect this means I’m going to have to write my own tag file generator — either that, or switch to imenu or CEDET Semantic, both of which I gather offer more functionality than etags in any case. Watch this space for further updates –
It is often useful under Windows to run a virtual machine as a service, for example to provide seamless management during system startup and shutdown. I found myself investigating the possibilities around same late last year, when I decided to run my own Postfix/Dovecot mail host, in a Linux VM on my Windows workstation, to work around some limitations in my previous employer’s mail infrastructure. Alas, my previous employer’s office recently went up in quite literal flames, and my workstation and mail host with it, but I still have the service wrapper scripts I wrote, and you can find them here. Benefits:
- Cleanly handles system startup and shutdown, unlike every other proposed solution I found; when Windows notifies the service wrapper of system shutdown, it shuts down the VM either by pressing the virtual power button, or by instructing VirtualBox to save the VM’s state, as you prefer. Service startup can occur in whatever fashion you implement, most likely at system start. In general, the service can be managed via the same interfaces as any other Windows service, including ‘net start/stop’, ‘sc’, the services management console, &c.
Very lightweight; the wrapper script weighs in at about one kilobyte, and while the script is running whenever the VM is, all it’s actually doing is waiting for the VM to exit — except at startup and shutdown, it consumes no CPU cycles. Caveats:
Cygwin is probably required; you might get this working under Win32 Perl (ActivePerl, Strawberry Perl, &c.), but I’ve never tried it, and it’d probably take a complete rewrite in any case. (For one thing, you won’t have cygrunsrv available, so you’ll have to use sc or equivalent — I never could get that to work, despite many attempts; the Windows console’s argument passing conventions were just too bogus to bear.)
The wrapper script’s a little rough. For example, while it handles SIGTERM correctly (that being its interface to the shutdown notice from Windows), I’m uncertain how it will behave on receipt of SIGINT, SIGKILL, &c.; it might (correctly) shut down the VM, or it might leave the whole situation in an indeterminate state. Use at your own risk; if it breaks, you get to keep both pieces. Share and enjoy!
- This code is well tested under Windows XP; though the cygrunsrv wrapper currently in svn is a bit bogus, it suffices to give the idea, and the resulting command will do what it should. It doesn’t work yet at all under Windows 7. Watch this space.
I’m not religious on the subject of operating systems; the point is to do the job in front of you, regardless of the platform you’re on. My home machine runs Windows, which with Cygwin means I have the best of all worlds: all of my hardware works like it should; I don’t have to put up with second-class citizen status for unparalleled but Windows-native software such as Microsoft Office and the Adobe Creative Suite1, and I get the Unix-flavored environment that Emacs and I need to make life worth living.
Unfortunately, running Windows also means that by default I’m stuck with a somewhat impoverished window manager. Fortunately, there are many people out there who are much better than I am at Windows-native programming, and they’re unwilling to put up with the lack of features I’ve come to appreciate in KDE on my workstation at the office. (Cubicle, really, but who’s counting?)
allSnap, a nice little piece of freeware from Ivan Heckman, brings KDE’s window snapping behavior to Windows. Options allow for windows to snap to one another, to the edges of the desktop (actually each monitor in a multi-monitor setup like mine), and to a bunch of other things I don’t have enabled; snap distance is also configurable, and a hotkey allows for temporarily disabling the snap behavior when moving windows which you don’t want to snap. The only drawback I can find is that the 32-bit and 64-bit builds are separate executables, each affecting only windows owned by processes compiled to their respective address size; that said, they happily run alongside one another, and Windows 7′s configurable system tray keeps the pair of tray icons from being clutter. (Incidentally, Office 2007 windows are managed just fine by allSnap, despite what it says on Heckman’s page.)
Dexpot, free for private, noncommercial use (and €24.90 otherwise) from Dexpot GbR, is, as desktop pagers go, a tiny god. I’ve used any number of such tools over the years, and I have never run across one which does all that Dexpot does — I expect I’m going to end up missing some of its features when I’m using my Linux box at work, rather than the other way around. Unlike every other Windows desktop pager I’ve ever tried, Dexpot integrates seamlessly with the Windows taskbar, and has hotkey support for every conceivable situation; it offers Exposé-style previewing in a couple of different flavors, separate wallpapers and background colors per desktop and per monitor, and roughly four hundred thousand more settings and options which I haven’t really had time to explore. It even supports wallpaper clocks, which I’d never even heard of before.
Both tools support Windows XP and above, possibly Windows 2000 as well, and if you, like me, favor the Linux/Unix-flavored desktop experience while preferring to work with the solid underpinnings Windows has to offer, then I recommend both allSnap and Dexpot most highly.
1 Yes, of course both of those packages offer OS X-native versions as well, but I also fancy myself something of a gamer, and the impression I have is that that’s not nearly so straightforward a thing to be on OS X as on Windows. Not having the money, the desire, or the desk space for two computers, each costing ~$2k all told, I expect I’ll be sticking with Windows for a while yet.
Having hacked up a Perl script (which will arrive here soon) that uses the otherwise pointless Scroll Lock LED as a mail notifier, I soon discovered that a blinking LED in the corner of one’s visual field is really, really annoying.
The obvious alternative would be to just turn the LED on when mail arrives and off once it’s read, but where’s the fun in that? Instead, I decided to see whether it’d be feasible to produce varying brightness from the keyboard LEDs by means of pulse-width modulation. The resulting proof of concept turns out to work pretty well.
That’s not to say it is without flaws. Most notably, there’s not all that much difference between the lower brightness levels, and the minimum available is maybe half as bright as the maximum; shortening the duty cycle any further produces flicker, though perhaps that’s as much as anything a result of not having root on the box and therefore not being able to
nice -n -20 the program. Using
nanosleep() in place of
usleep() would probably help as well, assuming nanosecond-level timing is even remotely reliable without getting special priority from the scheduler. Even that probably wouldn’t help; since all it’s actually doing is calling the X server, I suspect there’s only so much improvement to be had by tightening the timing loop.
In any case, it works well enough to become part of biff.pl, and I haven’t seen it done anywhere else so I’m posting it here for the Internet to find. Share and enjoy!
Oh, and here’s a video, which doesn’t do too poor a job at demonstrating xledpwm in action:
(PS: I’m not a C hacker; this is the first thing I’ve ever written in the language, whether for distribution or otherwise. Be gentle.)
#!/usr/bin/perl print "Hello world!\n"; exit(0);