/**
* Copyright (c) 2009, 2010 Mark Feber, MulgaSoft
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package com.mulgasoft.emacsplus.minibuffer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.texteditor.ITextEditor;
import com.mulgasoft.emacsplus.EmacsPlusActivator;
/**
* On CR, pass the minibuffer result back to the command invocation
*
* @author Mark Feber - initial API and implementation
*/
public abstract class ExecutingMinibuffer extends HistoryMinibuffer {
static final String A_MSG = " ["; //$NON-NLS-1$
static final String Z_MSG = "]"; //$NON-NLS-1$
static String ABORT_MSG = A_MSG + EmacsPlusActivator.getResourceString("Exec_Abort") + Z_MSG; //$NON-NLS-1$
static String COMPLETE_MSG = A_MSG + EmacsPlusActivator.getResourceString("Exec_Completion") + Z_MSG; //$NON-NLS-1$
static String NOMATCH_MSG = A_MSG + EmacsPlusActivator.getResourceString("Exec_NoMatch") + Z_MSG; //$NON-NLS-1$
private IMinibufferExecutable executable;
public ExecutingMinibuffer(IMinibufferExecutable executable) {
super();
setExecutable(executable);
}
public void initMinibufferText(String text){
initMinibuffer(text);
}
/**
* @see com.mulgasoft.emacsplus.minibuffer.WithMinibuffer#getMinibufferPrefix()
*/
@Override
protected String getMinibufferPrefix() {
return (executable != null ? executable.getMinibufferPrefix() : EMPTY_STR);
}
protected IMinibufferExecutable getExecutable() {
return executable;
}
private void setExecutable(IMinibufferExecutable executable) {
this.executable = executable;
}
/**
* Pass the minibuffer result back to the command invocation
*
* @see com.mulgasoft.emacsplus.minibuffer.WithMinibuffer#executeResult(org.eclipse.ui.texteditor.ITextEditor, java.lang.Object)
*/
@Override
protected boolean executeResult(ITextEditor editor, Object commandResult) {
return executeResult(editor,executable,commandResult);
}
boolean executeResult(ITextEditor editor, IMinibufferExecutable executable, Object commandResult) {
boolean result = true;
if (executable != null) {
result = executable.executeResult(editor,commandResult);
}
return result;
}
protected boolean exitExecuteResult(ITextEditor editor, Object commandResult) {
// Save the executable for invocation after leaving current minibuffer.
// We do this so that we can call another minibuffer command invoked from here
// in this thread, rather than processing it as an asynchUI. The proximate
// cause is that the invoked minibuffer is set up before the invoking
// minibuffer is torn down (which can call setKeyFilter(false) and the command
// we're invoking may have specified true.
boolean result = false;
IMinibufferExecutable exec = getExecutable();
leave();
if (exec != null) {
result = executeResult(editor,exec,commandResult);
}
return result;
}
/**
* Set the result message back on the invoking command
*
* @param resultString the message
* @param resultError error if true
* @param forceNow if true, display immediately
*/
protected void setResultMessage(String resultString, boolean resultError, boolean forceNow) {
if (forceNow) {
super.setResultMessage(resultString, resultError);
}
executable.setResultMessage(resultString,resultError);
}
/**
* @see com.mulgasoft.emacsplus.minibuffer.WithMinibuffer#setResultMessage(java.lang.String, boolean)
*/
protected void setResultMessage(String resultString, boolean resultError) {
executable.setResultMessage(resultString,resultError);
}
protected void setResultMessage(String resultString) {
executable.setResultMessage(resultString,false);
}
/**
* @see com.mulgasoft.emacsplus.minibuffer.WithMinibuffer#initializeBuffer(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.ui.IWorkbenchPage)
*/
@Override
protected boolean initializeBuffer(ITextEditor editor, IWorkbenchPage page) {
return true;
}
/**
* Minor cleanups after leaving
*
* @see com.mulgasoft.emacsplus.minibuffer.WithMinibuffer#leave(boolean)
*/
protected void leave(boolean closeDialog) {
super.leave(closeDialog);
setExecutable(null);
}
/**
* charEvent fragment: only allow numbers or edits & escapes
* @param event
*/
protected void numCharEvent(VerifyEvent event) {
event.doit = false;
switch (event.character) {
case 0x0D: // CR - execute command (if complete) \r
case 0x1B: // ESC - another way to leave
case 0x08: // BS
case 0x7F: // DEL
super.charEvent(event);
break;
default:
if (checkAlt(event)) {
// enable history events
if (dispatchAlt(event)) {
event.doit = false;
break;
}
} else if ((Character.isDigit(event.character) && ((event.stateMask & SWT.MODIFIER_MASK) == 0)) || ('-' == event.character)) {
// accept if plain number or minus
super.charEvent(event);
} else {
beep();
}
}
}
/**
* charEvent fragment: process any text char, but also treat it as a <CR>
* @param event
*/
protected void immediateCharEvent(VerifyEvent event) {
event.doit = false;
switch (event.character) {
case 0x0D: // CR - execute command (if complete) \r
case 0x1B: // ESC - another way to leave
case 0x08: // BS
case 0x7F: // DEL
super.charEvent(event);
break;
default:
// respond immediately to a character
super.charEvent(event);
this.executeCR(event);
}
}
/**
* charEvent fragment: disallow spaces and tabs
* @param event
*/
protected void noSpaceCharEvent(VerifyEvent event) {
event.doit = false;
switch (event.character) {
case ' ': // beep on space
case '\t': // or tab
event.doit = false;
beep();
break;
default:
super.charEvent(event);
}
}
}