//---------------------------------------------------------------------------- // COMPONENT NAME: LPEX Editor // // All Rights Reserved. // // DESCRIPTION: // TestUserProfile - sample user profile //---------------------------------------------------------------------------- package com.ibm.lpex.samples; import com.ibm.lpex.core.LpexAction; import com.ibm.lpex.core.LpexCommand; import com.ibm.lpex.core.LpexDocumentLocation; import com.ibm.lpex.core.LpexView; /** * Sample user profile - customize keys, commands, actions. * It customizes the base editor profile (if not "vi") by redefining several * settings and keys: * <ul> * <li>restricts the action of the Backspace and Delete keys to the current line * <li>sets the Enter keys to go to the next line rather than split * <li>sets the Home and End keys to actions <b>contextHome</b> and <b>contextEnd</b> * <li>sets Alt+F1 to action <b>compose</b> (defined in * {@link ComposeAction}) to enter special characters * <li>redefines Alt+J (join) to remove extra spaces between the joined segments * <li>sets Alt+T to action <b>blockTransfer</b> (defined in * {@link BlockTransferAction}) to transfer selection, adds it to the popup * <li>redefines Ctrl+Backspace (delete line) to preserve the cursor column position * <li>redefines Ctrl+N (find next) to first search for the selected text, if any * <li>sets Ctrl+Shift+V to do a paste replace * <li>redefines mouse button 1 double-click to select the current line * <li>sets the default selection type to character * <li>defines a <b>detab</b> command (using {@link DetabCommand}) * <li>defines a synonym <b>diff</b> for the <b>compare</b> command * <li>defines a synonym <b>k</b> for the <b>calc</b> command * <li>adds an action to the pop-up menu of Java properties documents to * compare ignoring the mnemonics ('&amp;'s). * </ul> * * <p>The user profile is run during the processing of the <b>updateProfile</b> * command. The <b>updateProfile</b> command is normally run when a document * view is created, and it may be issued at any time to allow the document view * to reflect changes to the profile.</p> * * <p>Here is the TestUserProfile <a href="doc-files/TestUserProfile.java.html">source * code</a>.</p> * * <p>To run this sample: * <ul> * <li>Register this user profile from an editor preference page, where available, or * from the editor command line: * <pre>set [default.]updateProfile.userProfile com.ibm.lpex.samples.TestUserProfile</pre> * <li>Run the <b>updateProfile</b> command from the editor command line: * <pre>updateProfile</pre> * </ul></p> * * <p>A user profile is a public Java class that has a method of the form: * <pre> * public static void userProfile(LpexView lpexView) </pre> * See the <b>updateProfile.userProfile</b> parameter.</p> * * @see com.ibm.lpex.samples All the samples */ public class TestUserProfile { // private constructor, not used private TestUserProfile() {} /** * This is the method in a user profile that is called by the * <b>updateProfile</b> editor command. * * @param lpexView the document view for which this profile is being run */ public static void userProfile(LpexView lpexView) { // if the current editor profile is "vi", don't touch it String baseProfile = lpexView.query("baseProfile"); if ("vi".equals(baseProfile)) { lpexView.doDefaultCommand("set messageText Base profile NOT modified by TestUserProfile."); return; } /*--------------------------*/ /* define actions, commands */ /*--------------------------*/ // define an action to select the current line lpexView.defineAction("myBlockMarkElement", new LpexAction() { public void doAction(LpexView view) { view.doCommand("block clear"); view.doCommand("block set element"); } public boolean available(LpexView view) { return true; } }); // define a deleteLine action that preserves the cursor column position lpexView.defineAction("myDeleteLine", new LpexAction() { public void doAction(LpexView view) { int displayPosition = view.queryInt("displayPosition"); if (displayPosition > 0) { view.doAction(view.actionId("deleteLine")); view.doCommand("set displayPosition " + displayPosition); } } public boolean available(LpexView view) { return true; } }); // define a join action that keeps one and only one space between texts lpexView.defineAction("myJoin", new LpexAction() { public void doAction(LpexView view) { LpexDocumentLocation joinLocation = view.documentLocation(); if (joinLocation.element > 0) { // save cursor position, may be affected by deleteWhiteSpace / insertText int displayPosition = view.queryInt("displayPosition"); joinLocation.position = view.queryInt("length") + 1; view.doAction(view.actionId("join")); view.doCommand(joinLocation, "action oneSpace"); // restore original cursor position view.doCommand("set displayPosition " + displayPosition); } } public boolean available(LpexView view) { return true; } }); // define a find-next action that first searches for the selected text, if any lpexView.defineAction("myFindNext", new LpexAction() { public void doAction(LpexView view) { if (view.actionAvailable(view.actionId("findSelection"))) { view.doAction(view.actionId("findSelection")); } else { view.doAction(view.actionId("findNext")); } } public boolean available(LpexView view) { return view.actionAvailable(view.actionId("findNext")) || view.actionAvailable(view.actionId("findSelection")); } }); // define a compare ignoring mnemonics action for the Java properties document parser lpexView.defineAction("myPropCompare", new LpexAction() { public void doAction(LpexView view) { view.doCommand("compare ignoredStyles \"a\" prompt"); } public boolean available(LpexView view) { return true; } }); // define a synonym "diff" for the "compare" command lpexView.defineCommand("diff", new LpexCommand() { public boolean doCommand(LpexView view, String parameters) { return view.doCommand("compare " + parameters); } }); // define a synonym "k" for the "calc" command lpexView.defineCommand("k", new LpexCommand() { public boolean doCommand(LpexView view, String parameters) { return view.doCommand("calc " + parameters); } }); /*------------------------------------------*/ /* (re)define keys, mouse events, the popup */ /*------------------------------------------*/ boolean isEmacs = "emacs".equals(baseProfile); // set "Delete" and "Backspace" keys to keep it inside the current line lpexView.doDefaultCommand("set keyAction.backSpace backSpaceInLine"); lpexView.doDefaultCommand("set keyAction.delete deleteInLine"); // set "Enter" keys to go to the next line (not split) lpexView.doDefaultCommand("set keyAction.enter newLine"); lpexView.doDefaultCommand("set keyAction.numpadEnter newLine"); // set smarter "Home" and "End" lpexView.doDefaultCommand("set keyAction.home contextHome"); lpexView.doDefaultCommand("set keyAction.end contextEnd"); // set "Alt+F1" key to compose special characters - use com.ibm.lpex.samples.ComposeAction lpexView.defineCommand("compose", ComposeAction.composeCommand); lpexView.defineAction("compose", ComposeAction.composeAction); lpexView.doDefaultCommand("set keyAction.a-f1 compose"); // set "Alt+J" to join next line's text with just one space in-between lpexView.doDefaultCommand("set keyAction.a-j myJoin"); // set "Alt+T" to do a block transfer - use com.ibm.lpex.samples.BlockTransferAction lpexView.doDefaultCommand("set actionClass.blockTransfer " + "com.ibm.lpex.samples.BlockTransferAction"); if (!isEmacs) lpexView.doDefaultCommand("set keyAction.a-t blockTransfer"); // set "Ctrl+Backspace" to delete and preserve the cursor column position lpexView.doDefaultCommand("set keyAction.c-backSpace.t.p.c myDeleteLine"); // set "Ctrl+N" to first search for the selected text, if any if (!isEmacs) lpexView.doDefaultCommand("set keyAction.c-n.t.p.c myFindNext"); // set "Ctrl+Shift+V" to do a paste replace, like "Alt+Z" does a block replace lpexView.doDefaultCommand("set keyAction.c-s-v.t pasteOverlay"); // set mouse button1 double-click to select the line (not word) lpexView.doDefaultCommand("set mouseAction.1-pressed.2 myBlockMarkElement"); // set default selection type to character (rather than the default stream) lpexView.doDefaultCommand("set block.defaultType character"); // define a "detab" command - use com.ibm.lpex.samples.DetabCommand lpexView.doDefaultCommand("set commandClass.detab com.ibm.lpex.samples.DetabCommand"); // add block-transfer action to the pop-up (context) menu, submenu "Selected" StringBuffer sb = new StringBuffer(lpexView.query("current.popup")); String transferSubmenu = " \"Tr&ansfer selection\" blockTransfer "; int i = sb.indexOf("popup.blockDelete "); if (i >= 0) { sb.insert(i, transferSubmenu); } else { sb.append(" separator" + transferSubmenu); } // if properties file, add option to compare ignoring mnemonics on submenu "Source" if ("prop".equals(parser(lpexView))) { String compareSubmenu = " \"Compare w/o &mnemonics...\" myPropCompare "; i = sb.indexOf("popup.sourceMenu"); if (i >= 0) { sb.insert(i + "popup.sourceMenu".length(), compareSubmenu); } else { sb.append(" separator beginSubmenu popup.sourceMenu" + compareSubmenu + "endSubmenu"); } } lpexView.doDefaultCommand("set popup " + sb.toString()); // indicate this profile has run lpexView.doDefaultCommand("set messageText TestUserProfile settings in effect."); } /** * Determines the document parser which will run after this user profile completes. * * @param lpexView the document view for which this profile is being run * @return the document parser name, or <code>null</code> if none */ public static String parser(LpexView lpexView) { String parser = null; if (!lpexView.queryOn("current.updateProfile.noParser")) { parser = lpexView.query("current.updateProfile.parser"); // if "associated", determine the parser via the document name extension if ("associated".equals(parser)) { parser = null; String extension = lpexView.query("name"); if (extension != null) { int extensionStart = extension.lastIndexOf('.'); if (extensionStart != -1) { extension = extension.substring(extensionStart); parser = lpexView.query("current.updateProfile.parserAssociation" + extension); } } } } return parser; } }