Okay... Here is a hack that allows you to remap arbitrary keystrokes in Matlab's Command Window and Editor. This is an unsupported hack that involves undocumented internals of the IDE. But it's "magic" like you were hoping for. Works in R2008b and R2009b for me.
First, define a Java class that can handle events by replacing them with other keystroke input. Compile this to a JAR and get it on your Matlab's javaclasspath.
package test;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.text.JTextComponent;
import javax.swing.text.TextAction;
/**
* An action that responds to an event with another keystroke.
*/
public class KeyReplacementAction extends TextAction {
private final char replacement;
/**
* @param name Name of this action (ignored in practice)
* @param replacement char to replace the event with
*/
public KeyReplacementAction(String name, char replacement) {
super(name);
this.replacement = replacement;
}
public void actionPerformed(ActionEvent e) {
if (!(e.getSource() instanceof JTextComponent)) {
return;
}
JTextComponent src = (JTextComponent) e.getSource();
KeyEvent replacementEvent = new KeyEvent(src, KeyEvent.KEY_TYPED,
java.lang.System.currentTimeMillis(), 0,
KeyEvent.VK_UNDEFINED, replacement);
src.dispatchEvent(replacementEvent);
}
}
Now, use Matlab code to dig into the IDE's Swing widgets, find the keymaps for the editor and command window, and add handlers for the remapping to them.
function remap_keys_in_text_areas()
%REMAP_KEYS_IN_TEXT_AREAS Custom key remapping in Matlab GUI text areas
%
% Must be called after the editor is open, otherwise it won't find the
% editor keymap.
% { from, to; ... }
% Try "disp(char(1:1024))" to see all chars that work in your Matlab font
map = {
'$' '^'
'#' char(181) % might be useful for text formatting
};
make_sure_editor_is_open(); % otherwise we won't find its keymap
keymaps = find_ide_keymaps();
for i = 1:size(map,1)
[from,to] = map{i,:};
disp(sprintf('Re-binding %s to %s in text areas', from, to));
for j = 1:numel(keymaps)
bind_keystroke_for(keymaps{j}, from, to);
end
end
function make_sure_editor_is_open()
s = find_editor_widgets();
if isempty(s.editors)
edit;
end
function bind_keystroke_for(keymap, from, to)
%BIND_KEYSTROKE_FOR Remap a single keystroke in a text component
import javax.swing.KeyStroke;
import java.awt.event.InputEvent;
import test.KeyReplacementAction;
key = javax.swing.KeyStroke.getKeyStroke(from);
action = KeyReplacementAction(['remap ' from ' to ' to], to);
keymap.addActionForKeyStroke(key, action);
function out = find_ide_keymaps
%FIND_IDE_KEYMAPS Find keymap objects for Matlab IDE widgets
set = java.util.HashSet();
s = find_editor_widgets();
widgets = [s.cmdwin s.editors];
for i = 1:numel(widgets)
set.add(widgets{i}.getKeymap());
end
set = set.toArray();
out = cell(size(set));
for i = 1:numel(set)
out{i} = set(i);
end
function out = find_editor_widgets
%FIND_EDITOR_WIDGETS Find editor and command window widgets in Matlab Swing GUI
out.cmdwin = [];
out.editors = {};
wins = java.awt.Window.getOwnerlessWindows();
for i = 1:numel(wins)
if isa(wins(i), 'com.mathworks.mde.desk.MLMainFrame')
out.cmdwin = get_command_window_from_mainframe(wins(i));
elseif isa(wins(i), 'com.mathworks.mde.desk.MLMultipleClientFrame')
out.editors = [out.editors get_text_areas_from_editor_frame(wins(i))];
end
end
function out = get_command_window_from_mainframe(frame)
out = findobj_swing_widget(frame, 'com.mathworks.mde.cmdwin.XCmdWndView');
function out = get_text_areas_from_editor_frame(frame)
out = findobj_swing_widget(frame, 'com.mathworks.widgets.SyntaxTextPane');
function out = findobj_swing_widget(widget, klass)
%FINDOBJ_SWING_WIDGET Recursively find all child components of given class
out = {};
if isa(widget, klass)
out{end+1} = widget;
end
for i = 1:widget.getComponentCount()
out = [out findobj_swing_widget(widget.getComponent(i-1), klass)];
end
To activate the remappings, just call the function. You could do this from within startup.m to have it happen automatically.
>> remap_keys_in_text_areas
Re-binding $ to ^ in text areas
Re-binding # to µ in text areas