Perlを編集しながら評価できるEditor
http://twitter.com/monjudoh/status/2038844182
この発言に触発されて、あると便利だよなぁと作ってみました。
とりあえずなので、上のペインで Ctrl+Enterを押すと書いてあるコードが Perlでevalされて下のペインに表示されます。選択している場合には選択していた場所だけが実行されます。機能はそれだけです。
Perlの評価部分に関しては以下の ipl.batを拝借しています。
日記帳だ! with Tux on Libserver :: irbをパクってiplを完成させてみた
以下の2つのファイルがコードの全体です。
実行するには、Perl5.10とJava6*1が必要になります。
MainFrame.java
import java.awt.event.*; import java.io.*; import javax.swing.*; public class MainFrame extends JFrame { private final ProcessBuilder builder_; private Process process_; private final JTextArea inputArea_ = new JTextArea(5, 20); private final JTextArea outputArea_ = new JTextArea(3, 20); public MainFrame() { super("Commander"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); builder_ = new ProcessBuilder("perl", "ipl.pl"); builder_.redirectErrorStream(true); JSplitPane root = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(inputArea_), new JScrollPane(outputArea_)); add(root); this.pack(); } public void start() throws IOException { process_ = builder_.start(); final Thread isThread = new Thread(new Runnable() { @Override public void run() { BufferedReader reader = new BufferedReader(new InputStreamReader(process_.getInputStream())); while (!Thread.currentThread().isInterrupted()) { try { final String line = reader.readLine(); if (line == null) break; SwingUtilities.invokeLater(new Runnable() { public void run() { if (outputArea_.isShowing()) { outputArea_.append(line); outputArea_.append("\r\n"); } }; }); } catch (Exception e) { e.printStackTrace(); } } } }, "InputStreamThread"); isThread.start(); final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process_.getOutputStream())); inputArea_.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER && e.isControlDown()) { e.consume(); String text = inputArea_.getSelectedText(); if (text == null || text.length() == 0) { text = inputArea_.getText(); } try { writer.append(text); writer.append("\r\n"); writer.flush(); } catch (IOException e1) { e1.printStackTrace(); } } } }); this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { if (process_ != null) { try { isThread.interrupt(); writer.append("exit\r\n"); process_.destroy(); process_.waitFor(); } catch (Exception e1) { e1.printStackTrace(); } process_ = null; } } }); } public static void main(String[] args) { MainFrame f = new MainFrame(); f.setVisible(true); try { f.start(); } catch (IOException e) { e.printStackTrace(); } } }
ipl.pl
#!/usr/bin/perl use feature ':5.10'; use List::Util qw(first max maxstr min minstr reduce shuffle sum); use Data::Dumper; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; use encoding 'shiftjis'; use IO::Handle; autoflush STDOUT; sub p { @_=($_) if !@_; while(1){ my $d=Dumper(shift(@_)); $d=~s/\\x{([0-9a-f]{4})}/chr(hex($1))/eg; print $d; last if !@_; print ','; } print "\n"; return undef } sub fr($) { open my $fh,"<",shift(@_); my @res=<$fh>; close $fh; return @res; } sub fw($@) { open my $fh,">",shift(@_); print $fh join("\n", @_ ),"\n"; close $fh; } sub fa($@) { open my $fh,">>",shift(@_); print $fh join("\n", @_ ),"\n"; close $fh; } sub ls($) { opendir my $fh,shift(@_); my @res=readdir($fh); closedir $fh; return grep( $_ !~ m/^\.\.?$/ , @res ); } my $__spool__ = ''; my $__tarminator__ = undef; my ($ANS,@ANS); while (1) { if(!defined $__tarminator__){ print '> '; } #else { print '* '; } my $__line__ = <>; print $__line__; if(defined $__tarminator__){ if (!defined $__line__) { $__tarminator__=undef; $__spool__ = ''; next; } elsif($__tarminator__ eq '' && $__line__=~m/^\s+$/) { $__tarminator__=undef; } elsif($__line__ =~ m/^##.*$__tarminator__\s*$/) { $__tarminator__=undef; } }else{ if ($__line__ =~ m/^##.*?(\S+)\s*$/) { $__tarminator__=$1; $__line__=''; } elsif($__line__ =~ m/{\s*$/) { $__tarminator__=''; } } $__spool__ .= $__line__; if (!defined $__tarminator__) { @ANS = do { eval($__spool__); }; if($@){ print $@; }else{ if(@ANS && ($__spool__ !~ m/;;\s*$/)){ print "=> "; p @ANS; } } $__spool__ = ''; } }
*1:確認していないけど、Java5でも動くかも?