From: SVN by r. <sv...@ca...> - 2008-02-15 13:29:27
|
Author: roy Date: 2008-02-15 14:29:16 +0100 (Fri, 15 Feb 2008) New Revision: 236 Modified: src/main/java/nl/improved/sqlclient/SQLShell.java Log: added keyaction (Help for keys) support Modified: src/main/java/nl/improved/sqlclient/SQLShell.java =================================================================== --- src/main/java/nl/improved/sqlclient/SQLShell.java 2008-02-14 21:05:21 UTC (rev 235) +++ src/main/java/nl/improved/sqlclient/SQLShell.java 2008-02-15 13:29:16 UTC (rev 236) @@ -23,6 +23,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; import jcurses.widgets.Window; @@ -96,6 +98,8 @@ */ private CommandManager commands = new CommandManager(); + private Map<String, KeyAction> actionKeys = new HashMap<String, KeyAction>(); + /** * Constructor. */ @@ -125,6 +129,178 @@ //commands.register("\\\\Q[\\s]*", new QuitCommand("\\q")); commands.register("@.*", new ExecuteBatchCommand()); + // keys + actionKeys.put(Integer.toString(InputChar.KEY_LEFT), new KeyAction() { + public void execute() { + if (cursorPosition.x > 0) { + cursorPosition.x--; + } else if (cursorPosition.y > 0) { + cursorPosition.y--; + cursorPosition.x = commandLines.getLines().get(cursorPosition.y).length(); + } + } + public CharSequence getHelp() { + return "Arrow Left:\tMove cursor to the left"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_RIGHT), new KeyAction() { + public void execute() { + CharSequence tmp = commandLines.getLines().get(cursorPosition.y); + if (cursorPosition.x < tmp.length()) { + cursorPosition.x++; + } else if (cursorPosition.y < commandLines.getLines().size()-1) { + cursorPosition.x = 0; + cursorPosition.y++; + } + } + public CharSequence getHelp() { + return "Arrow Right:\tMove cursor to the right"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_UP), new KeyAction() { + public void execute() { + if (commandIndex > 0) { + commandLines = commandHistory.get(--commandIndex); + cursorPosition.y = commandLines.getLines().size()-1; + CharSequence lineBuffer = commandLines.getLines().get(cursorPosition.y); + cursorPosition.x = lineBuffer.length(); + } + } + public CharSequence getHelp() { + return "Arrow Up:\tBrowse to previous command in the history"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_DOWN), new KeyAction() { + public void execute() { + if (commandIndex < commandHistory.size()-1) { + commandLines = commandHistory.get(++commandIndex); + cursorPosition.y = commandLines.getLines().size()-1; + CharSequence lineBuffer = commandLines.getLines().get(cursorPosition.y); + cursorPosition.x = lineBuffer.length(); + } + } + public CharSequence getHelp() { + return "Arrow Down:\tBrowse to next command in the history"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_BACKSPACE), new KeyAction() { + public void execute() { + if (cursorPosition.x == 0) { + if (cursorPosition.y > 0) { + StringBuilder line = getEditableCommand().getEditableLines().remove(cursorPosition.y); + cursorPosition.y--; + StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); + cursorPosition.x = lineBuffer.length(); + lineBuffer.append(line); + } + } else { + StringBuilder tmp = getEditableCommand().getEditableLines().get(cursorPosition.y); + if (cursorPosition.x > 0) { + tmp.deleteCharAt(cursorPosition.x-1); + cursorPosition.x--; + } + } + } + public CharSequence getHelp() { + return "Backspace:\tRemove the character before the cursor position"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_DC), new KeyAction() { + public void execute() { + StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); + if (cursorPosition.x < lineBuffer.length()) { + StringBuilder tmp = getEditableCommand().getEditableLines().get(cursorPosition.y); + tmp.deleteCharAt(cursorPosition.x); + } + } + public CharSequence getHelp() { + return "Del:\tDelete the charactor at the current cursor position"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_PPAGE), new KeyAction() { + public void execute() { + if ((screenBuffer.size() + commandLines.getLines().size() + - (Toolkit.getScreenHeight()/2) * pageUpCount) > 0) { + pageUpCount++; + + } + } + public CharSequence getHelp() { + return "PageUp:\tMove back in screen history"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_NPAGE), new KeyAction() { + public void execute() { + if (pageUpCount > 0) { + pageUpCount--; + } + } + public CharSequence getHelp() { + return "PageDown:\tMove forward in screen history"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_END),new KeyAction() { + public void execute() { + cursorPosition.y = commandLines.getLines().size()-1; + CharSequence lineBuffer = commandLines.getLines().get(cursorPosition.y); + cursorPosition.x = lineBuffer.length(); + } + public CharSequence getHelp() { + return "End:\tMove the cursor to the end of the command"; + } + }); + actionKeys.put(Integer.toString(InputChar.KEY_HOME), new KeyAction() { + public void execute() { + cursorPosition.y = 0; + cursorPosition.x = 0; + } + public CharSequence getHelp() { + return "Home:\tMove the cursor to the start of the command"; + } + }); + actionKeys.put("", new KeyAction() { + public void execute() { + StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); + int previousBreak = SQLUtil.getLastBreakIndex(lineBuffer.substring(0, cursorPosition.x)); + lineBuffer.delete(previousBreak, cursorPosition.x); + cursorPosition.x = previousBreak; + } + public CharSequence getHelp() { + return "Control-W:\tRemove word before cursor position"; + } + }); + actionKeys.put("", new KeyAction() { // ctrl+u + public void execute() { + StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); + lineBuffer.delete(0, cursorPosition.x); + cursorPosition.x = 0; + } + public CharSequence getHelp() { + return "Control-U:\tRemove all characters before the cursor position"; + } + }); + actionKeys.put("", new KeyAction() { //Ctrl+D + public void execute() { + if (commandLines.getCommandString().length() == 0) { //Quit on empty commandline, ignore otherwise + executeCommand(new InputCommand("quit")); + } + } + public CharSequence getHelp() { + return "Control-D:\tExit sqlshell"; + } + }); + actionKeys.put("", new KeyAction() { // ctrl+a + public void execute() { + output("Abort requested"); + if (commandThread.isAlive() && commandThread.getCommand().abort()) { + output("Abort done.."); + } + } + public CharSequence getHelp() { + return "Control-A:\tAbort current command (if it is supported by that command)"; + } + }); + MAX_LINE_LENGTH = Toolkit.getScreenWidth()-(2+PROMPT.length()+2+1); // 2 spaces bouds.. prompt + "> " output("Welcome to the SQLShell client."); @@ -196,197 +372,119 @@ if (inp.getCode() != InputChar.KEY_PPAGE && inp.getCode() != InputChar.KEY_NPAGE) { pageUpCount = 0; // some character entered, so reset pageup count } - if (inp.isSpecialCode() || inp.toString().equals("") || inp.toString().equals("")) { - if (inp.getCode() == InputChar.KEY_LEFT) { - if (cursorPosition.x > 0) { - cursorPosition.x--; - } else if (cursorPosition.y > 0) { - cursorPosition.y--; - cursorPosition.x = commandLines.getLines().get(cursorPosition.y).length(); - } - } else if (inp.getCode() == InputChar.KEY_RIGHT) { - CharSequence tmp = commandLines.getLines().get(cursorPosition.y); - if (cursorPosition.x < tmp.length()) { - cursorPosition.x++; - } else if (cursorPosition.y < commandLines.getLines().size()-1) { - cursorPosition.x = 0; - cursorPosition.y++; - } - } else if (inp.getCode() == InputChar.KEY_UP) { - if (commandIndex > 0) { - commandLines = commandHistory.get(--commandIndex); - cursorPosition.y = commandLines.getLines().size()-1; - CharSequence lineBuffer = commandLines.getLines().get(cursorPosition.y); - cursorPosition.x = lineBuffer.length(); - } - } else if (inp.getCode() == InputChar.KEY_DOWN) { - if (commandIndex < commandHistory.size()-1) { - commandLines = commandHistory.get(++commandIndex); - cursorPosition.y = commandLines.getLines().size()-1; - CharSequence lineBuffer = commandLines.getLines().get(cursorPosition.y); - cursorPosition.x = lineBuffer.length(); - } - } else if (inp.getCode() == InputChar.KEY_BACKSPACE) { - if (cursorPosition.x == 0) { - if (cursorPosition.y > 0) { - StringBuilder line = getEditableCommand().getEditableLines().remove(cursorPosition.y); - cursorPosition.y--; - StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); - cursorPosition.x = lineBuffer.length(); - lineBuffer.append(line); - } - } else { - StringBuilder tmp = getEditableCommand().getEditableLines().get(cursorPosition.y); - if (cursorPosition.x > 0) { - tmp.deleteCharAt(cursorPosition.x-1); - cursorPosition.x--; - } - } - } else if (inp.getCode() == InputChar.KEY_DC) { - StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); - if (cursorPosition.x < lineBuffer.length()) { - StringBuilder tmp = getEditableCommand().getEditableLines().get(cursorPosition.y); - tmp.deleteCharAt(cursorPosition.x); - } - } else if (inp.getCode() == InputChar.KEY_PPAGE) { - if ((screenBuffer.size() + commandLines.getLines().size() - - (Toolkit.getScreenHeight()/2) * pageUpCount) > 0) { - pageUpCount++; - - } - } else if (inp.getCode() == InputChar.KEY_NPAGE) { - if (pageUpCount > 0) { - pageUpCount--; - } - } else if (inp.getCode() == InputChar.KEY_END) { - cursorPosition.y = commandLines.getLines().size()-1; - CharSequence lineBuffer = commandLines.getLines().get(cursorPosition.y); - cursorPosition.x = lineBuffer.length(); - } else if (inp.getCode() == InputChar.KEY_HOME) { - cursorPosition.y = 0; - cursorPosition.x = 0; - } else if (inp.toString() != null && inp.toString().equals("")) { // ctrl+w - StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); - int previousBreak = SQLUtil.getLastBreakIndex(lineBuffer.substring(0, cursorPosition.x)); - lineBuffer.delete(previousBreak, cursorPosition.x); - cursorPosition.x = previousBreak; - } else if (inp.toString() != null && inp.toString().equals("")) { // ctrl+u - StringBuilder lineBuffer = commandLines.getEditableLines().get(cursorPosition.y); - lineBuffer.delete(0, cursorPosition.x); - cursorPosition.x = 0; - } else + if (inp.isSpecialCode()) { + KeyAction ke = actionKeys.get(Integer.toString(inp.getCode()));// || inp.toString().equals("") || inp.toString().equals("")) { + if (ke != null) { + ke.execute(); + } else { debug("Unknown character: "+ inp.getCode()); - } else if (inp.toString().equals("")) { //Ctrl+D - if (commandLines.getCommandString().length() == 0) { //Quit on empty commandline, ignore otherwise - executeCommand(new InputCommand("quit")); } - } else if (inp.toString() != null && inp.toString().equals("")) { // ctrl+a - output("Abort requested"); - if (commandThread.isAlive() && commandThread.getCommand().abort()) { - output("Abort done.."); - } } else { - if (inp.getCharacter() == '\n') { - // execute the command - SQLCommand sqlCommand = getCommand(); - String command = sqlCommand.getCommandString(); - // search command... - if (command.length() > 0 && command.charAt(0) == '/') { - String matchPattern=".*"+command.substring(1,command.length())+".*"; - for (int cIndex = commandHistory.size()-1; cIndex >=0; cIndex--) { - if (cIndex == commandIndex) { - continue; // skip current command + KeyAction ke = actionKeys.get(inp.toString()); + if (ke != null) { + ke.execute(); + } else { + if (inp.getCharacter() == '\n') { // newline... see if the command can be executed + // execute the command + SQLCommand sqlCommand = getCommand(); + String command = sqlCommand.getCommandString(); + // search command... + if (command.length() > 0 && command.charAt(0) == '/') { // search in history + String matchPattern=".*"+command.substring(1,command.length())+".*"; + for (int cIndex = commandHistory.size()-1; cIndex >=0; cIndex--) { + if (cIndex == commandIndex) { + continue; // skip current command + } + SQLCommand newSqlCommand = commandHistory.get(cIndex); + String commandString = newSqlCommand.getCommandString(); + if (commandString.matches(matchPattern)) { + commandHistory.remove(commandIndex); + commandIndex = commandHistory.indexOf(newSqlCommand); + commandLines = newSqlCommand; + cursorPosition.y = 0; + cursorPosition.x = 0; + paint(); // force repaint + return; + } } - SQLCommand newSqlCommand = commandHistory.get(cIndex); - String commandString = newSqlCommand.getCommandString(); - if (commandString.matches(matchPattern)) { - commandHistory.remove(commandIndex); - commandIndex = commandHistory.indexOf(newSqlCommand); - commandLines = newSqlCommand; - cursorPosition.y = 0; - cursorPosition.x = 0; - paint(); // force repaint - return; + Toolkit.beep(); // TODO clear search?? + return; + } else if (executeCommand(sqlCommand)) { + // clear command history + if (commandIndex != commandHistory.size()-1) { + SQLCommand tmpLines = commandLines; + commandLines = commandHistory.get(commandHistory.size()-1); + if (commandLines.getCommandString().equals("")) { + commandHistory.add(commandHistory.size()-1, tmpLines); + } else { + commandHistory.add(tmpLines); + commandLines = tmpLines; + } } + if (!commandLines.getCommandString().equals("")) { + commandLines = new SQLCommand(); + commandHistory.add(commandLines); + newLine(); + } + commandIndex = commandHistory.size()-1; + cursorPosition.y = commandLines.getLines().size()-1; + cursorPosition.x = commandLines.getLines().get(cursorPosition.y).length(); + paint(); // force repaint + return; } - Toolkit.beep(); - return; } - if (executeCommand(sqlCommand)) { - // clear command history - if (commandIndex != commandHistory.size()-1) { - SQLCommand tmpLines = commandLines; - commandLines = commandHistory.get(commandHistory.size()-1); - if (commandLines.getCommandString().equals("")) { - commandHistory.add(commandHistory.size()-1, tmpLines); - } else { - commandHistory.add(tmpLines); - commandLines = tmpLines; - } + CharSequence newText; + if (inp.getCharacter() == '\t') { + try { + newText = getTabCompletion(commandLines, cursorPosition); + } catch(IllegalStateException e) { + output(getCommand().getCommandString()); // add command as well... + error(e); + return; } - if (!commandLines.getCommandString().equals("")) { - commandLines = new SQLCommand(); - commandHistory.add(commandLines); - newLine(); - } - commandIndex = commandHistory.size()-1; - cursorPosition.y = commandLines.getLines().size()-1; - cursorPosition.x = commandLines.getLines().get(cursorPosition.y).length(); - paint(); // force repaint - return; + } else { + newText = Character.toString(inp.getCharacter()); } - } - CharSequence newText; - if (inp.getCharacter() == '\t') { - try { - newText = getTabCompletion(commandLines, cursorPosition); - } catch(IllegalStateException e) { - output(getCommand().getCommandString()); // add command as well... - error(e); - return; - } - } else { - newText = Character.toString(inp.getCharacter()); - } - if (newText.equals("\n")) { - newLine(); // TODO Fix - } else { - List<StringBuilder> editableLines = getEditableCommand().getEditableLines(); - StringBuilder currentLine = editableLines.get(cursorPosition.y); - currentLine.insert(cursorPosition.x, newText); - cursorPosition.x += newText.length(); - // check if the new line is becoming too long - if (currentLine.length() > MAX_LINE_LENGTH) { - // TODO search for lastspace that is not between '' ?? - int lastSpace = currentLine.lastIndexOf(" "); - // check if there are enough 'next' lines - // if not.. add one - if (editableLines.size()-1 == cursorPosition.y) { - StringBuilder newLine = new StringBuilder(); - editableLines.add(newLine); + if (newText.equals("\n")) { + newLine(); // TODO Fix return in middle of an other line + } else { + List<StringBuilder> editableLines = getEditableCommand().getEditableLines(); + StringBuilder currentLine = editableLines.get(cursorPosition.y); + currentLine.insert(cursorPosition.x, newText); + cursorPosition.x += newText.length(); + // check if the new line is becoming too long + if (currentLine.length() > MAX_LINE_LENGTH) { + // TODO search for lastspace that is not between '' ?? + int lastSpace = currentLine.lastIndexOf(" "); + // check if there are enough 'next' lines + // if not.. add one + if (editableLines.size()-1 == cursorPosition.y) { + StringBuilder newLine = new StringBuilder(); + editableLines.add(newLine); + } + // check if the nextline has enough room for the new word + // if not.. add a new line + if (editableLines.get(cursorPosition.y+1).length() + + (currentLine.length()-lastSpace+1) > MAX_LINE_LENGTH) { + StringBuilder newLine = new StringBuilder(); + editableLines.add(cursorPosition.y+1, newLine); + } + // fetch the next line + StringBuilder nextLine = editableLines.get(cursorPosition.y+1); + // if the nextline already has some text.. add a space in front of it + if (nextLine.length() > 0) { + nextLine.insert(0, ' '); + } + // insert the new text at the beginning + nextLine.insert(0, currentLine.subSequence(lastSpace+1, currentLine.length())); + currentLine.delete(lastSpace, currentLine.length()); + // check if the cursor postition > the new line length + // calculate new x and go to nextline + if (cursorPosition.x >= lastSpace) { + cursorPosition.x = cursorPosition.x - (lastSpace+1); + cursorPosition.y++; + } } - // check if the nextline has enough room for the new word - // if not.. add a new line - if (editableLines.get(cursorPosition.y+1).length() - + (currentLine.length()-lastSpace+1) > MAX_LINE_LENGTH) { - StringBuilder newLine = new StringBuilder(); - editableLines.add(cursorPosition.y+1, newLine); - } - // fetch the next line - StringBuilder nextLine = editableLines.get(cursorPosition.y+1); - // if the nextline already has some text.. add a space in front of it - if (nextLine.length() > 0) { - nextLine.insert(0, ' '); - } - // insert the new text at the beginning - nextLine.insert(0, currentLine.subSequence(lastSpace+1, currentLine.length())); - currentLine.delete(lastSpace, currentLine.length()); - // check if the cursor postition > the new line length - // calculate new x and go to nextline - if (cursorPosition.x >= lastSpace) { - cursorPosition.x = cursorPosition.x - (lastSpace+1); - cursorPosition.y++; - } } } } @@ -1076,20 +1174,41 @@ return "Unkown command '"+ cmdString+"'"; } // default print all commands + // TODO iterate + StringBuilder returnValue = new StringBuilder(); + returnValue.append("Available key mappings:\n"); + int max = 0; + Iterator<KeyAction> iKeyActions = actionKeys.values().iterator(); + while (iKeyActions.hasNext()) { + max = Math.max(max, iKeyActions.next().getHelp().toString().indexOf('\t')); + } + iKeyActions = actionKeys.values().iterator(); + while (iKeyActions.hasNext()) { + returnValue.append(" "); + //returnValue.append(iKeyActions.next().getHelp()); + String help = iKeyActions.next().getHelp().toString(); + int index = help.indexOf('\t'); + returnValue.append(help.substring(0, index)); + for (int i = index; i < max; i++) { + returnValue.append(' '); + } + returnValue.append(help.substring(index)); + returnValue.append('\n'); + } + returnValue.append("\n\nAvailable commands:\n"); Iterator<Command> iCommands = commands.getCommands().iterator(); while (iCommands.hasNext()) { Command cmd = iCommands.next(); availableCommands.add(cmd.getCommandString()); } - StringBuilder returnValue = toColumns(availableCommands); + returnValue.append(toColumns(availableCommands)); String helpHeader = "\nHelp for SQLShell client "+SQLProperties.getProperty(SQLProperties.PropertyName.VERSION, "SVN Snapshot")+"\n"+ "Here you find a list of available commands. "+ "To get more information about a specific command enter:\n"+ " help command (for example 'help help')\n\n"+ "If the list is not sufficient enough you could try searching help using:\n"+ " help -k searchstring (for example help -k column)\n"+ - "This results in a list of commands matching the searchstring\n\n"+ - "Available commands:\n"; + "This results in a list of commands matching the searchstring\n\n"; returnValue.insert(0, helpHeader); return returnValue; } @@ -1381,6 +1500,11 @@ } + private interface KeyAction { + void execute(); + CharSequence getHelp(); + } + public static void main(String[] args) { SQLShell shell = new SQLShell(); shell.show(); |