タンブラー?

Big Sky

1月 27 '12

Vim scriptはウェブアプリケーション記述言語やったんやー

こんにちわ。昨今、ウェブ開発の進化はすざましいですね。PythonやPerlやJava、色んな言語で書かれていると思います。
もちろん編集にはVimを使っているかと思います。
でも編集だけ?

違うよね!
Vim scriptはウェブアプリケーション記述言語なんだよ!

Plack::App::Vim
package Plack::App::Vim;
use strict;
use warnings;
use parent qw/Plack::Component/;
use Plack::Request;
use Encode;
use JSON::PP;

sub prepare_app {
    my $self = shift;
    $self->{vim} ||= ’vim’;
    if (!$self->{server}) {
        open(my $f, ”vim —serverlist|”);
        my $server = ;
        close($f);
        chomp $server;
        $self->{server} = $server;
    }
    if (!$self->{encoding}) {
        open(my $f, sprintf(“%s —servername %s —remote-expr "&encoding"|”,
            $self->{vim}, $self->{server}));
        my $encoding = ;
        close($f);
        chomp $encoding;
        $self->{encoding} = $encoding;
    }
    $self;
}

sub call {
    my ($self, $env) = @_;
    my $req = Plack::Request->new($env);
    my $json = JSON::PP->new->ascii
        ->allow_singlequote->allow_blessed->allow_nonref;
    my $str = $json->encode({
        uri => $env->{PATH_INFO}||”,
        method => $req->method,
        headers => [split( /\n/, $req->headers->as_string)],
        content => $req->content,
    });
    $str =~ s!”!\x22!g;

    my $command;
    if ($^O eq ’MSWin32’) {
        $command = sprintf(
            ’%s —servername %s —remote-expr “vimplack#handle(“”“%s”“”)”’,
            $self->{vim}, $self->{server},
            encode($self->{encoding} || ’utf8’, $str));
    } else {
        $command = sprintf(
            ”%s —servername %s —remote-expr ‘vimplack#handle("%s")’”,
            $self->{vim}, $self->{server},
            encode($self->{encoding} || ’utf8’, $str));
    }
    open(my $f, ”$command|”);
    binmode $f, ’:utf8’;
    my $out = ;
    close $f;
    my $res = $json->decode($out);
    $res->[2][0] = encode_utf8 $res->[2][0] if $res;
    $res || [500, [‘Content-Type’ => ’text/plain’], [‘Internal Server Error’]];
}

1;

__END__

=head1 NAME

Plack::App::Vim - The Vim App in Plack

=head1 SYNOPSIS

  use Plack::Builder;
  use Plack::App::Vim;

  builder {
    mount “/” => Plack::App::Vim->new(server => ‘VIM’);
  };

=head1 DESCRIPTION

Plack::App::Vim allows you to write web application with Vim script.

=head1 AUTHOR

Yasuhiro Matsumoto

=head1 SEE ALSO

L

=cut
Plack::Appのアプリケーションハンドラを書いたよ。これを起動するpsgiファイルを用意するよ!

app.psgi
#!perl
use lib qw/lib/;
use Plack::Builder;
use Plack::App::Vim;

builder {
    mount ”/” => Plack::App::Vim->new(server => ’VIM’);
};
引数のserverにはclientserver機能が使えるVimを立ち上げ、そのサーバIDを指定しておく必要があるよ!
そしてVim側にハンドラを書くよ!

autoload/vimplack.vim
scriptencoding utf-8

function! vimplack#handle(req)
  let req = json#decode(a:req)
  let res = [200, [], [“hello world”]]
  return json#encode(res)
endfunction
PSGIプロトコルそのままですね!便利!

起動しよう!
# plackup app.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/
ブラウザでhttp://localhost:5000を開こう!
やたー!
あとはアプリケーション書き放題ですね!
試しに掲示板書いてみるよ!

autoload/vimplack.vim
scriptencoding utf-8

let s:comments = get(s:, ’comments’, [])

function! vimplack#handle(req)
  let req = json#decode(a:req)
  if req.uri == ”/”
    let res = [200, [“Content-Type”, ”text/html; charset=utf-8”], [“”
.”“
.”“
.”“
.”コメント:

.”“
.”“
.join(map(copy(s:comments), ’html#encodeEntityReference(v:val)’), ’
‘)
.”“
.”“
\]]
  elseif req.uri == ’/regist’ && req.method == ’POST’
    let params = {}
    for _ in map(split(req.content, ’&’), ’split(v:val,”=”)’)
      let params[_[0]] = iconv(http#decodeURI(_[1]), ’utf-8’, &encoding)
    endfor
    if has_key(params, ’comment’)
      call add(s:comments, params[‘comment’])
    endif
    let res = [302, [“Location”, ”/”], [“”]]
  else
    let res = [404, [], [“404 Dan Nout Found”]]
  endif
  return json#encode(res)
endfunction
アプリケーションの更新はVimを再起動するかautoload/vimplack.vimを開いている常態なら :so %
で行けるよ!

知らんかったー
Vim scriptはウェブアプリケーション記述言語やったんやー
mattn/p5-Plack-App-Vim - GitHub

Vim Application Handler for PSGI https://github.com/mattn/p5-Plack-App-Vim http://j.mp/xQfXtG