+sub vi_form_while {
+ my $text = shift;
+ my $cb = shift;
+
+ my $error = 0;
+ my ($c, $o, $k, $e);
+ do {
+ my $ntext = vi($text);
+ return undef if ($error && $ntext eq $text);
+
+ $text = $ntext;
+
+ my $form = Form::parse($text);
+ $error = 0;
+ ($c, $o, $k, $e) = @{ $form->[0] };
+ if ( $e ) {
+ $error = 1;
+ $c = "# Syntax error.";
+ goto NEXT;
+ }
+ elsif (!@$o) {
+ return 0;
+ }
+
+ my ($status, $msg) = $cb->( $text, [$c, $o, $k, $e] );
+ unless ( $status ) {
+ $error = 1;
+ $c = "# $msg";
+ }
+
+ NEXT:
+ $text = Form::compose([[$c, $o, $k, $e]]);
+ } while ($error);
+
+ return $text;
+}
+