• Sep 24 2004 4:45 PM - Version 0.21.0

    Some minor problems that prevented j from working correctly with the Java 1.5 betas are fixed in this release.

    It is now possible to use drag/drop in the sidebar buffer list to reorder the buffers, so that navigating between buffers using nextBuffer and prevBuffer (mapped by default to Alt Right and Alt Left, respectively) is more efficient. Thanks to Mike Rutter for providing the code to do this.

    By request, the command wrapParagraphsInRegion has been added. It is mapped by default to Ctrl Shift F12 in plain text and mail composition buffers. wrapParagraphsInRegion walks through the region (or the whole buffer if no region is selected) and, in effect, calls wrapParagraph on each paragraph.

    The wrap commands should now do a better job of handling lines that break on the hyphen of a hyphenated word (like "wrap-paragraph"). If the paragraph is subsequently reformatted in such a way that the line break no longer falls on the hyphen in question, the parts of the hyphenated word are now put back together properly. In previous versions of j, you were likely to end up with "wrap- paragraph", with a bogus extra space after the hyphen.

    The commands pageUpOtherWindow and pageDownOtherWindow have been added. They are mapped by default to Alt Page Down and Alt Page Up, respectively, in all modes. These commands are helpful in a split-window situation when you want to scroll the other window without switching to it.

    The commmand findOccurrenceAtDotAndKillList has been added. It is mapped by default to Ctrl Enter in List Occurrences buffers. It works like findOccurrenceAtDot, but in addition it closes the List Occurrences buffer.

    The commands shellNextPrompt and shellPreviousPrompt have been added. They are mapped by default to Ctrl Alt N and Ctrl Alt P, respectively, in shell buffers and their derivatives (including Lisp shells), and they help you find the next or previous prompt, starting from the current location of the caret.

    The command p4Log has been added. It runs the Perforce command "filelog -l" on the file associated with the current buffer.

    The command p4Diff now runs the Perforce command "p4 diff -f -du", instead of "p4 diff -du". This change means that p4Diff will display potentially useful output even if the file associated with the current buffer has not, in Perforce's opinion, been officially opened for editing.

    J's ssh-related code now recognizes "Response:" as a password prompt, in addition the to other password prompts it recognized already.

    Compilation buffers are now supported on Windows NT 4. Thanks to Pete Kirkham for pointing out that this was possible.

    In previous versions of j, there was an incorrect optimization in the display code which malfunctioned on very rare occasions and caused lines to disappear from the display, even though they were still present in the buffer (there was never any loss of data). This bug has been fixed by removing the optimization in question.

    There are a number of new features and minor improvements in Lisp mode and in Lisp shells. Thanks to Sam Steingold for help with many of these.

    This release includes version 0.0.4 of Armed Bear Common Lisp. ABCL 0.0.4 passes 17778 out of 17942 tests in the GCL ANSI Common Lisp test suite, for a nominal compliance of 99.0859%. The test suite is still not complete, however, so ABCL's actual percentage of ANSI compliance, whatever that may mean, is undoubtedly lower. In any case, version 0.0.4 represents a substantial improvement over version 0.0.3, back when it was still called Armed Bear Lisp, which passed 12986 out of 14127 tests (91.92%).

    ABCL includes a compiler, written in Lisp, that generates JVM bytecode from Lisp source. The compiler is not finished, and there are valid Lisp constructs that it doesn't know how to compile. In most situations, when the compiler encounters code that it can't compile correctly, it is smart enough to leave the code alone so that it will continue to work correctly with the interpreter. Compiled code and interpreted code can coexist happily in the same running instance of ABCL.

    The 0.21.0 binary distribution contains a compiled version of the Lisp library code (i.e. a full set of .abcl and .cls files), as well as the Lisp source files for the library code that is implemented in Lisp. If you build j from source, using either configure/make or Ant, the Lisp library code will be compiled as part of the build. There is no longer any need to do COMPILE-SYSTEM manually.

    ABCL 0.0.4 is better at some things than others. In particular, it's not very good at CLOS. ABCL's CLOS correctness is reasonable, but its CLOS performance is terrible (for one thing, the compiler doesn't even attempt to compile generic functions). This deficiency is due more to simple neglect than to any intrinsic limitation, and the CLOS implementation should improve in future releases.

    You can start ABCL from within j by doing Alt X, "abcl", or by selecting "Run Lisp as Separate Process" from the Lisp menu. Note that the "Run Embedded Lisp" menu selection opens a Lisp shell using an instance of ABCL that runs in the editor process; it only makes sense to do this if you're planning to interact with the running instance of j, which is not normally the case. If you just want to experiment with ABCL, "Run Lisp as Separate Process" (or Alt X, "abcl") is your friend.

    If you're truly adventurous, you can also start ABCL from within j by doing Alt X, "slime". J's version of slime is adapted from the "Superior Lisp Interaction Mode for Emacs", originally written by Eric Marsden, Luke Gorrie and Helmut Eller. Slime-for-j is less than a month old, so it is nowhere near as robust or featureful as slime-for-emacs, but in principle it offers more functionality than Alt X, "abcl". In particular, the tab key can be used for symbol completion, function argument lists are displayed in the status bar when you type a space, and Alt . should work to find function definitions (if you've built ABCL from source). In addition, the evaluation of forms and regions in Lisp source files makes an attempt to set *PACKAGE* to the right thing first. I don't think any of these features works 100% correctly yet, but even so, slime-for-j feels like an improvement over the basic Lisp shell functionality available in previous versions of j. For more information, see slime.lisp.

    More (and more timely) details about recent changes in j and ABCL are available on the J Development Mailing List, the archives of which are here (or on Gmane).

  • Oct 23 2003 10:46 AM - Version 0.20.2

    This release introduces a number of minor editor improvements and fixes a few minor bugs.

    In addition, this release includes (at no extra charge) version 0.0.3 of Armed Bear Lisp. ABL now passes 12986 of the 14127 tests in the GCL ANSI Common Lisp test suite (91.92%), up from 7918 of 12842 tests (61.66%) at the end of June. The test suite doesn't cover everything, however, so the percentage of ANSI CL compliance (if that concept is meaningful at all) is really quite a bit lower. And as the saying goes, the last 1141 test failures are always the hardest ones to fix.

    There is a bit more glue in this release to support using Lisp to script editor functionality. Both interface and implementation are still very much subject to change, but what's there now can be found in LispAPI.java and j.lisp, and there are a couple of real-world examples in the examples directory.

    By request, starting with this release, antialiasing is applied to menus, toolbars, dialogs, etc., as well as to the text in the edit window.

    To enable antialiasing, add this line to ~/.j/prefs:

          antialias = true

    Antialiasing is off by default.

    In previous versions, j has followed a policy of not relocating the caret to stay in the edit window if you did mousewheel- or scrollbar-based scrolling (or used windowUp or windowDown).

    A problem with this approach is that if you scroll a few pages and decide you like where you've ended up, you can't just start typing or hit a cursor key, because that will take you summarily back to whence you came before you started scrolling; you need to click in the edit window first, and it's easy to forget to do this.

    Despite this problem, this behavior was (I seem to recall) the standard behavior of most Windows-based editors at some point in the distant past when I paid more attention to Windows-based editors than I do today.

    By request, this behavior is changed in this release.

    Generally speaking, the caret is now forced to stay with you in the edit window when you scroll.

    So, for example, if the caret scrolls off the top of the window, it gets reeled back in and placed in the leftmost column of the top line, where it stays while the text continues to scroll up, as long as you keep scrolling.

    If you wander away in this manner and do want to return to your starting point, undo (Ctrl Z) is your friend.

    There is one exception to this new behavior: if a selection is active in the edit window, scrolling does not move the caret.

    If you decide you prefer the old behavior, you can have it back by adding this line to ~/.j/prefs:

          scrollCaret = false

    By request, the command selectToMarker has been added. You can now drop a bookmark by doing (for example) Alt 1 at the location of interest, then go somewhere else in the same file and do Alt X, "selectToMarker 1", and the region between the caret and marker 1 (which is the same thing as bookmark 1) will be selected.

    I didn't map "selectToMarker 1" to Ctrl Shift 1, because (for one thing) Ctrl Shift 9 is already spoken for in certain modes (it's mapped to insertParentheses in Java and Lisp modes, for example).

    And I didn't map selectToMarker (by itself) to any key combination either, because no compelling mapping came to mind. Suggestions are welcome. You can always do

          (global-map-key "Alt F11" "selectToMarker")
    in ~/.j/init.lisp, if you find Alt F11 compelling (for example).

    The commands dropTemporaryMarker, gotoTemporaryMarker, and selectToTemporaryMarker have been added, mapped by default to Alt \, Ctrl \, and Ctrl Shift \, respectively. These commands do what their names suggest and are like the similarly named bookmark commands, except that they act on a single, global temporary marker which is recycled for each use, and there is no prompting for confirmation when you try to re-use the marker.

    Since the beginning of time, findInFiles and replaceInFiles have used the Java definition of a word (from a delimiter perspective) when the "Whole words only" checkbox was checked, which works well enough for Java, C and C++.

    This behavior is suboptimal, however, if you're searching (say) Lisp files, where searching for the word "complete" with "Whole words only" checked would find a match in the string "ilisp-complete", which is clearly wrong.

    In this respect, the behavior of findInFiles was also not consistent with the behavior of find in a single buffer, which used the method isIdentifierPart() from the mode of the buffer to determine whether a particular substring match was actually word-delimited.

    This release makes an attempt to remedy this deficiency.

    The findInFiles dialog now offers a "Mode" combo box if you check the "Whole words only" option.

    The combo box should come up prefilled with a plausible mode, based on the contents of the "Files" textfield. If there are multiple entries in the "Files" textfield, the first one is used to set the default. If the contents of the textfield don't correspond to a known mode, Java mode is used as the default.

    You can change the mode in the combo box to force the search to follow the word-delimiter rules of a different mode of your choosing, but this should not be necessary in most cases.

    The search then follows the word-delimiter rules of the specified mode. In addition, the occurrences list uses the rules of the specified mode to control its highlighting of the found pattern (which was another inconsistency in previous versions).

    Since the beginning of time, the command findMatchingChar has been mapped by default to Ctrl M. This command finds the match for the parenthesis, brace, or bracket at (or near) the current location of the caret.

    In previous versions, if what you were trying to match was a left delimiter ('(', '{', or '['), the caret would be placed to the left of the matching right delimiter (')', '}', or ']').

    This is well and good, but it is inconsistent with the way matching delimiters are highlighted when the highlightBrackets preference is turned on: the right delimiter is highlighted when the caret is to the right of it, not to the left of it.

    So, starting with this snapshot, findMatchingChar puts the caret to the right of, rather than to the left of, the matching delimiter, if the matching delimiter is a right delimiter (')', '}', or ']').

    Now, if you have the highlightBrackets preference turned on, both delimiters will be highlighted at both ends of the match operation.

    I don't think this will cause any confusion once you get used to it, but it might take a little getting used to.

    While I was thinking about this issue, it occurred to me that it might also be useful to provide a way to select the region from one delimiter to another, so I've added the command selectSyntax, which does just that.

    selectSyntax is mapped by default to Ctrl Shift M, which makes a certain amount of sense from a mnemonic point of view, considering the use of Ctrl M for findMatchingChar and the common application of Shift as a modifier meaning "select this". Sadly, however, this forces the previous tenant of Ctrl Shift M, showMessage, to move to Ctrl Alt M, which might even have made more sense to begin with, but that's what hindsight can do for you.

    In Lisp mode, Ctrl Shift M is now mapped by default to lispSelectSyntax, which has the added virtue that if a region is already selected, the selection is extended to the enclosing syntactic expression, making it useful (in some situations) to do Ctrl Shift M two (or more) times in a row.

    By request, you can now disable the paste command's auto-detection and special handling of line blocks by adding this line to ~/.j/prefs:

          autoPasteLines = false
    or by adding this line to ~/.j/init.lisp:
          (setf (variable-value 'auto-paste-lines :global) nil)

    By request, when you use the "here" dynamic alias as part of the compile command (e.g. "javac here"), the substituted string (to wit, the name of the file in the current buffer) is now enclosed in double quotes if it contains any embedded spaces.

    By request, a top-level "Lisp" menu has been added, to make it easier (or possible) to figure out how to run Lisp from within j.

    The new menu is invoked with the Alt L key combination, so the previous occupant of Alt L, listOccurrences, has been moved to Ctrl L.

    Ctrl L, moreover, was previously assigned to listFiles, which is really listOccurrences for findInFiles, so listFiles has been moved to Ctrl Shift L, which makes more sense in the big picture anyway (cf. Ctrl F, Ctrl Shift F, Ctrl R, Ctrl Shift R).

    Ctrl Shift L, however, was previously assigned to sidebarListTags, which all along would have been assigned to Ctrl Shift T, were it not for an odd bug in some ancient version of Java that prevented the Ctrl Shift T mapping from being recognized at all. That version of Java being no longer in the game, sidebarListTags has now been moved to Ctrl Shift T, where it rightfully belonged from the beginning.

    This is normally where I say, "All bugs reported to j's official bug tracker on SourceForge have been fixed for this release," but that's not quite true this time. There's one unfixed bug, involving incorrect indentation in C mode after a particular construct in a #define/#endif block.

    More (and more timely) details about recent changes are available on the J Development Mailing List, the archives of which are here (or on Gmane).

  • Jul 8 2003 9:48 AM - Version 0.20.1

    This release fixes several non-critical bugs in 0.20.0. All bugs reported to j's official bug tracker on SourceForge have now been fixed.

    Starting with this release, BeanShell is no longer bundled with j, and init.bsh is no longer loaded at startup. Use init.lisp instead.

    More details about recent changes are available on the J Development Mailing List, the archives of which are here (or on Gmane).

  • Jun 26 2003 10:56 AM - Version 0.20.0

    Java 1.4 or later is now required.

    This release officially introduces j's new built-in extension language, which has been lurking in the code since version 0.18.1. At that time, the language itself was an ad-hoc, bug-ridden and slow implementation of half of Common Lisp. Since then, it has gotten faster (by a factor of 2), and it's now up to 61% of Common Lisp (it passes 7918 of the 12842 tests in the GCL ANSI test suite). I don't think it's particularly bug-ridden, but it's still very ad hoc, in terms of exactly what features have been implemented.

    Initially, the only functionality that's officially supported is exactly the same functionality that has been supported since version 0.11.0 for BeanShell and init.bsh. More details are available in the documentation; there are also a couple of relevant example files in the examples directory of the distribution.

    In the future, the plan is to extend the extension language to provide editor-specific functionality that's more or less in the spirit of Emacs Lisp (arguably, j is architecturally closer to Hemlock than to Emacs, but that's not important now).

    Future releases of j will no longer bundle BeanShell or load init.bsh, so if you're doing customizations in init.bsh, this would be a good time to move them into init.lisp. Converting uses of the officially supported API should be absolutely trivial. If you have trouble, or if you're using BeanShell beyond the scope of the official API and would like to convert your code, let me know and I'll try to help.

    Note that j's Lisp can call arbitrary Java code, so in principle it should be possible to do anything in Lisp that you might have been doing in BeanShell.

    Since Java 1.4 includes an XML parser, j no longer bundles Ælfred. You can still use an external XML parser if you prefer.

    The command xmlValidateBuffer has been added, which validates the contents of the current buffer against its DTD. Both xmlValidateBuffer and xmlParseBuffer now use a transient output buffer to display errors and warnings. The transient output buffer works just like a compilation buffer in programming modes: the commands nextError, previousError, and showMessage are available to help you make sense of the situation there.

    Some modes (including XML mode) now have a "Mode" menu, to make it easier to find mode-specific features, such as the ones described in the preceding paragraph.

    Early on, j's support for customized key mappings involved writing out a keymap file (using writeGlobalKeyMap or writeLocalKeyMap), editing it to taste and then pointing to it from ~/.j/prefs.

    This approach works and is still supported, but it's unwieldy to have to do all that if you just want to change one or two key mappings.

    The solution to that problem was to support ad hoc key mappings, first in init.bsh (which is deprecated as of the current release) and now in init.lisp.

    This led to a new problem, however: if you're using custom keymaps, and also have some ad hoc mappings in init.lisp, then, when you edit a keymap, the reloading of that keymap is likely to discard some or all of the ad hoc mappings.

    Starting with this release, by default, saving ~/.j/prefs (or the file containing a custom keymap that's pointed to in ~/.j/prefs) no longer automatically reloads the affected keymap(s) or makes any change to the key mappings that are in effect, so your ad hoc key mappings are (by default) preserved.

    There's a new command, reloadKeyMaps, that does what its name suggests: all the custom keymaps (or j's internal defaults, if there are no custom keymaps) are reloaded, and any ad hoc key mappings are discarded.

    If you do use custom keymaps and don't care about ad hoc key mappings, you can add this line to ~/.j/prefs:

            autoReloadKeyMaps = true
    and things will work just like they used to: your keymaps will be reloaded automatically when you edit them (or when you edit ~/.j/prefs).

    While I was at it, I added another new command, defaultKeyMaps, that discards all custom key mappings (including ad hoc key mappings) and restores j's internal defaults.

    The command apropos has been added. It's not mapped to any keystroke by default, but it's available on the Help menu.

    The preference patchMode has been added. If you specify an extension such as ".orig" as the value for this preference, the specified extension is used to create the initial backup when a file is first edited (so, for example, "foo.java" gets backed up for the first time in "foo.java.orig"). The diff command, when invoked with no arguments, now looks for the .orig file corresponding to the file in the current buffer and diffs the current contents of the buffer against that file. You can reset this behavior by deleting all the .orig files.

    Thanks for your support.

  • May 28 2003 10:09 AM - Version 0.19.0

    Other things being equal, this will be the last release of j that runs with Java 1.3. For future releases, Java 1.4 or later will be required.

    This release formally introduces j's built-in JPDA-based Java debugger.

    The debugger has actually been lurking quietly in the code base for a long time as an undocumented feature. It is now documented in doc/jdb.html and doc/jdbcommands.html. From within j, Alt X, "help jdb" (or Alt X, "help jdb.html") should get you started.

    (Note that there are better debuggers than this one; the main advantage of this debugger is its integration with j. If you need a more powerful debugger, consider JSwat.)

    In order for the debugger to work, tools.jar (which is part of the JDK) needs to be in j's CLASSPATH, which will not be the case if you just do "java -jar j.jar". See the installation section of doc/jdb.html for full details.

    In other news, j now opens .diff and .patch files in diff mode by default. Patches embedded in mail messages are now syntax-highlighted appropriately.

    The command diff has been added, available via Alt X. For useful output this command requires two filenames. One of them can be "%", which is a dynamic alias for the name of the file in the current buffer. For example, at the command prompt after Alt X:

            diff -ub % ~/backup
    This command line compares the file in the current buffer against its backup copy in the directory ~/backup. You need to supply the complete command line at the command prompt. If you don't explicitly specify any switches, j will run "diff -u"; diff mode works best with unified diffs.

    The preference restrictCaret now defaults to true, meaning that the caret's perambulations are restricted to the actual text on the line. If you prefer the virtual space concept, which was the old default, add this line to ~/.j/prefs:

            restrictCaret = false
    The command killWindow is now mapped by default to Ctrl Shift F10, which makes some sense when you consider that unsplitWindow is mapped by default to Shift F10.

    The command dirOpenFileAndKillDirectory has been added. It is mapped by default to Ctrl Enter in directory buffers. It does what its name suggests.

    The preference confirmSend is now true by default.

    All bugs reported to j's official bug tracker on SourceForge have been fixed for this release, as well as quite a few that never made it that far.

    Plus a larger-than-usual accumulation of code cleanups, subliminal enhancements, and minor adjustments to the user experience.

    Thanks for your support.

  • Mar 31 2003 11:53 AM - Version 0.18.1

    This release fixes a number of non-critical bugs. The worst of these caused a memory leak in certain situations when j kept a reference to a closed buffer for no good reason. Most of the others were either of very minor consequence or very hard to trigger.

    Officially, there isn't much new functionality in this release. Syntax highlighting and indentation should work a bit better in Lisp mode. The command backwardSexp, mentioned in the documentation for 0.18.0, has now actually been implemented (and mapped to Ctrl Alt B in Lisp mode, as the aforementioned documentation promised).

    Unofficially, the infrastructure for j's new extension language is present for the first time in this release, albeit a bit sub rosa. The language itself, at the moment, is an ad-hoc, bug-ridden and slow implementation of half of Common Lisp, but it does try to conform to the official ANSI specification. More information is available in the archives of the j development mailing list (for example here).

    Thanks for your support.

  • Jan 8 2003 9:04 AM - Version 0.18.0

    By default, the caret now blinks.

    You can make it stop by adding this line to ~/.j/prefs:

            blinkCaret = false

    Since the beginning of time, the openFile command (mapped by default to Ctrl O) has provided filename completions when you type in part of the filename and press the Tab key.

    In previous versions, you had to keep hitting the Tab key to cycle through all of the possibilities.

    Starting with this release, this feature has a fancier UI, which is enabled by default.

    There are two new preferences to control the new behavior (shown here with their default values):

            showCompletionList = true
            selectCompletion = true

    You can have things the old way, with no completion list and no fancy UI, by adding this line to ~/.j/prefs:

            showCompletionList = false

    When the completion list is enabled, and when selectCompletion is true (which is the default), the part of the filename that you didn't actually type (i.e., the part that's supplied by the completion facility) is selected in the location bar textfield, so that the next character you type (if you keep typing) replaces the completion, as if it never happened. (This is probably the behavior you want, if you like this sort of thing at all.)

    Regardless of the value of selectCompletion, you can always use Escape to clear the completion (and remove the completion list), in case none of the possibilities presented to you is exactly what you had in mind.

    The command renumberRegion has been added. It's not mapped to any key by default, but it's available via executeCommand (Alt X).

    renumberRegion changes the first number in each line of the selected region so that the it is one more than the first number in the preceding line. By default, the smallest value in the entire region is used as the value for the first line. The order of the lines is not changed. Only the first number in each line is considered, and lines that don't contain a number at all are ignored.

    For example, suppose you start with a region that looks like this:

            private static final int DEFUN       = 52;
            private static final int DEFVAR      = 6;
            private static final int DO          = 17;
            private static final int DOLIST      = 81; // Not 82!
            private static final int IF          = 9;
            private static final int LAMBDA      = 1;
            private static final int LET         = 3;

    When invoked with no arguments, renumberRegions starts by looking at the first number in each line of the region to find the smallest value (which in this case is 1). The first number in the first line of the region (52) is replaced with this value (1), and the first number in each subsequent line is changed so that it is one more than the first number on the preceding line. So the region ends up looking like this:

            private static final int DEFUN       = 1;
            private static final int DEFVAR      = 2;
            private static final int DO          = 3;
            private static final int DOLIST      = 4; // Not 82!
            private static final int IF          = 5;
            private static final int LAMBDA      = 6;
            private static final int LET         = 7;

    Note that the comment ("Not 82!") is unchanged, since 82 is not the first number on that particular line.

    You can also explicitly specify what number to start with by providing a numeric argument with the command. For example, if you do Alt X, "renumberRegion 100", the region ends up looking like this:

            private static final int DEFUN       = 100;
            private static final int DEFVAR      = 101;
            private static final int DO          = 102;
            private static final int DOLIST      = 103; // Not 82!
            private static final int IF          = 104;
            private static final int LAMBDA      = 105;
            private static final int LET         = 106;

    The code that does syntax highlighting in Lisp mode has been completely rewritten.

    The default list of "keywords" (which in this context is a confusing term) in LispMode.keywords now supports ANSI Common Lisp, and ANSI Common Lisp only, rather than the previous hodgepodge. After all, no one in his right mind uses j to edit Emacs Lisp... ;)

    Symbols representing official Common Lisp functions (e.g. "list") are now highlighted as keywords only when they are the first element of their containing form (and only when the containing form itself isn't quoted). So, for example, "list" is highlighted in "(list 1 2 3)", but not in "(member x list)", which is as it should be. (There are still some cases where things aren't quite perfect; "list" is still erroneously highlighted in "(let ((list x)) ...)", for example.)

    There are four new syntactic elements (quoting here from Kodiak):

            LispMode.color.substitution             = 153 0 153
            LispMode.color.punctuation              = 102 102 102
            LispMode.color.parenthesis              = 102 102 102
            LispMode.color.secondaryKeyword         = 0 102 153

    substitution is used for symbols preceded by "," or ",@" within a backquoted expression.

    punctuation is used for backquote itself, and for "," and ",@".

    parenthesis is used for parentheses.

    secondaryKeyword is used for lambda-list keywords ("@optional", "@rest", etc.) and symbols that start with ':' (i.e. symbols in the keyword package).

    I've updated Kodiak, AnokhaClassic and Freefloater to support the new syntactic elements. Sensible fallbacks are in place, so you shouldn't notice anything particularly amiss if you use a different theme, but the new syntactic elements won't be highlighted in the new way if you're using an old theme.

    (The real point of color.parenthesis, BTW, is to help you overcome your fear of parentheses by choosing a color that makes them less conspicuous, and hence less fearsome.)

    The command hyperspec has been added. It's mapped by default to Alt F1 in Lisp mode.

    hyperspec displays the Common Lisp HyperSpec documentation for the symbol at the current location of the caret.

    The documentation is displayed in a second window, splitting the current window if necessary. This transient window can be dismissed using the command escape, mapped by default to the Escape key.

    You can also invoke the hyperspec command with Alt X, giving the symbol name as an argument (e.g. Alt X, "hyperspec mapcar", or Alt X, "hs mapcar", "hs" being a built-in abbreviation for "hyperspec").

    The Common Lisp HyperSpec is available for download here:

          http://www.lispworks.com/reference/HyperSpec/index.html

    or:

            apt-get install hyperspec

    For the hyperspec command to work, you may need to add a line to your preferences file specifying the location of the HyperSpec root directory on your system:

            clhsRoot = /usr/share/doc/hyperspec

    (This should not be necessary on a Debian system.)

    Finally, all bugs reported to j's official bug tracker on SourceForge have been fixed (or otherwise dealt with) in this release.

  • Nov 18 2002 4:47 PM - Version 0.17.2

    This release fixes three problems with 0.17.1.

    To start with the worst of the three, if you were running Sun Java 1.4.1 fcs on either Windows or Linux, the version of j.jar in the 0.17.1 binary distribution would fail to load, although it did work with Sun 1.4.1_01 and many other versions of Java (I haven't tested them all). This was a build problem rather than a bug in the code.

    For this release, I've verified that the version of j.jar in the binary distribution loads correctly (in my environment, at least) with Sun 1.4.1 fcs, Sun 1.4.1_01, and Blackdown 1.4.1 beta on Linux, and with Sun 1.3.1_05, Sun 1.4.0_02, Sun 1.4.1 fcs, and Sun 1.4.1_01 on Windows 2000. Note that Java 1.3 or better is required in any case; on platforms where Java 1.4.1 (or 1.4.1_01) is available, that's what you should use.

    The second problem was that loadSession was broken in both 0.17.0 and 0.17.1. It should work again now.

    Finally, on Unix, directory buffers parse the output of "ls -l" in order to provide additional information such as file permissions and user/group ownership. In at least one situation (on a German system running SuSE 8.1), "ls -l" was apparently using the "long-iso" time style by default, which confused j's parser and prevented directory buffers from working correctly. Starting with this release, the parser should be smart enough to handle this situation.

    Thanks for your support.

  • Nov 12 2002 7:39 AM - Version 0.17.1

    This release introduces custom toolbars, a shellCommand feature (on Linux only), and a number of minor improvements, including support for automatic indentation in Lisp mode. There are also fixes for a large number of bugs, most of them minor or rarely triggered or both.

    By request, j now supports custom toolbars.

    To customize your Java mode toolbar (for example), create an XML file that looks something like this:

            <?xml version="1.0"?>
            <toolbar>
                <button label="New" icon="stock_new.png" command="newBuffer"/>
                <button label="Open" icon="stock_open.png" command="openFile"/>
                <button label="Save" icon="stock_save.png" command="save"/>
                <button label="Close" icon="stock_cancel.png" command="killBuffer"/>
                <separator/>
                <button label="Undo" icon="stock_undo.png" command="undo"/>
                <button label="Redo" icon="stock_redo.png" command="redo"/>
                <separator/>
                <button label="Cut" icon="stock_cut.png" command="killRegion"/>
                <button label="Copy" icon="stock_copy.png" command="copyRegion"/>
                <button label="Paste" icon="stock_paste.png" command="paste"/>
                <separator/>
                <button label="Find" icon="stock_search.png" command="find"/>
                <button label="Replace" icon="stock_search_and_replace.png" command="replace"/>
                <separator/>
                <button label="Directory" icon="stock_index.png" command="dir"/>
                <button label="Home" icon="stock_home.png" command="dirHomeDir"/>
                <button label="Inbox" icon="mail.png" command="inbox"/>
                <separator/>
                <button label="Compile" icon="stock_refresh.png" command="compile javac here"/>
                <separator/>
                <button label="Exit" icon="stock_exit.png" command="quit"/>
            </toolbar>
        

    You can give this file any filename you want. For the purposes of this example, let's say it's "/home/peter/tb.xml".

    Then add a line like this to ~/.j/prefs:

            JavaMode.toolBar = /home/peter/tb.xml

    And you're done.

    Compared to the default Java mode toolbar, the custom toolbar defined above has one additional button for "Compile". This button invokes j's "compile" command with the argument(s) "javac here" to compile the file that's open in the current buffer ("here" being a dynamic alias for the current file).

    If the icon filename is a relative path (or a simple filename with no directory prefix at all), it's assumed to be relative to (or in) src/org/armedbear/j/images. You can also specify an absolute pathname for the icon, so you don't have to keep the icons for your custom toolbar in j's source tree.

    By request, the command shellCommand, not mapped by default but available via Alt X, has been added, on Linux and similar platforms only (i.e. not on Windows).

    shellCommand prompts for a command and then executes that command using /bin/sh. The output of the command (if any) is presented in a transient output buffer.

    So, for example, you can do Alt X, "shellCommand ls -l" to get a directory listing of the current directory, or Alt X, "p4 opened" to see what files you have checked out from Perforce.

    Note that you can append the shell command itself to the string you feed to Alt X, as in Alt X, "shellCommand ls -l". If you just do Alt X, "shellCommand", by itself, j will prompt you for the command to run.

    The shell command you specify is executed in the editor's current directory, which is normally the parent directory of the file that's open in the current buffer, or the user's home directory if the current file is remote or if there is no file associated with the current buffer.

    You can do real damage with an errant shellCommand, so caution is advised. It's much safer to perform delicate operations in a shell buffer (or even a real xterm), where the light is better and you can see what you're doing.

    The property reorderBuffers, which controls reordering of buffers for the sidebar buffer list, was a boolean in previous versions of j. By request, it is now an integer, to support additional functionality.

    If reorderBuffers is 0, no reordering is performed; buffers are left in the order in which they were originally opened. (In previous versions, this behavior was specified by a value of false.)

    If reorderBuffers is 1, buffers opened (or activated) by openFile (and similar commands) are placed after the current buffer in the list. (In previous versions, this behavior was specified by a value of true.)

    If reorderBuffers is 2, reordering is also performed when you use the sidebar buffer list to switch to a different buffer. (This behavior is new in this release.)

    Buffers are never reordered when you use nextBuffer or prevBuffer to switch between buffers.

    If the property sortBufferList is true, reorderBuffers is ignored.

    The idea of buffer reordering is to keep the buffers that you're actively using close to one another in the buffer list, so you have some hope of navigating usefully among them with nextBuffer and prevBuffer.

    Lisp mode now supports automatic indentation using the commands tab, mapped by default to the Tab key, and newlineAndIndent, mapped by default to Enter. It's not perfect, but it's better than nothing.

    The Lisp mode tagger now skips over #|...|# comments, as it should.

    The C and C++ taggers (and formatters) are no longer quite as likely to be confused by preprocessor continuation lines.

    iList, an indispensable command that is mapped by default to Ctrl F6 in C and C++ modes, now puts up an hourglass to reassure the user while it considers the situation.

    wrapParagraph, mapped by default to F12 in mail composition buffers (and elsewhere too), now understands quoted text in mail messages, i.e. lines that begin with "> " or "> > " or "> > > ", etc. This means you can now use F12 to reformat quoted sections (or excerpts therefrom) in mail messages.

    describeKey, mapped by default to Alt K, now describes ad hoc key mappings correctly.

    This release also contains an unusually large number of bug fixes, mostly for bugs that were quite unlikely to occur in any event. The worst one was a problem with undo that made it impossible to undo the replay of a recorded macro that used the up or down cursor keys. This bug is now fixed, along with a number of others that you were even less likely to hit.

    More details about recent changes in j are available on the J Development Mailing List, the archives of which are here.

  • Sep 23 2002 9:14 PM - Version 0.17.0

    This release introduces persistent registers for storing text, an alignStrings command, new navigational behavior related to findInFiles, and a number of other minor improvements.

    Starting with this release, j requires Java 1.3 or later. Java 1.4.1 is highly recommended if it's available for your platform.

    Serious editors like vi, emacs and jEdit all support the concept of registers, which are basically named receptacles for storing text.

    This release adds this functionality to j.

    Unlike the other editors mentioned, j's registers persist across sessions.

    There are five new commands: saveToRegister, insertRegister, editRegister, clearRegister and listRegisters.

    These commands do what their names suggest. They're not mapped to any keystrokes by default, but they're available via executeCommand (Alt X).

    The way all of this works is that you highlight a selection and then do (for example) Alt X, "saveToRegister a". The name of the register (in this example) is "a". "saveToRegister a" copies the selected region to register a.

    Register names must be lower-case letters (a-z). That's "be", not "be composed of", so you get 26 registers.

    Once you've put something in register a, you can paste it somewhere by doing Alt X, "insertRegister a".

    Alt X, "editRegister a" opens a buffer so you can edit the contents of register a.

    Alt X, "clearRegister a" deletes the contents of register a, leaving it empty again.

    Using registers tends to be awkward without having these commands mapped to keystrokes. I'll be happy to provide default mappings for these commands as soon as someone suggests a scheme which is reasonably mnemonic and not too badly in conflict with anything else.

    Since that may never happen, abbreviations are provided in this release for the more commonly used register commands: you can use sr for saveToRegister, ir for insertRegister, and lr for listRegisters.

    So, for example, you can save the currently selected region to register x by doing Alt X, "sr x", and later paste it somewhere else with Alt X, "ir x".

    If, like me, you can't remember from one day to the next what's in your registers, listRegisters (lr for short) is your friend.

    lr is a bit like listOccurrences or listMatchingTags. In the lr output buffer, Enter (or Ctrl Shift G) opens a buffer so you can edit the contents of the corresponding register. Ctrl Enter inserts the contents of the current register at the location of the caret in the other window, provided that a second window is in fact open in the same frame (which is likely to be the case). Delete (that is, the Delete key) deletes the contents of the current register (i.e. the register at the location of the caret in the lr output buffer).

    The command alignStrings is also new in this release. Like the register commands, it's not mapped to any keystroke by default, but it's available via executeCommand (Alt X).

    alignStrings prompts for a regular expression and aligns the first occurrence of the specified regular expression in each line of the selected region.

    For example, suppose you start with a region that looks like this:

    
            private static final int STATE_VARIABLE = STATE_LAST + 1;
            private static final int STATE_HERE_DOCUMENT = STATE_LAST + 2;
            private static final int STATE_POD = STATE_LAST + 3;
            private static final int STATE_REGEXP_DELIMITER = STATE_LAST + 4;
            private static final int STATE_REGEXP = STATE_LAST + 5;
            private static final int STATE_SUBST = STATE_LAST + 6;

    If you specify "=" as the regular expression, alignStrings will make the region prettier by aligning the "=" in each line, like this:

    
            private static final int STATE_VARIABLE         = STATE_LAST + 1;
            private static final int STATE_HERE_DOCUMENT    = STATE_LAST + 2;
            private static final int STATE_POD              = STATE_LAST + 3;
            private static final int STATE_REGEXP_DELIMITER = STATE_LAST + 4;
            private static final int STATE_REGEXP           = STATE_LAST + 5;
            private static final int STATE_SUBST            = STATE_LAST + 6;

    alignStrings ignores lines that don't contain the specified regular expression, so with a little care you can even use it to reformat regions that contain embedded comment lines (for example).

    For a while now, findInFiles has worked by sending its output to a transient output buffer that gets displayed in the other window of the current frame (splitting the current window if necessary).

    Starting with this release, some new behavior has been added to facilitate navigation in this situation.

    The new behavior only comes into play if:

    1. the last search in the current editor was findInFiles

    2. the findInFiles output buffer is currently displayed in the other window of the current frame

    If these conditions are met, j now tries to make the location of the caret in the findInFiles output buffer follow along with the commands findNext (mapped by default to Ctrl G and F3) and findPrev (mapped by default to Ctrl H and Shift F3) when these commands are carried out in the editable buffer in the other window.

    Currently the algorithm to do this is not very smart, so things will very likely get out of sync if you make significant changes to the editable buffer as you go along. This deficiency is basically harmless, since that was the old behavior at all times.

    In addition (and this is the real point), once you get to the end (or beginning) of the current buffer with findNext or findPrev, the next invocation of findNext or findPrev, instead of failing the search, will continue on with the next (or previous) occurrence in the findInFiles output list, which will be in a different file. (Note that this may not in fact be an actual occurrence of the string in question, by the time you get there, if the file in question has been modified since the findInFiles output list was generated.)

    This is extremely useful if you're looking for occurrences of a particular string in a big set of files in order to make changes that are more complicated than can be accomplished by a simple multifile search-and-replace operation.

    This new behavior happens automatically (if the aforementioned conditions are met), and the only way to turn it off (and force findNext and findPrev to fail at the end or beginning of the current buffer) is to use Escape to get rid of the findInFiles output buffer. This is not such a big deal, since you can always get the output buffer back with Ctrl L.

    Note that this trick only happens when both the editable buffer you're doing findNext or findPrev in and the findInFiles output buffer (in the other window) are in plain view, and only when findInFiles is the current search (i.e. when you haven't done any other search since doing findInFiles).

    You can now use the Meta key in j's keymaps. Thanks to Thomas Stromberg for submitting a patch to enable this functionality.

    Files are now saved in place on all non-Windows platforms. The main consequence of this change is that file permissions and ownership are now preserved correctly when you save a file on MacOS X (which was not the case with prior versions of j).

    J now recognizes MacOS X as a Unix platform, so your directory buffers should now appear by default in "ls -l" format.

    Some folks have reported odd display problems with MacOS X 10.2. If you encounter this sort of thing, a possible workaround is to disable hardware acceleration when starting j:

              java -Dcom.apple.hwaccel=false -jar j.jar

    The support for displaying embedded images in mail messages and web pages has been improved. Scrolling is much less exciting now.

    In previous versions, automatic indentation in PHP mode was badly broken unless you happened to have opened some other file in Java mode first. This bug has been fixed.

    In addition, a number of relatively minor bugs have also been fixed, many of them having to do with automatic indentation (or the highlighting of matching braces) under adverse circumstances.

    Finally, the toolbar icons have been updated for this release, using a new set from the GNOME 2 Icon Project.

    More details about recent changes in j are available on the J Development Mailing List, the archives of which are here.

  • Sep 4 2002 7:36 AM - Version 0.16.4

    Reading mail has a different feel in this release. By default, messages are now opened in a split window.

    In mailbox mode, Enter is now mapped to mailboxReadMessageOtherWindow, which (as its name suggests) displays the message in another window, splitting the current window if necessary. This second window is roughly analogous to what some mail clients call a preview pane.

    By default, the original window is split in half, which may not be exactly ideal. You can adjust things by dragging the window divider up or down, and j will remember the position of the window divider and restore it correctly the next time mailboxReadMessageOtherWindow splits the window, so your preview pane will continue to be whatever size you've set, even across sessions.

    This remembering of the divider position only applies to the preview pane and mailboxReadMessageOtherWindow. Other commands that split the window continue to split it in half, and manual adjustments to the divider position in other split-window situations are not remembered.

    You can use the command escape, mapped by default to the Escape key, to dismiss the preview pane and restore a full-height view of the mailbox.

    (The command mailboxReadMessage, which was mapped by default to Enter in mailbox mode prior to this release, is now mapped to Ctrl Enter, so if you prefer a full-height message buffer, Ctrl Enter is your friend.)

    The command sortByThread, introduced in version 0.16.2, was badly named. Threads are not a way of sorting mailboxes, exactly; they're a way of grouping messages. The sibling messages in a thread can (in theory) still be sorted in various other ways (by sender, by date sent, by size, etc.).

    So the command sortByThread has been replaced by the command toggleGroupByThread, which does what its name suggests. The View menu in mailbox mode has been updated accordingly.

    The command sortByDateSent has also been removed. Currently j doesn't support any sort order other than date sent, so there's really nothing for sortByDateSent to do.

    To sum up, sortByThread (in previous versions) has been replaced by checking the "Group Messages By Thread" checkbox; sortByDateSent (in previous versions) has been replaced by unchecking the "Group Messages By Thread" checkbox. toggleGroupByThread is the command behind the aforementioned checkbox; it's not mapped to any keystroke by default but you can invoke it via Alt X.

    By request, this release introduces automatic header beautification in message mode.

    This means that by default, message headers now appear with the header names right-justified, and in most cases the header values are wrapped at 74 columns. ("In most cases" means the wrapping happens deliberately with the address lists for "To" and "Cc", which are most likely to have problems with line length; the subject, date and "From" header are normally short enough to begin with.)

    Headers are beautified by default. If you like your headers raw, add this line to ~/.j/prefs:

            beautifyHeaders = false

    If you turn on raw mode (Shift R, messageToggleRaw) or full header mode ('h', messageToggleHeaders), you'll see the raw headers even if beautifyHeaders is true.

    By request, messageViewAttachment is now mapped by default to Enter, as well as 'v', in message mode. messageViewAttachment views the attachment on the line containing the caret.

    By request, this release adds support for signature files. On Unix, ~/.signature is picked up by default. On non-Unix platforms, or if you'd prefer a different file, you can add a line like this to ~/.j/prefs or C:\.j\prefs:

            signature = /home/peter/my_funny_signature

    In web mode, the command copyLink has been added, available via Alt X. copyLink copies the link (href) at the current location of the caret to j's kill ring and to the system clipboard, so you can paste it after "wget " in a shell buffer.

    In JavaScript mode, findTagAtDot now ignores the arity of the expression at dot. You really can't trust arity in JavaScript mode.

    In directory buffers, the sidebar tree no longer indulges in gratuitous repaints when you scroll around in the buffer.

    By request, in Java mode, j now tries to keep the selected tag in the sidebar tree somewhat centered vertically (that is, not at the very beginning or very end of the visible part of the list), so you can always see some of the other tags around it.

  • Aug 21 2002 7:12 AM - Version 0.16.3

    This release introduces a drafts folder and fixes a number of minor bugs.

    For a long time, if you exited j while you were in the midst of composing a mail message, the composition buffer containing the message you were working on would be restored as part of the saved session when j started up again. This happened automatically because there was an actual file backing the message, so the buffer was restored just like any other file-backed buffer. J knew the buffer should be a mail composition buffer because the file backing it was in a special directory (~/.j/mail/unsent).

    So postponed messages weren't a total disaster. But if you made the mistake of closing the composition buffer after you saved it, there was no obvious or documented way to re-open the saved message again later so you could finish it and send it on its way.

    Starting with the current release, you can simply enter the system alias "drafts" in the location bar, and you'll get a mailbox view of the drafts folder. (If you're looking at some other mailbox, you can also get to the drafts folder by clicking on "drafts" under "Local Folders" in the sidebar tree.)

    In the drafts folder, as in any other mailbox, mailboxReadMessage, mapped by default to Enter, opens the message on the line containing the caret. In the drafts folder this gets you a mail composition buffer which lets you continue working on the message in question and eventually send it off.

    The drafts folder supports mailboxDelete (mapped by default to 'd'), mailboxUndelete (mapped by default to 'u') and mailboxExpunge (mapped by default to '$'). When you eventually send a message that has at some point been saved as a draft, the draft of the message in question is automatically deleted from the drafts folder.

    Finally, the location of the drafts folder has changed. It's now ~/.j/mail/local/drafts, rather than ~/.j/mail/unsent. 0.16.3 runs a bit of code at startup to move your unsent messages to the new place and remove the obsolete ~/.j/mail/unsent directory. If you have unsent messages that are important to you, you might want to back up ~/.j/mail/unsent before running 0.16.3, just in case.

    This release also fixes a number of minor bugs unrelated to mail.

    In previous versions, with Java 1.4.1 on Linux, if you did Alt B to set focus to the buffer list (so you could use the keyboard to scroll around in the list, maybe close some buffers, etc.), when you subsequently hit Escape to return to the edit window, focus was lost.

    This bug is now fixed, and the code behind Escape, which in previous versions contained an elaborate hack that seemed necessary at the time, has been simplified considerably. I've tested the new code with the latest versions of IBM 1.3.1, Blackdown 1.3.1, Sun 1.4.0, Sun 1.4.1-beta and Blackdown 1.4.1 beta; all seems to be well.

    In addition, if you do Alt B and use the Delete key to close a buffer that's currently displayed in an edit window, the edit window now repaints immediately, as it should. (In previous versions it tended not to repaint at all.)

    In Java mode in 0.16.2, if there were multiple interface names following "implements", all but the last were incorrectly added to the tag list as fields. Fixed.

    The Java tagger in 0.16.2 reported the visibility of public, private, or protected methods incorrectly if the method in question immediately followed a field declaration with an initializer, e.g.

            private static Stack markers = new Stack();
    
            public void pushPosition() {}

    In this situation pushPosition() would be incorrectly reported to have package (rather than public) visibility. Fixed.

    In previous versions, cvsCommit (actually finish in a CVS checkin buffer) didn't refresh the display properly when the CVS checkin buffer went away if the window wasn't split at the time. Fixed.

    Keywords are now configurable in BeanShell mode, as in all other modes. (In previous recent versions keywords weren't highlighted at all in BeanShell mode.)

  • Aug 14 2002 5:22 PM - Version 0.16.2

    This release introduces three new commands in C and C++ modes: iList, checkPath and listIncludes.

    Since the beginning of time, j has supported the concept of an include path for C and C++ modes. The idea is, you add lines like the following to ~/.j/prefs:

            CMode.includePath   = ../include:\
                                  /usr/include:\
                                  /usr/lib/gcc-lib/i386-linux/2.95.4/include
    
            CppMode.includePath = /usr/include:\
                                  /usr/lib/gcc-lib/i386-linux/2.95.4/include:\
                                  /usr/include/g++-3

    Then, when you're working on a C file (for example), you can enter "stdarg.h" in the location bar, without any path prefix at all, and j will look in the C mode include path and find the file you're looking for, which is /usr/lib/gcc-lib/i386-linux/2.95.4/include/stdarg.h.

    (Note that you need to use the platform-specific path separator character, which is a colon for Unix and a semicolon for Windows, when specifying the include path.)

    If your include path is set up correctly, you can also put your caret anywhere at all on the line:

            #include <stdarg.h>

    and use gotoFile (Ctrl Shift G) to open stdarg.h in the aforementioned location, with no actual typing whatsoever.

    The new commands checkPath and listIncludes help you verify that you have your include path set up correctly.

    The command checkPath, not mapped by default but available via executeCommand (Alt X, "checkPath"), looks at all the lines in the current buffer that start with "#include" and reports which included files can't be found in your include path (or in the current directory, if the filename is enclosed in quotes rather than in angle brackets). checkPath also recursively checks all the included files that it can find, and reports which (if any) of the files included by those files can't be found.

    listIncludes (Alt X, "listIncludes") is similar to checkPath, but it lists all the included files, not just the ones that can't be found.

    iList, mapped by default to Ctrl F6 in C and C++ modes, operates on the identifier at the current location of the caret. It creates a List Occurrences output buffer showing all occurrences of the identifier in question in the current buffer AND in any included files, in the order in which they occur.

    So, to take an example from the Linux kernel source, suppose your C mode include path is set up as in the example above and you're looking at this line in sched.c:

            #define MIN_TIMESLICE               ( 10 * HZ / 1000)

    And you wonder what "HZ" is. If you put your caret on "HZ" and hit Ctrl F6, you'll get a List Occcurrences buffer that starts like this:

            Pattern: "HZ"
            Options: case sensitive, whole words only
            File: /usr/src/linux-2.4.19-pre10-ac2-A4/include/linux/sched.h
            4:#include <asm/param.h>	/* for HZ */
            File: /usr/src/linux-2.4.19-pre10-ac2-A4/include/asm-i386/param.h
            4:#ifndef HZ
            5:#define HZ 100

    From which you can see that HZ is 100, as defined on line 5 of param.h.

    There are two new commands in mailbox mode, sortByDateSent and sortByThread. These commmands are not mapped to any keystrokes by default, but they are available on the View menu or via Alt X.

    By default, mailboxes come up sorted in order of date sent, as they always have. sortByThread gets you a threaded view. (Bear in mind that sortByThread just changes the view; it doesn't actually modify the underlying data in any way.) If you're looking at a threaded view, sortByDateSent will get you back to a flat list in order of date sent.

    By default, j now saves a local copy of each IMAP message that you read. If you reread the message later, j will get it from the cache instead of pulling the same bits over the network again. This is particularly useful if you have a slow network connection.

    Each message is saved in a file named after its UID, in a directory specific to the mailbox in question, under ~/.j/mail/imap/cache.

    Deleted messages are automatically removed from the cache as a side effect of the mailboxExpunge command, which is mapped by default to '$' in mailbox mode. The current implementation has no concept of expiration or aging of undeleted messages and imposes no limit on utilization of disk space.

    IMAP message caching can be disabled by adding this line to ~/.j/prefs:

            imapUseLocalCache = false


  • Jul 30 2002 6:59 AM - Version 0.16.1

    By request, this release adds basic support for named sessions.

    J has always saved information about your editing session, so that by default, when you restart j, things come back more or less as you left them: the same buffers will be open (except for remote and transient buffers), and the current location in each buffer will be the same.

    The commands saveSession and loadSession, new in this release, add support for named sessions.

    saveSession saves information about the current editing session in a named session file. If no named session is active yet, you will be prompted for a name for the current session; once you've specified a name, saveSession will use that session file without further prompting.

    loadSession loads a named session that you have previously saved, which then becomes the active named session as far as saveSession is concerned. All currently open buffers are closed before the new session is loaded.

    The "Name:" textfield, in the dialog that comes up when you do loadSession or saveSession, supports both history and completion; if you hit Tab when the textfield is empty you'll cycle through all the named session files in your collection.

    If a named session is active, you can save the current session under a new name by using executeCommand to invoke saveSession with the new name as an argument (e.g. Alt X, "saveSession foo"). If you do this, subsequent saves will go to the new session file ("foo") by default.

    When a named session is active, the session name appears in the title bar of the top-level window, enclosed in brackets.

    By default, the information in a named session file is only updated when you explicitly invoke saveSession. This allows you to exercise better control over the contents of named session files. If you'd like named session information to be updated automatically, add this line to ~/.j/prefs or C:\.j\prefs:

            autosaveNamedSessions = true
    You can use "-session" on the command line to start j with a specific named session:
            j -session foo
    or
            java -jar j.jar -session foo
    When you start j without specifying a named session on the command line, the previous session is restored, but no named session is active until you do saveSession or loadSession.

    In the current implementation, only the buffer list is saved in the named session file. This means that command history (among other things) is global across named sessions. It would be nice to store command history in the named session files too, but I'd like to make sure the basic functionality is solid first. The folks who requested this feature were mainly interested in the buffer list.

    Documentation about named sessions has been added to the help system (F1, scroll down to "Sessions" and hit Enter).

    Of course, if you don't care about named sessions, you can ignore all of this and j will behave exactly as it always has.

    Starting with this release, findTag (mapped by default to Ctrl T in programming modes) and findTagAtDot (mapped by default to Alt . in programming modes) use a smart output buffer (similar to a List Occurrences buffer) instead of a dialog box to resolve ambiguities. You can use the cursor keys to scroll around in the List Tags buffer, and if you hit Enter on the line corresponding to the method you're interested in, you'll go directly to its source in the other window. Keyboard focus stays in the List Tags buffer, but the List Tags buffer will go away if you hit Escape.

    There are a couple of additional minor features in List Tags mode (as opposed to List Occurrences mode). First, the up and down cursor keys are mapped to tagUp and tagDown, respectively, so navigation using the up and down cursor keys always lands on interesting lines. Second, Ctrl Enter (as opposed to Just Plain Enter) is mapped by default to jumpToTagAndKillList, which does what its name suggests; to wit, you'll go directly to the source of the method in question and the List Tags buffer will go away, leaving the edit window unsplit. You can use Ctrl Enter if you're sure you've found the tag you want in the list; if you're not sure, you can use Enter, possibly more than once, to audition the various candidates, followed by Escape when you've found what you're looking for.

    With previous versions of j and Java 1.4.1-beta on Linux, focus would frequently (but not always) go astray after you dismissed a dialog box. This problem is fixed in this release, and j now seems to work fine with 1.4.1-beta.

  • Jul 15 2002 9:16 AM - Version 0.16.0

    First a word of warning: as things stand, j won't work correctly if it's built with jikes 1.16 (which was released last week). I haven't had a chance to look into the problem in detail, but jikes 1.15 (26 Sept 2001) has always worked fine for me, and I've been told that javac from Sun 1.4.0_01 and javac from Blackdown 1.3.1_02b work fine too. The binaries for this release were built with jikes 1.15 (as usual).

    This release introduces Ruby mode (contributed by Jens Luedicke), support for custom keyword lists, and new options for highlighting braces, brackets and parentheses.

    Ruby mode supports all of the features you've come to expect in a mode: syntax highlighting, automatic indentation with the Tab key, and a tag list in the sidebar. Feel free to complain if you encounter syntax that isn't handled correctly; please include a code sample that illustrates the problem.

    By request, this release adds support for custom keyword lists for the various modes.

    This feature is mainly useful for languages like Lisp and Scheme that have a variety of dialects, where you might want to use a custom keyword list that contains the keywords of the particular dialect you're using.

    To use a custom keyword list, first prepare the list itself. It should be an ordinary text file with one keyword per line. For an example of the format, take a look at src/org/armedbear/j/JavaMode.keywords (there is such a file for each mode, containing the default keyword list for that mode).

    After you have prepared your custom keyword list, all you have to do is add a line like this to ~/.j/prefs (or C:\.j\prefs), pointing to the file you want to use:

            LispMode.keywords = /home/peter/lispkeywords

    In response to Feature Request 577186, you can now set things up so that, when your caret is on (or just past) a brace, bracket, or parenthesis, j will highlight the matching brace, bracket, or parenthesis (if possible).

    To enable this feature, add this line to ~/.j/prefs:

            highlightMatchingBracket = true

    And you may need to add a line like this to your theme (or ~/.j/prefs):

            color.matchingBracketBackground = 255 204 102

    If you'd like both of the brackets, braces or parentheses to be highlighted (instead of just the one at the far end), add this line to ~/.j/prefs:

            highlightBrackets = true

    J now recognizes that files beginning with "<?php" (or just "<?") should be opened by default in PHP mode.

    In PHP mode, syntax highlighting and automatic indentation work much better now in the vicinity of multi-line quoted strings.

    J's menu mnemonics work correctly now with Java 1.4.1-beta.

    Finally, as usual, all bugs reported to j's official bug tracker have been fixed (or otherwise dealt with) for this release.

    Thanks for your support.

  • Jul 2 2002 9:04 AM - Version 0.15.3

    This release provides better support for reading and writing files using non-default character encodings, plus a few minor improvements and bugfixes.

    The default character encoding is controlled by the defaultEncoding preference:

            defaultEncoding = ISO-8859-1
    In previous versions of j, there was no ad-hoc way to open a file with a specific non-default encoding. Starting with this release, you can use the "-e" switch to specify the encoding when you're opening a file in the location bar, e.g.:
            /home/peter/greek.txt -e iso-8859-7

    The encoding must be supported by the version of Java that you're using. The encoding name is not case-sensitive. Commonly supported encodings include "IS08859_1" and "ISO-8859-1" (two names for the same thing), and "UTF8" and "UTF-8" (likewise).

    Java recognizes both canonical names and aliases for many encodings. To make things more interesting, there are significant variations in this area among the different versions of Java. More information from the perspective of Java 1.4 is available here.

    The "-e" mechanism, which is currently available in the location bar but not on the command line when starting j, is not likely to be the last word in UI design for this particular feature. But you never know...

    Once the text of a file is loaded into a buffer, it's in Unicode. By default, if you modify the buffer and save it, the encoding of the original file is used for the save.

    You can change the save encoding with the new command setEncoding, available on the File menu or via Alt X. So, for example, you could do Alt X, "setEncoding utf-8" if you wanted to save greek.txt in UTF-8 instead of ISO-8859-7.

    If you open a file using a non-default encoding, or if you later use setEncoding to specify a non-default encoding, j will make an effort to remember the encoding you used for the file and use that encoding again the next time you open the same file, unless you explicitly specify a different encoding with the -e switch on that occasion.

    In XML mode, j now chooses the encoding to use when loading a file based on the encoding declaration in the file itself. The encoding declaration is an optional part of the XML declaration, which itself is also optional, and which, if it exists at all, must be at the very beginning of the file. If there's no encoding declaration, UTF-8 is assumed, as required by the Section 4.3.3 of the official XML 1.0 W3C Recommendation. This is a change in j's behavior compared to prior versions, which not only paid no attention to the encoding declaration, but defaulted to the user's default encoding, which itself defaulted to ISO-8859-1 (and still does).

    The name of the encoding that's in effect for the current buffer is shown in the Properties dialog (Alt P), in the "File" box.

    One casualty of all this is the archaic command toggleSaveAsUnicode, which is obsolete and has been removed, since you can now do (for example) Alt X, "setEncoding UTF-16", which is clearer and more flexible.

    By request, there is now an option to sort the sidebar tree alphabetically in Java mode. Only the fields and methods are sorted; the "extends" and "implements" lines and the classes themselves are still presented in the order in which they appear in the buffer.

    The new option is available on the right-button context menu in the tree pane. It's global (i.e. whichever way you set it, it works the same way for all Java mode buffers), and it persists from one session to the next, until you specifically change it again. (In these respects it works the same as the "Arrange by type" option which is also available on the aforementioned right-button context menu.)

    By request, the behavior of incrementalFind has changed again. Now, in the incremental find textfield, backspace always removes the last character from the search pattern and then finds the first occurrence of the new, shorter pattern, starting from the starting point of the original search. In addition, you can use whatever key(s) you have mapped to findPrev to find the previous occurrence of the current pattern. findPrev is mapped by default to Shift F3 and Ctrl H.

    As before, you can use whatever key(s) you have mapped to findNext (or to incrementalFind itself) to find the next occurrence of the current pattern. findNext is mapped by default to F3 and Ctrl G.

    By request, pastePrimarySelection is now mapped globally to Mouse-2 by default on Unix if you're using Java 1.4 (which is required for primary selection support in any case). I've also removed all of the default mode-specific mappings for Mouse-2 in buffers that can accept a paste, so the global mapping won't be overridden (by default, at least) in any situation where it would be missed. The net effect of all this is that on Unix, if you're using Java 1.4, X-style copy/paste is now the default behavior.

    By request, xmlElectricSlash, mapped by default to '/' in XML mode, now automatically re-indents the line after completing the end tag, provided the property autoIndent is true for the buffer in question (which it is by default).

    By request, window information is now correctly saved and restored even if the main window is maximized, provided you are running Java 1.4 (there's no way to do this properly with earlier versions of Java).

    For a long time, j has provided a certain amount of support for showing the request and response headers associated with HTTP buffers. In previous versions, this involved a preference (httpShowHeaders) and a command (httpToggleHeaders). If you wanted to see the headers, they were prepended to the HTML source of the HTTP buffer in question. Because of that approach, the formatting was a bit sketchy, there was no way to see the headers associated with an image buffer (for example), and it wasn't easy to remember how to set things up.

    In this release all of this has changed. The httpShowHeaders preference and the httpToggleHeaders command have been replaced by the httpShowHeaders command, which is available in any HTTP buffer, including image buffers.

    The httpShowHeaders command shows the request and response headers in a separate transient output buffer. No setup is required, no muss, no fuss.

    In addition, if j followed redirection to get where it got to, as it does, if necessary, when the enableWeb preference is true, all of the request and response headers are shown, so you can see the full chain of redirections.

    httpShowHeaders is not mapped to a keystroke by default, but you can do Alt X and type it in.

    Starting with this release, logging is on by default. This shouldn't make any difference under normal circumstances, since only errors are logged, but it can be very helpful in tracking down problems. If you're reporting a bug, you might want to look at the log file (~/.j/log or C:\.j\log) to see if there's any useful information there. If so, you can attach the log file to the bug report.

    Logging is configurable; for full details, see the documentation (F1, "Logging").

    Finally, all bugs reported to j's official bug tracker have been fixed (or otherwise dealt with) in this release.

    Thanks for your support.

  • Jun 12 2002 8:43 AM - Version 0.15.2

    This release fixes a serious bug which led to an assertion failure and caused j to hang, under most circumstances, if you tried to open a file via HTTP (say "http://armedbear.org/index.html", just for one example).

    This bug has been around for a while (since 0.13.0 at least), and it has the distinction of being the first bug reported to j's new bug tracker on SourceForge. It is fixed now, and you should once again be able to open "http://armedbear.org/" or "http://slashdot.org/" or "http://www.cnn.com/" without immediately regretting it.

    In other news, the behavior of incrementalFind has changed in this release.

    In earlier releases, the incrementalFind textfield rejected any characters you might type that changed the search pattern so there was no match.

    So, for example, if the pattern was "fo", and there was a match for that in the buffer, and if you then typed 'x' (making "fox"), and there was no "fox" in the buffer, the textField would refuse to accept the 'x'.

    The problem with this approach was that if you typed fast and didn't pay close attention, the textfield would reject a few characters and then find one that it could accept, leading to a match on a string you never intended to look for.

    So, to make the contrived example above even more far-fetched, maybe you're looking for "foxfire"; the textfield rejected the 'x', so there's no possible match for "foxfire" in the buffer, but if you don't notice that and keep typing, maybe when you type 'r' you'll get a match on "for", which is confusing and not at all what you wanted.

    In the current release, this behavior has changed. J no longer rejects any characters you type. If there's no match, so be it; a message to that effect is displayed inconsipicuously in the status bar, the typed character appears in the textfield and life goes on. At some point you notice there's no match. The last-matched substring will still be selected in the buffer, the string in the textfield will be whatever you actually typed, and the inconspicuous message in the status bar will tell you the search failed. You can backspace back through the pattern that didn't work, and eventually that will backtrack through the buffer like it always has done.

    I think this behavior is an improvement, and it's a bit closer to what other editors do.

  • Jun 9 2002 7:05 PM - Version 0.15.1

    A new mode, a stupid mouse trick, a number of minor enhancements and some bugfixes.

    CSS mode is the new mode, for all your Cascading Style Sheets.

    By request, for those of you who like that sort of thing, this release introduces drag/drop of text within a buffer, using the mouse. And from one buffer to another, for that matter.

    In fact, on Windows, you can drag text from j and drop it into other consenting applications, or vice versa.

    Straight drag (no keys down) is a move; if the Ctrl key is down, it's a copy. You can press (or release) the Ctrl key while you're dragging; the mouse cursor will change to reflect the change of operation.

    All drag/drop operations are fully undoable and redoable.

    To drag text from one buffer to another, both buffers must be visible, so you'll need to do splitWindow (F10) or possibly newFrame (Ctrl Shift N) and jockey things around a bit first.

    I haven't implemented an autoscroller yet, so for now you can only drag text to a location that's currently visible within the destination window. Drag/drop is not yet supported for column selections.

    If you just can't abide stupid mouse tricks, you can turn off the drag/drop feature by adding this line to ~/.j/prefs:

            enableDragText = false

    By request, Tcl mode now supports different syntax highlighting for braces and brackets. Taking Kodiak as an example:

            TclMode.color.brace   = 153 0 51
            TclMode.style.brace   = 1
            TclMode.color.bracket = 204 102 0
            TclMode.style.bracket = 1

    By request, in XML mode the tree in the sidebar now displays all of the attributes, rather than just the first one, as well as the element name. Often there will be just one or two attributes, and they will show up in the tree without scrolling. Sometimes there will be too many attributes and the line will be too long, but you can scroll horizontally if you care, or just ignore the extra attributes; they don't eat much.

    By request, selectAll, mapped by default to Ctrl A, now calls pushPosition before selecting all the text in the buffer. The point of this is that after you've had your way with all of the text in the buffer, you can use popPosition, mapped by default to Shift F5, to return to where you were before you did selectAll.

    By request, the jump commands (jumpToLine, which is mapped by default to Ctrl J, jumpToColumn, and jumpToOffset) now support arithmetic expressions as well as simple numbers. So you can enter, for example, "143+37" instead of "180", which might be useful if you're trying to find an error at line 37 of procedure foo and procedure foo starts at line 143. You can also enter an offset from the current line number: if you're at line 50 and enter "+12" you'll get to line 62.

    By request, the Find dialog has a new checkbox, "Search from start of document". If you check this box, the search begins at (you guessed it!) the start of the document. Otherwise, the search begins at the current location of the caret (like it always has).

    By request, the date/time string inserted by the stamp command, which is mapped by default to Shift F2, can now be customized by adding a line like this to ~/.j/prefs:

            stampFormat = "EEE, dd MMM yyyy HH:mm:ss"
    You can do Alt X, "help stamp" and follow the links to get documentation on the format of the template string; there's enough flexibility there to kill a horse.

    In previous recent versions of j, on Windows only, and only with versions of Java prior to 1.4.0, the Confirm Replacement dialog performed (or skipped) two replacements instead of one if you hit 'Y' (or 'N'). This bug, introduced a while back with the changes that were made to support Java 1.4.0, is now fixed.

    In previous versions of j, if you used control shift left click to make a column selection, then switched away from the buffer containing the column selection and switched back again, the column selection was magically (and incorrectly) transformed into an ordinary selection. This bug is now fixed.

    J's MIME parser now handles multipart messages correctly even if one of the parts is empty, as is often the case with messages generated by the W32/Klez virus.

  • May 20 2002 8:22 AM - Version 0.15.0

    Additional CVS support, three new modes, and a number of minor improvements.

    J's CVS support is now fully documented; use F1 and look for "CVS Support". I've been using j's CVS support every day for months, so it's well tested in my environment (Linux), but your environment may vary...

    By request, modes have been added for Verilog, VHDL, and Tcl/Tk. In each case, syntax highlighting seems to work well, there's a rudimentary tag list in the sidebar, and conveniences like commentRegion (F11), uncommentRegion (Shift F11), and wrapComment (F12) are provided.

    Tcl mode fully supports automatic indentation (hitting Tab indents the current line correctly, the indentation should be correct on the next line after you hit Enter, and '{' and '}' are electric).

    Verilog mode makes some effort towards automatic indentation, but it's far from 100%.

    In VHDL mode, for the moment, at least, the Tab key is mapped to insertTab, which is a way of giving up; if the indentation is wrong, you're better off using insertTab to correct it manually. Enter is mapped to newlineAndIndent, but manual intervention will frequently be required.

    There is obviously room for improvement here. I don't use Verilog or VHDL (or, for that matter, Tcl/Tk) in real life myself, so please let me know when you find bugs or if you have suggestions to improve the behavior of these modes. Samples of Verilog, VHDL, or Tcl/Tk code that illustrate the issue you're describing are worth a thousand words.

    By request, a new confirmation dialog is now presented when you try to close a buffer that has unsaved changes. No big deal if you're new to j, but compared to the way things worked in previous releases, the positive/negative options have been reversed. Now, "Yes" means, "Yes, save my changes and then close the buffer", "No" means, "No, don't save my changes, but go ahead and close the buffer anyway", and "Cancel" means, "Don't do anything; I need to think about this some more." In previous releases, there was no "Cancel", "Yes" meant what "No" means now, and "No" meant what "Cancel" means now. The advantage of the new approach is that you can save the buffer in question directly from the confirmation dialog, skipping a couple of steps that were necessary with the old approach. But be careful, lest old habits or a quick trigger finger lead you astray.

    By default, j now uses the "Monospaced" font in its textfields. If you don't like this, you can change it by adding the following lines (or variants thereof) to ~/.j/prefs or C:\.j\prefs:

            textFieldFontName = Dialog
            textFieldFontSize = 12
    If you don't specify a value for textFieldFontSize, the value of dialogFontSize is used, and if you don't specify a value for dialogFontSize either, it's 11.

    Starting with the current release, the keys for j's preferences are case-insensitive, so the following lines work too:

            textfieldfontname = Dialog
            textfieldfontsize = 12

    For a long time, the expand command, mapped by default to Alt Space, has saved me a lot of typing. The idea is, you type the first few characters of a long word that appears somewhere in the current buffer, hit Alt Space, and the characters you typed are magically expanded into the word you want. If j gets it wrong on the first try, you can keep hitting Alt Space to cycle through all the possible expansions, or hit Escape at any point to get back to just the characters you actually typed. Another one of my favorite features.

    Starting with the current release, all of the textfields in j's dialogs support expansion with Alt Space too. (This also applies to the textfields in the location bar, except for incrementalFind, which is a bit of a special case in many respects.) The candidates for the expansion come from the text in the current buffer. Hitting Escape with an expansion in progress cancels the expansion; hitting Escape a second time closes the dialog.

    If you have experimental features turned on, the commands find and replace now support multiline regular expressions. So, for example, you can search for "Alt\s+Space", and find what you're looking for even if it spans two lines. You can also replace "Alt Space" with "Alt\nSpace", if you should so desire. Because of the way j handles things internally, "\n" should always be used as the line separator string, even on platforms where that is not normally the case; the correct platform-specific line separator will be used when the file is written out. (You can use the Properties dialog, mapped by default to Alt P, to change the line separator for a particular buffer.) Multiline pattern support is an experimental feature for now; it will graduate to the mainstream after a bit more testing and use. If you try it out, please report any anomalies.

    For the last several releases, Java mode has featured tooltips that try to find and report the declaration of the identifier under the mouse cursor. It turns out that this feature is a bit of a performance problem in certain environments, so Java mode tooltips are now disabled by default. To re-enable them, add this line to ~/.j/prefs:

          JavaMode.enableToolTips = true

    By request, those brave souls who use j as their mail client can now add the following line to ~/.j/prefs:

            confirmSend = true
    If you do this, you'll get a confirmation dialog when you send a mail message. The confirmation dialog lets you change the "From" and "Bcc" addresses of the outgoing message on the fly, and you can also specify which SMTP server to use. This is useful for folks with multiple identities and/or network connections.

    J now uses version 1.2b5 of the BeanShell package.

    Plus the usual menagerie of minor bugfixes, imperceptible enhancements, and long-overdue documentation updates.

  • Apr 21 2002 6:50 PM - Version 0.14.3

    This release offers a preview of j's new CVS support and fixes a long-standing (and long-unreported) bug that prevented the editing session from being saved and restored correctly under certain circumstances.

    Starting with this release, CVS revision information for checked-out files is now displayed in the status bar, to the right of the mode name, like this:

            CVS 1.34
    or
            CVS 1.34 M
    or
            CVS A
    "1.34" is the revision; it's followed by an 'M' if the file modification time of the local file is different from the checkout time, which is often an indication that the local file has been modified since it was checked out. If there's an 'A' following "CVS", but no revision number, it means the file has been added to CVS but not yet committed.

    In addition, there are a couple of new commands related to CVS: cvsDiff and cvsDiffDir. These commands only work on files that CVS knows about, of course, but if you're working on such a file, you can use cvsDiff to get a diff output buffer showing the changes between the checked-in version and your local copy. cvsDiffDir is similar, but it generates a diff output buffer for all the files in the current directory, not just the current buffer. Once you're in the diff output buffer, you can scroll around and use diffGotoFile, mapped by default to Enter or Ctrl Shift G or left button double click or middle button single click, to jump to the location in the source corresponding to the line you're on in the diff output buffer. One of my favorite features.

    cvsDiff and cvsDiffDir are not mapped to any keystrokes by default, but you can use executeCommand, mapped by default to Alt X, and then type in the name of the command ("cvsd", then hit Tab once or twice; completion is your friend).

    There's more CVS support waiting in the wings, but I'd like to see if cvsDiff and cvsDiffDir work as expected for a broader audience before proceeding. If you find these commands useful, please let me know, and please let me know if you think they might be useful but for some reason you can't get them to work right. I've used these commands extensively myself, and they work for me, but we always need to be careful of the inmates running the asylum.

    Almost from the beginning of time, j has saved session information on exit, including the size and position of the main window, the list of open buffers, your current location in each buffer, and which buffer you were working on when you quit (among other things), the idea being that the next time you start j, the previous situation will be restored so you can pick up where you left off. (By design, only buffers corresponding to local files are restored, and only if the local files in question still exist when the new session starts up; things like remote buffers and mailboxes are deliberately not restored, to avoid weirdness in case your connectivity has changed in the interim.)

    And for a long time all of this worked just fine.

    Then one day I got the idea that it would work even better if j made a backup of the session information each time it was saved, just in case. So I wrote the code to do that, and while I was at it, I changed things to write the session information to a temporary file first, then delete the existing session file and rename the temporary file to replace it, which is also perfectly reasonable.

    The new code first appeared in 0.11.0, back in October of last year, and it worked fine for me and for lots of other folks, and until last week nobody complained about it at all. Then I received a surprising enhancement request: "Could you make j remember the position and size of its main window from one session to the next?" Hmmm...

    After a certain amount of investigation, it turned out that the problem was that the temporary file for the session information was written to ~/.j/temp, which is j's private directory for temporary files. And that would have been fine, except that the session-saving code did nothing to make sure that this directory actually existed. Now, a fair amount of other code uses ~/.j/temp, and all of that code did check to make sure it existed (and created it if it didn't), but it turns out that most of that code deals with fairly esoteric things like remote buffers and mail, things that most j users don't get around to right away, if at all. So a lot of folks won't have a ~/.j/temp directory, and a lot of folks will lose their session information.

    Sorry about that.

    Anyway, this bug is now fixed, and there are undoubtedly a number of morals that could be drawn from this sad tale.

    Thanks for your support.

  • Apr 18 2002 7:39 AM - Version 0.14.2

    This release improves j's source path functionality, particularly in Java mode, and fixes a number of minor bugs.

    For a long time j has supported the concept of a source path, which lets you open files without having to specify their full paths. For example, you might add a line like this to ~/.j/prefs:

            sourcePath=/usr/src/linux/kernel
    Then you can just type
            sched.c
    to open /usr/src/linux/kernel/sched.c, regardless of what the current directory is. This works in the location bar and also on the command line when first starting j. There is also a separate include path, which j uses to find .h files in C and C++ modes.

    In the current release, this concept has been extended to support mode-specific and relative source paths.

    For example, suppose you have these lines in ~/.j/prefs:

            CMode.sourcePath  = /usr/src/linux-2.4.18-rc1-preempt-K3/kernel:\
                                /usr/src/linux-2.4.18-rc1-preempt-K3/mm
            CMode.includePath = ../include:/usr/include
    Now, if you just type
            sched.c
    you'll get /usr/src/linux-2.4.18-rc1-preempt-K3/kernel/sched.c. Once you're there, you can move your caret to line 15:
            #include <linux/mm.h>
    With your caret anywhere on this line, you can use gotoFile, mapped by default to Ctrl Shift G, to open the referenced header file, and you'll get the one in /usr/src/linux-2.4.18-rc1-preempt-K3/include, following the relative path ../include, which precedes /usr/include in the C mode include path. So you'll get the mm.h in the kernel source you're actually working on, rather than the one in /usr/include (just in case it matters).

    In the general case, J tries pretty hard to find the file you want. In the present implementation, it looks in the current directory first, then in the list of open buffers, then in the source path of the current buffer (which is normally the mode-specific source path of the mode of the current buffer), then in the mode-specific source path of the default mode of the file you're looking for (e.g. Java mode if you're trying to open AbstractMode.java), and finally in the global (i.e. non-mode-specific) source path.

    In Java mode, j now goes even further with the source command, which is new in this release. The source command tries to help you find the source of any Java class referenced in the current buffer.

    Since at least some of the Java classes referenced in any Java buffer are likely to be part of the Java runtime library, you should have the Java runtime library source installed somewhere (it's normally provided with the JDK in either src.zip or src.jar), and you should tell j where it is by adding a line like this to ~/.j/prefs:

            jdkSourcePath = /home/peter/sun/j2sdk1.4.0/src
    Once you have things set up correctly, you should be able to put your caret on the name of any Java class (say, "String", for example), and hit Ctrl F1 (which is the default mapping of source in Java mode), and get the source of the class in question (in this case, java.lang.String). J finds the source of the referenced class by examining the "import" statements at the top of the current buffer and by navigating within the current package relative to the root of its source tree. You can also do, for example, Alt X, "source String", if that's more convenient than finding an instance of "String" to do Ctrl F1 on.

    In addition, gotoFile, mapped by default to Ctrl Shift G in all modes, should work on the "import" statements themselves. You don't have to be right on the class name, either; anywhere on the line should work.

    By request, the commands nextTag and previousTag have been added. These commands do what their names suggest, providing yet another way of moving around in a buffer. They're not mapped to any keystrokes by default, but ~/.j/init.bsh is your friend.

    For Unix platforms, the code behind save (Ctrl S) has been changed to preserve both permissions and ownership of the file being saved.

    This release also fixes a number of minor bugs involving indentation and/or syntax highlighting in Java, Perl, and PHP modes.

  • Mar 14 2002 3:38 AM - Version 0.14.1

    This release fixes three major bugs in 0.14.0.

    Undo was broken for indentRegion in some situations, leading to an assertion failure that caused j to hang. Now fixed.

    Undo and redo were not write-locking the buffer while they did their work, which caused trouble in certain situations if the operation took a long time and the idle thread tried to format the same buffer while the undo or redo was still in progress. Now fixed.

    These bugs were introduced in 0.14.0 by a rewrite of the undo/redo code to provide a better infrastructure for the change mark feature.

    There was also an unrelated bug in the PHP formatter (from the beginning of time, I believe) that kept it from doing the right syntax highlighting for "//" comments. Now fixed.

    Finally, jikes 1.14 had some trouble with ImapMailbox.java. The problem was not really in the code, since both javac and jikes 1.15 compiled it without complaint, but I renamed a couple of variables and now jikes 1.14 is happy too.

    On the subject of jikes, the version that is currently in Debian unstable, "Version 1.15b(CVS)", compiles j without complaint, and the resulting binary does run, but certain classes encounter verification errors at runtime, at least with Java 1.4, and not everything will work right. Don't build j with this version of jikes! The official release of 1.15, available here, should work fine (and now, as mentioned, jikes 1.14 should work fine too).

  • Mar 13 2002 6:48 AM - Version 0.14.0

    This release introduces change marks, and, in Java mode, replaces the sidebar tag list with a class tree representing the current buffer.

    By default, change marks are now displayed to the left of all changed lines. Change marks come in two colors, one ("color.change") for changes you've just made, the other ("color.savedChange") for changes that were made in the current editing session, but before the buffer was last saved. When you save the buffer, the buffer's change marks will all change to the saved change color, since your changes are now saved. (Got it?)

    Change marks are themeable, and the maintained themes (Kodiak, Freefloater, AnokhaClassic and Dark) have been updated to support them.

    Two new commands, nextChange and previousChange, mapped by default to Ctrl Alt N and Ctrl Alt P, respectively, and available on the Go menu, will help you find areas where changes have been made, so you can admire the change marks.

    In most cases, change marks are smart enough to recognize when a sequence of changes to a line brings the line back to its original state (for example, if you type a character and then immediately hit Backspace). At the moment, however, this particular light stays under the bushel, so to speak, so the buffer may still show up as modified in the buffer list when in fact it contains no changed lines. This deficiency, as well as others, will be corrected in a future release (if all goes well).

    If you don't like change marks, you can turn them off by adding this line to ~/.j/prefs:

            showChangeMarks = false

    While working on the change mark code, I needed a way to check my work, so I added the command changes, not mapped by default but available via Execute Command (Alt X). The changes command runs diff to generate a listing of the unsaved changes in the current buffer and presents the listing in a formatted output buffer. You can move around in the output buffer and use diffGotoFile, mapped by default to Enter, to jump to the location of a particular change. Note that since changes uses diff, diff must be installed and in your path, which is more likely to be true on Unix than Windows, but if diff is available, changes works on Windows as well as on Unix.

    In Java mode, the sidebar tag list is now a tree. By default, the tree is arranged by type, with sections for fields, constructors, methods, and (if applicable) nested classes. If this is too much arrangement for you, you can click your right mouse button in the tree pane and uncheck the "Arrange by type" checkbox, in which case you'll still get a tree, but without the aforementioned sections.

    In previous versions, j was not really meticulous about honoring the restrictCaret preference. If restrictCaret is true, the idea is that the caret is never placed beyond the end of the actual text on a line (the actual text, of course, might be whitespace).

    The problem in previous versions was that when you used newlineAndIndent, mapped by default to Enter in programming modes, or tab on an empty line to get the proper indentation, j placed the caret where it needed to go, but did not, at that very moment, insert the necessary whitespace to the left of it. This had the advantage that if you then moved away without actually typing anything on that particular line, no stray whitespace was added to the buffer. But strictly speaking it was the wrong thing to do if restrictCaret was true, and as a practical matter the subsequent behavior of backspace was not always ideal.

    This behavior has been corrected in the current release. Now, both newlineAndIndent and tab insert the required whitespace right away if restrictCaret is true, as they should.

    To prevent the whitespace creep that this change might otherwise lead to, you can configure j to remove trailing whitespace, defined as spaces and tab characters at the end of a line of text, whenever a buffer is saved, by adding this line to ~/.j/prefs:

            removeTrailingWhitespace = true
    If removeTrailingWhitespace is true, the act of saving a buffer will in fact make changes to the buffer if any trailing whitespace is actually removed. When this happens, it will be reflected in the change marks, if you have change marks turned on, and the change itself (like other changes) may be undone (Ctrl Z) and subsequently redone (Ctrl Y) at your sole discretion.

  • Feb 20 2002 7:28 AM - Version 0.13.1

    Python mode now supports automatic (or at least semi-automatic) indentation.

    To accomplish this, tab is now mapped by default to Tab, and newlineAndIndent is now mapped by default to Enter. insertTab, which does what you might think the Tab key ought to do, is now mapped by default to Ctrl Tab. And finally, for reasons to be explained shortly, slideOut is now mapped to Shift Tab (as well as to Alt [, which has always been its default global mapping).

    Python indentation, I've learned, is not an exact science: the correct indentation of a given line cannot always be derived from an inspection of the preceding lines.

    Like the other editors I've looked at, j tends to overindent Python code. A typical example:

          def shuffle(size):
              "Generate a random permutation of 0...(size - 1)."
              shuffle = range(size)
              for i in range(1, size+1):
                  j = random.randrange(i)
                  holder = shuffle[i - 1]
                  shuffle[i - 1] = shuffle[j]
                  shuffle[j] = holder
              return shuffle
    J gets everything right in this example except the last line, which it wants to place directly under the previous line instead of one notch to the left as the author intended.

    Hence the default mapping in Python mode of Shift Tab to slideOut, a command which forcibly moves the current line (or selected region if there is one) one notch to the left.

    So the workflow is that you use Tab and/or Enter to apply j's idea of proper indentation to the current line, and then you use Shift Tab to move the line to the left manually if you need to make a correction. You probably won't need to move the line to the right very often, but if you do, slideIn, mapped by default to Alt ] in all modes, is your friend.

    In Python mode, triple-quoted strings (and lines continued with a '\' in the midst of a single-quoted string) are no longer quite as likely to confuse j's syntax highlighting.

    By request, the line numbers introduced in version 0.13.0 can now be displayed in a font (and/or size) different from the normal display font. You can control this by adding lines like these to ~/.j/prefs:

            gutterFontName = Monospaced
            gutterFontSize = 10
    By default, the gutter font name and size are the same as the display font name and size.

    In addition, the gutter (the area containing the line numbers) now has a vertical border to separate it visually from the actual text in the buffer. You can specify the color of this border by specifying suitable RGB values in ~/.j/prefs:

            color.gutterBorder = 153 153 153
    There's no way to turn the border off, exactly, but if you set color.gutterBorder to the same color as color.background, you won't hardly notice it.

    And as a reminder, to get any of this to happen you need to turn line numbering on:

            showLineNumbers = true

    J's preferences architecture has been overhauled slightly. The net outcome is that settings in ~/.j/prefs now override settings of the same properties in your theme. In previous versions of j, the theme was loaded last, overriding the settings in ~/.j/prefs. The new approach is arguably more convenient, since you can specify a stock theme and just make a couple of corrections in ~/.j/prefs, rather than having to make modifications to the theme itself.

    detabRegion and entabRegion are now undoable (and redoable).

    Cleaned up and documented the old command decodeRegion, which base-64 decodes the selected region (or the line containing the caret if no region is selected). If the resulting output is text, it is displayed in a new buffer; otherwise, you are prompted for a filename and the output is saved in the specified file. decodeRegion is not mapped to a keystroke by default, but it's available from the Execute Command dialog box (Alt X). decodeRegion was introduced a long time ago when j was just learning how to handle mail messages with binary attachments, but it's still useful on occasion on its own hook.

    Fixed a bug that prevented user-specified files preference settings from being recognized in any mode. As in, for example:

            PHPMode.files = ".+\\.php|.+\\.phtml|.+\\.php[34]"
    These settings should work correctly now.

    Version 0.13.0 introduced a NullPointerException in messageToggleRaw. Now fixed.

    Version 0.13.0 also introduced a NullPointerException when undoing an action whose undo information was saved with SimpleEdit.FILE. (Fortunately the only documented command in 0.13.0 that used this approach was sortLines.) Also now fixed.

    In the source, Debug.assert() has been renamed to Debug.assertTrue(), since "assert" is now a reserved word.

  • Feb 12 2002 10:26 AM - Version 0.13.0

    A couple of new features (by request) and a major bugfix.

    First the major bugfix. An attempt to optimize the formatting code in version 0.12.4 led to an ArrayOutOfBoundsException in HTML mode under certain circumstances (in particular if the file contained a <script> tag). It was pretty much game over if you hit this bug. Now fixed.

    The first new feature is Python mode, used by default for .py files. Syntax highlighting and a tag list in the sidebar are supported.

    The second new feature is the optional display of line numbers in the edit window. To turn on line numbering, add the following line to ~/.j/prefs or C:\.j\prefs:

            showLineNumbers = true
    showLineNumbers is false by default.

    Even if you've added the aforementioned line to your preferences file, line numbers are only displayed in ordinary editing buffers (and not, for example, in directory buffers or mailboxes). If you want, you can override this inhibition on a mode-specific basis:

            MailboxMode.showLineNumbers = true

    Starting with this release, showLineNumbers also controls whether line numbers are included when you print a buffer (using print, mapped by default to Ctrl P and available on the File menu). The old property that used to control this, printLineNumbers, has been removed.

    Added the property color.lineNumber, which you can use to customize the color of the line numbers displayed in the edit window. The supported themes (Freefloater, AnokhaClassic, Dark, and Kodiak) have been updated accordingly.

    In Directory mode, dirBack is now mapped by default to 'b' (lower case B), and dirForward is now mapped by default to 'f' (lower case F). As a consequence of this change, dirBrowseFile is no longer mapped to 'b'. dirBrowseFile is still mapped to Ctrl Shift B, however, which is consistent with the mapping of the corresponding command in other modes.

  • Feb 7 2002 8:29 AM - Version 0.12.4

    Minor improvements and bugfixes.

    Added xmlElectricSlash, mapped by default to '/' in XML mode, which autocompletes the end tag (if possible) when you type "</".

    Added xmlInsertMatchingEndTag, mapped by default to Ctrl E in XML mode, which inserts the whole end tag, so you don't have to type "</" first. (On my keyboard, Ctrl E is a keystroke or so shorter than "</".)

    (Generally, I think xmlInsertMatchingEndTag is more useful, since it does no harm if there's no start tag to match, but xmlElectricSlash is a good fallback if you've already started to type the end tag.)

    Added mailboxFlag and messageFlag, mapped by default to 'F' (upper case F) in mailboxes and message buffers, respectively. These commands toggle the "important" flag for the message in question (which, in a mailbox, is the message on the line containing the caret). If the "important" flag is set, the message gets a '!' in the leftmost column of the mailbox message index.

    Added the mailbox limit pattern "~F", matching messages that have been flagged by these new commands, for use with mailboxLimit and mailboxTagPattern.

    The new approach to FTP saves introduced in 0.12.0, while normally safer than saving the destination file in place, does not always preserve all the attributes (permissions, ownership, etc.) of the destination file. Now, if you want, you can have the old approach back by adding this line to ~/.j/prefs or C:\.j\prefs:

            saveInPlace = true
    If saveInPlace is true, FTP saves are written directly to the destination file. This approach is better at preserving the file's attributes, but it has the disadvantage that the file is likely to be lost or truncated if a network problem prevents successful completion of the save. saveInPlace is false by default and applies only to FTP saves.

    In version 0.12.3, findInFiles and replaceInFiles underwent a bit of reorganization, mostly cosmetic in nature, which included, among other things, a "Replace with:" status line near the top of the output buffer to report the replacement text for replaceInFiles. Unfortunately, the new status line was also displayed, incorrectly, for findInFiles, as follows:

            Replace with: "null"
    Which was a bit disconcerting if you took it at face value, although the bug was just in the status display and the unasked-for replacement was never actually attempted. This is now fixed.

    It should now be possible to invoke openFile successfully from the File menu or toolbar as well as with Ctrl O (its default mapping). There was never a problem with Ctrl 0, but using the menu or toolbar did not always (ever?) set focus to the location bar correctly.

  • Jan 29 2002 8:42 AM - Version 0.12.3

    This release introduces support for syntax highlighting of HTML content in PHP mode. It should work right out of the box if you're using a supported theme (Freefloater, AnokhaClassic, Dark, or Kodiak) or no theme at all (which is equivalent to Kodiak).

    For a long time, j has supported preferences that let you adjust the ascent, descent and leading of the edit window display font:

            adjustAscent = -3
            adjustDescent = -2
            adjustLeading = -1
    You might want to specify negative adjustments, within reason, to squeeze more lines of text into a fixed amount of vertical space. A certain amount of trial and error is usually needed to get this right; adjustments that would otherwise make the adjusted parameter negative are silently ignored.

    These preferences were introduced because blind acceptance of the font metrics reported by Java has not invariably led to a great-looking display, even apart from differences of individual taste in such matters.

    These adjustments are still supported in the current release, but now j tries a bit harder to arrive at reasonable pre-adjustment defaults. The result of this is that you may need to change your adjustment values if you've set them up for a previous version of j.

    In addition, there are a couple of other preferences that may prove useful in the same area:

            enableItalics = false
            emulateBold = true
    Setting enableItalics to false disables use of the italic font even if it is specified by the theme you're using, which saves you the trouble of modifying the theme itself. Setting emulateBold to true makes j emulate a bold font by doing a paint trick with the plain font. (You should only set emulateBold to true if you're using a font that lacks a built-in bold variant.)

    Added findFirstOccurrence, mapped by default to Ctrl Alt up arrow in all modes. As its name suggests, findFirstOccurrence finds the first occurrence in the current buffer of the word at the current location of the caret. In the case of a file-scope variable or C/C++ #define, the first occurrence is the one you want to look at when you're wondering what the thing in question is. undo, mapped by default to Ctrl Z, will take you back where you came from after you've had a look.

    electricEquals, which was mapped by default to '=' in HTML and XML modes, has been replaced by htmlElectricEquals in HTML mode and by xmlElectricEquals in XML mode. You probably won't notice the change unless you're using custom keymaps, in which case you should update them with the new command names.

    In XML mode, the change in 0.12.0 that appended the name and value of the first attribute to the name of the element in the sidebar tree broke copyXPath. This is now fixed.

  • Jan 22 2002 6:58 AM - Version 0.12.2

    This release fixes a couple of minor but annoying bugs introduced in 0.12.1.

    The help command (F1) was broken in 0.12.1. Help worked fine if you started off by asking about a specific command (e.g. Alt X, "help cyclePaste"), but F1 (or just Alt X, "help") led to a NullPointerException, which was no help at all. This bug is now fixed.

    A change in 0.12.1 broke indentation in Java mode (and its derivatives) after "else if", when there were no curly braces around the following code. Also now fixed.

    Plus a couple of XML mode indentation fixes, unrelated to 0.12.1 per se.

  • Jan 16 2002 11:48 AM - Version 0.12.1

    One new feature (vertical rule) and a number of bug fixes and minor improvements.

    Some folks like to have a vertical line displayed inconspicuously at some specific column in the edit buffer as a hint to help them maintain a right margin for their code, out of deference to colleagues who might happen to be display-width-challenged for whatever reason. J now supports this feature. To enable it, put a line like this in ~/.j/prefs:

            verticalRule=80
    The vertical rule will be displayed to the right of the column specified by the verticalRule property. If verticalRule is zero (which is the default), no vertical rule will be displayed. You can use color.verticalRule in your theme to specify a color for your vertical rule. When enabled, the vertical rule is displayed in editable buffers only (and not, for example, when you're reading a man page or working in a directory buffer).

    Command lookup for executeCommand (Alt X), whereIs, and help is now case-insensitive. So you can do, for example, Alt X "help ccgroup", in all lower case, instead of Alt X "help ccGroup", with a capital 'G', which used to be r