home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / vile-src.zip / vile-8.1 / perl.xs < prev    next >
Text File  |  1998-09-27  |  88KB  |  3,522 lines

  1. /*
  2.  * perl.xs        -- perl interface for vile.
  3.  *
  4.  * Author: Kevin Buettner, Brendan O'Dea
  5.  *
  6.  * (with acknowledgments to the authors of the nvi perl interface and
  7.  * to Sean Ahern who has contributed snippets of code here and there
  8.  * and many valuable suggestions.)
  9.  *
  10.  * Created: Fall, 1997
  11.  *
  12.  * Description: The following code provides an interface to Perl from
  13.  * vile.  The file api.c (sometimes) provides a middle layer between
  14.  * this interface and the rest of vile.
  15.  *
  16.  * $Header: /usr/build/vile/vile/RCS/perl.xs,v 1.30 1998/09/28 00:50:30 Kuntal.Daftary Exp $
  17.  */
  18.  
  19. /*#
  20.   #
  21.   # Note: This embedded documentation may be retrieved for formatting
  22.   # with one of the pod transformers as follows.  To make the
  23.   # pod file, do
  24.   #
  25.   #     perl -lne 'print if s/^\s{1,2}#\s{0,1}//' perl.xs
  26.   #
  27.   # To transform the pod file into something nicely formatted, do
  28.   # one or more of the following:
  29.   #
  30.   #     pod2text vile-perl-api.pod >vile-perl-api.doc
  31.   #
  32.   #     pod2html vile-perl-api.pod >vile-perl-api.html
  33.   #
  34.   #     pod2man  vile-perl-api.pod >vile-perl-api.man
  35.   #
  36.   #     pod2latex vile-perl-api.pod >vile-perl-api.latex
  37.   #
  38.   # I experimented with different formatting layouts.  I found that I
  39.   # was unable to dispense with the initial transformation because
  40.   # xsubpp doesn't like it when some of my pod documentation started
  41.   # in the left-most column.  I've also found that placing the # in
  42.   # the left-most column will sometimes screw up xsubpp wrt to
  43.   # preprocessor statements.  It does not get confused when when there
  44.   # are one or more spaces preceding the pound sign.  I usually like
  45.   # to indent things by four spaces, and yet I wanted to use ^A-f in
  46.   # vile to reformat things, so I settled on two spaces, followed by
  47.   # a pound sign, followed by a single space, followed by whatever
  48.   # as the most pleasing layout.
  49.   #
  50.   #
  51.   # =pod
  52.   #
  53.   # =head1 NAME
  54.   #
  55.   # vile-perl-api       -- Vile/Perl interface reference
  56.   #
  57.   # =head1 DESCRIPTION
  58.   #
  59.   # This document describes the interface by which by Perl scripts may
  60.   # access the I<vile> editor's internals when run from an editor in which
  61.   # Perl has been embedded.
  62.   #
  63.   # There are presently two packages which comprise this interface.  They
  64.   # are:
  65.   #
  66.   # =over 4
  67.   #
  68.   # =item Vile
  69.   #
  70.   # Subroutines for accessing and controlling vile in general.
  71.   #
  72.   # =item Vile::Buffer
  73.   #
  74.   # Subroutines and methods for accessing individual buffers.
  75.   #
  76.   # =back
  77.   #
  78.   # A Vile::Window package is being contemplated, but has not been
  79.   # written yet.
  80.   #
  81.   # =head2 Calling Perl from Vile
  82.   #
  83.   # The perl interpreter may be invoked from I<vile> using either
  84.   # the I<perl> or I<perldo> commands.
  85.   #
  86.   # =over 4
  87.   #
  88.  */
  89.  
  90. /* contortions to avoid typedef conflicts */
  91. #define main perl_main
  92. #define regexp perl_regexp
  93.  
  94. /* for perl */
  95. #include <EXTERN.h>
  96. #include <perl.h>
  97. #include <XSUB.h>
  98.  
  99. #undef main
  100. #undef regexp
  101. #undef HUGE
  102.  
  103. /* Some earlier versions of perl don't have GIMME_V or G_VOID. We must
  104.    be careful of the order in which we check things if these defines
  105.    are activated. */
  106. #ifndef GIMME_V
  107. #define GIMME_V GIMME
  108. #endif
  109.  
  110. #ifndef G_VOID
  111. #define G_VOID G_SCALAR
  112. #endif
  113.  
  114. /* Prior to perl5.005, the PL_ prefix wasn't used for things such
  115.    as PL_rs.  Define the PL_ macros that we use if necessary. */
  116.  
  117. #include <patchlevel.h>        /* This is perl's patchlevel.h */
  118.  
  119. #if PATCHLEVEL < 5
  120. #define PL_incgv incgv
  121. #define PL_rs rs
  122. #define PL_ofslen ofslen
  123. #define PL_ofs ofs
  124. #define PL_ors ors
  125. #define PL_orslen orslen
  126. #endif
  127.  
  128. /* for vile */
  129. #include "estruct.h"
  130. #include "edef.h"
  131.  
  132. #include "api.h"
  133.  
  134. extern REGION *haveregion;
  135.  
  136. static PerlInterpreter *perl_interp;
  137. static int use_ml_as_prompt;
  138. static SV *svcurbuf;        /* $Vile::current_buffer in perl */
  139. static int svcurbuf_set(SV *, MAGIC *);
  140. static MGVTBL svcurbuf_accessors = {
  141.     /* Virtual table for svcurbuf magic. */
  142.     NULL, svcurbuf_set, NULL, NULL, NULL
  143. };
  144.  
  145. static int perl_init(void);
  146. static void xs_init(void);
  147. static int  perl_prompt(void);
  148. static int  perldo_prompt(void);
  149.  
  150. /* write each line to message line */
  151. static int
  152. write_message(SV *sv)
  153. {
  154.     int count = 0;
  155.     char *text = SvPV(sv, na);
  156.     char *nl;
  157.  
  158.     while (text)
  159.     {
  160.     if ((nl = strchr(text, '\n')))
  161.     {
  162.         *nl = 0;
  163.         while (*++nl == '\n')
  164.         ;
  165.  
  166.         if (!*nl)
  167.         nl = 0;
  168.     }
  169.  
  170.     mlforce("%s", text);
  171.     text = nl;
  172.     count++;
  173.     }
  174.  
  175.     return count;
  176. }
  177.  
  178. /* require a file, `optional' indicates that it is OK for the file not
  179.    to exist */
  180. static int
  181. require(char *file, int optional)
  182. {
  183.     /* require the file */
  184.     perl_require_pv(file);
  185.  
  186.     /* OK */
  187.     if (!SvTRUE(GvSV(errgv)))
  188.     return TRUE;
  189.  
  190.     if (optional)
  191.     {
  192.     /* this error is OK for optional files */
  193.     SV *tmp = newSVpv("Can't locate ", 0);
  194.     char const *check;
  195.     int sz;
  196.     int not_found;
  197.  
  198.     sv_catpv(tmp, file);
  199.     sv_catpv(tmp, " ");
  200.     check = SvPV(tmp, sz);
  201.     not_found = !strncmp(SvPV(GvSV(errgv), na), check, sz);
  202.     SvREFCNT_dec(tmp);
  203.  
  204.     if (not_found)
  205.         return SORTOFTRUE;
  206.     }
  207.  
  208.     write_message(GvSV(errgv));
  209.     return FALSE;
  210. }
  211.  
  212. /* When no region is specified, this will cause the entire buffer to
  213.    be selected without moving DOT. */
  214. void
  215. perl_default_region(void)
  216. {
  217.     static REGION region;
  218.     MARK save_DOT = DOT;
  219.     DOT.l = lforw(buf_head(curbp));
  220.     DOT.o = 0;
  221.     MK.l  = lback(buf_head(curbp));
  222.     MK.o  = 0;
  223.     regionshape = FULLLINE;
  224.     haveregion = NULL;
  225.     if (getregion(®ion)) {
  226.     haveregion = ®ion;
  227.     /* This should really go in getregion(), but other parts of
  228.        vile break when we do this. */
  229.     if (is_header_line(region.r_end, curbp) && !b_val(curbp, MDNEWLINE))
  230.         region.r_size--;
  231.     }
  232.     DOT = save_DOT;
  233. }
  234.  
  235. /*
  236.  * Create a VB buffer handle object.  These objects are both
  237.  * blessed into the Vile::Buffer class as well as made magical
  238.  * so that they may also be used as filehandles.
  239.  */
  240. static SV *
  241. newVBrv(SV *rv, VileBuf *sp)
  242. {
  243.     if (sp->perl_handle == 0) {
  244.     sp->perl_handle = newGVgen("Vile::Buffer");
  245.     GvSV((GV*)sp->perl_handle) = newSV(0);
  246.     sv_setiv(GvSV((GV*)sp->perl_handle), (IV) sp);
  247.     SvREFCNT_inc(sp->perl_handle);
  248.     sv_magic(sp->perl_handle, rv, 'q', Nullch, 0);
  249.     gv_IOadd((GV*)sp->perl_handle);
  250.     IoLINES(GvIO((GV*)sp->perl_handle)) = 0;    /* initialise $. */
  251.     }
  252.     else
  253.     SvREFCNT_inc(sp->perl_handle);
  254.  
  255.     sv_upgrade(rv, SVt_RV);
  256.     SvRV(rv) = sp->perl_handle;
  257.  
  258.     SvROK_on(rv);
  259.     return sv_bless(rv, gv_stashpv("Vile::Buffer", TRUE));
  260. }
  261.  
  262. static VileBuf *
  263. getVB(SV *sv, char **croakmessage_ptr)
  264. {
  265.     VileBuf *vbp = 0;
  266.     if (sv_isa(sv, "Vile::Buffer")) {
  267.     vbp = (VileBuf *)SvIV((SV*)GvSV((GV*)SvRV(sv)));
  268.     if (vbp == 0) {
  269.         *croakmessage_ptr = "buffer no longer exists";
  270.     }
  271.     }
  272.     else {
  273.     *croakmessage_ptr = "buffer of wrong type";
  274.     }
  275.     return vbp;
  276. }
  277.  
  278. void
  279. perl_free_handle(void *handle)
  280. {
  281.     /*
  282.      * Zero out perl's handle to the VileBuf structure
  283.      */
  284.     sv_setiv(GvSV((GV*)handle), 0);
  285.  
  286.     /*
  287.      * Decrement the reference count to indicate the fact that
  288.      * we are no longer referencing it from the api private structure.
  289.      * If there aren't any other references from within perl either,
  290.      * then this scalar will be collected.
  291.      */
  292.     SvREFCNT_dec(handle);
  293. }
  294.  
  295. static int recursecount = 0;
  296.  
  297. static int
  298. do_perl_cmd(SV *cmd, int inplace)
  299. {
  300.     int old_discmd;
  301.     int old_isnamedcmd;
  302.  
  303.     use_ml_as_prompt = 0;
  304.  
  305.     if (perl_interp || perl_init()) {
  306.     REGION region;
  307.     VileBuf *curvbp;
  308.  
  309.     if (recursecount == 0) {
  310.         curvbp = api_bp2vbp(curbp);
  311.  
  312.         if (getregion(®ion) != TRUE) {
  313.         /* shouldn't ever get here. But just in case... */
  314.         perl_default_region();
  315.         if (getregion(®ion) != TRUE) {
  316.             mlforce("BUG: getregion won't return TRUE in perl.xs.");
  317.         }
  318.         }
  319.         if (is_header_line(region.r_end, curbp) && !b_val(curbp, MDNEWLINE))
  320.         region.r_size--;
  321.  
  322.         /* Initialize some of the fields in curvbp */
  323.         curvbp->region = region;
  324.         curvbp->regionshape = regionshape;
  325.         curvbp->inplace_edit = inplace;
  326.  
  327.         sv_setsv(svcurbuf, newVBrv(sv_2mortal(newSV(0)), curvbp));
  328.         IoLINES(GvIO((GV*)curvbp->perl_handle)) = 0;  /* initialise $. */
  329.     }
  330.  
  331.     /* We set the following stuff up in the event that we call
  332.        one of the mlreply methods.  If they are not set up this
  333.        way, we won't always be prompted... */
  334.         clexec = FALSE;
  335.         old_discmd = discmd;
  336.         discmd = TRUE;
  337.     old_isnamedcmd = isnamedcmd;    /* for mlreply_dir */
  338.     isnamedcmd = TRUE;
  339.     recursecount++;
  340.  
  341. #define PDEBUG 0
  342. #if PDEBUG
  343.     printf("\nbefore eval\n");
  344.         sv_dump(svcurbuf);
  345. #endif
  346.     sv_setpv(GvSV(errgv),"");
  347.     if (SvROK(cmd) && SvTYPE(SvRV(cmd)) == SVt_PVCV)
  348.     {
  349.          dSP;
  350.          PUSHMARK(sp);
  351.          PUTBACK;
  352.          perl_call_sv(cmd, G_EVAL|G_VOID|G_DISCARD);
  353.     }
  354.     else
  355.         perl_eval_sv(cmd, G_DISCARD|G_NOARGS|G_KEEPERR);
  356. #if PDEBUG
  357.     printf("after eval\n");
  358.         sv_dump(svcurbuf);
  359. #endif
  360.  
  361.     recursecount--;
  362.         discmd = old_discmd;
  363.     isnamedcmd = old_isnamedcmd;
  364.  
  365.     if (recursecount == 0) {
  366.         SvREFCNT_dec(SvRV(svcurbuf));
  367.         api_command_cleanup();
  368.     }
  369.  
  370.     if (!SvTRUE(GvSV(errgv)))
  371.         return TRUE;
  372.  
  373.     write_message(GvSV(errgv));
  374.     }
  375.  
  376.     return FALSE;
  377. }
  378.  
  379. /*
  380.  * procedures for bindable callbacks: see Vile::register*
  381.  */
  382.  
  383. static SV *opsv;
  384.  
  385. static int
  386. perl_oper(void)
  387. {
  388.     return do_perl_cmd(opsv, FALSE);
  389. }
  390.  
  391. int
  392. perl_call_sub(void *data, int oper, int f, int n)
  393. {
  394.     AV *av = data;    /* callback is an array containing: */
  395.     SV **name;        /* the registered name, */
  396.     SV **sub;        /* a sub name or coderef to call, */
  397.     SV **req;        /* and an [optional] file to require */
  398.  
  399.     switch (av_len(av))
  400.     {
  401.     case 2: /* (name, sub, require) */
  402.         if ((req = av_fetch(av, 2, 0)) && SvTRUE(*req))
  403.         if (!require(SvPV(*req, na), FALSE))
  404.             return FALSE;
  405.  
  406.         /* FALLTHRU */
  407.  
  408.     case 1: /* (name, sub) */
  409.         if (!(name = av_fetch(av, 0, 0)) || !SvTRUE(*name))
  410.         croak("BUG: can't fetch name SV");
  411.  
  412.         if (!(sub = av_fetch(av, 1, 0)) || !SvTRUE(*sub))
  413.         croak("BUG: can't fetch subroutine SV");
  414.  
  415.         break;
  416.  
  417.     default:
  418.         croak("BUG: array contains %d elements", av_len(av) + 1);
  419.     }
  420.  
  421.     /* call the subroutine */
  422.     if (oper)
  423.     {
  424.     opcmd = OPOTHER;
  425.     opsv = *sub;
  426.     f = vile_op(f, n, perl_oper, SvPV(*name, na));
  427.     }
  428.     else
  429.     {
  430.     if (!f)
  431.         n = 1;
  432.  
  433.     while (n-- && (f = do_perl_cmd(*sub, FALSE)))
  434.         ;
  435.     }
  436.  
  437.     return f;
  438. }
  439.  
  440. void
  441. perl_free_sub(void *data)
  442. {
  443.     AV *av = data;
  444.     av_undef(av);
  445. }
  446.  
  447. /*
  448.  * Prompt for and execute a perl command.
  449.  *
  450.  * This function is actually only a wrapper for perl_prompt below to make
  451.  * the history management easier.
  452.  *
  453.   #
  454.   # =item :perl STMTS
  455.   #
  456.   # The I<perl> command will cause perl to execute one or more
  457.   # perl statements.  The user is usually prompted for the statments
  458.   # to execute immediately after ":perl " is entered.  The user is
  459.   # expected to enter legal perl statements or expressions.  These
  460.   # statements must all fit on one line.  (Vile's :-line will scroll
  461.   # horizontally though, so don't worry about running out of space.)
  462.   #
  463.   # The perl command may also appear in macros in vile's internal
  464.   # macro language, in which case the perl statements to execute must
  465.   # appear as a double quoted string to the perl command.  The user
  466.   # is not prompted in this case.
  467.   #
  468.   # Regardless, prior to execution, the global variable,
  469.   # C<$Vile::>C<current_buffer> is set to an object of type C<Vile::Buffer>
  470.   # which represents the current buffer.  The statements to be executed
  471.   # may choose to act either directly or indirectly on the current
  472.   # buffer via this variable or a suitable alias.
  473.   #
  474.   # Normally, the cursor's current position, also referred to as I<dot>,
  475.   # is left unchanged upon return from perl.  It can be propagated
  476.   # back to a viewable window by explicitly setting via the
  477.   # C<Vile::Buffer::>C<dot> method.
  478.   #
  479.   # For purposes of reading from the buffer, there is always a region
  480.   # associated with the buffer object.  By default, this region is the
  481.   # entire buffer.  (Which means that potentially, the entire buffer
  482.   # may be acted upon.) This range may be restricted by the user in
  483.   # the normal way through the use of a range specification which
  484.   # precedes the perl command.   E.g,
  485.   #
  486.   #     30,40perl @l = <$Vile::current_buffer>
  487.   #
  488.   # will cause lines 30 thru 40 to be placed into the @l array.
  489.   #
  490.  */
  491.  
  492. int
  493. perl(int f GCC_UNUSED, int n GCC_UNUSED)
  494. {
  495.     int status;
  496.  
  497. #if OPT_HISTORY
  498.     if (recursecount == 0)
  499.     hst_init(EOS);
  500. #endif
  501.  
  502.     status = perl_prompt();
  503.  
  504. #if OPT_HISTORY
  505.     if (recursecount == 0)
  506.     hst_flush();
  507. #endif
  508.  
  509.     return status;
  510. }
  511.  
  512. static int
  513. perl_prompt(void)
  514. {
  515.     register int status;
  516.     char buf[NLINE];    /* buffer to receive command into */
  517.     SV *cmd;
  518.  
  519.     buf[0] = EOS;
  520.     if ((status = mlreply_no_opts("Perl command: ", buf, sizeof(buf))) != TRUE)
  521.         return status;
  522.  
  523.     status = do_perl_cmd(cmd = newSVpv(buf, 0), FALSE);
  524.     SvREFCNT_dec(cmd);
  525.     return status;
  526. }
  527.  
  528. #define isoctal(c) ((c) >= '0' && (c) <= '7')
  529. static int octal(char **s)
  530. {
  531.     int oct = 0;
  532.     int i = (**s > '3') ? 2 : 3;
  533.  
  534.     while (i-- && isoctal(**s))
  535.     {
  536.     oct *= 8;
  537.     oct += *((*s)++) - '0';
  538.     }
  539.  
  540.     return oct;
  541. }
  542.  
  543. /*#
  544.   #
  545.   # =item :perldo STMTS E<lt>EnterE<gt> OPTIONS
  546.   #
  547.   # The I<perldo> command is like the perl command, but it takes
  548.   # various options making it possible to write "one liners" to
  549.   # operate on the current buffer in much the same way that you might
  550.   # write a one line perl command at the prompt of your favorite shell
  551.   # to operate on a file.  The options even mimic those provided by
  552.   # the perl interpreter, so if you are familiar with one, you'll be
  553.   # familiar with the other.
  554.   #
  555.   # After entering the perldo command (preceded by an optional range
  556.   # specification) on the :-line, the user will be prompted for some
  557.   # perl statements to execute.  These should usually be written to
  558.   # operate on the $_ variable and leave the result in $_.
  559.   #
  560.   # After pressing the B<Enter> key, you'll be prompted for a set
  561.   # of options.  The default options are -lpi and will even be displayed
  562.   # as such.  The B<-i> switch causes the buffer to be edited in place.
  563.   # The B<-p> switch causes the user supplied statements to be placed
  564.   # in a loop which fetches lines one by one place them in $_ for each
  565.   # iteration of the loop along with a trailing C<print> which'll cause
  566.   # whatever's left in $_ to be put back into the buffer.  The B<-l> switch
  567.   # causes an initial chomp to be done on each line after it is read.
  568.   # It will also cause the output record separator to be set so that
  569.   # when $_ is written back to the buffer, it will end up on a line of
  570.   # its own.
  571.   #
  572.   # For example, the command:
  573.   #
  574.   #     :25,30perldo $_ = sprintf("%4d",$lnum++) . $_
  575.   #                  -lpi
  576.   #
  577.   # will cause each line in between 20 and 30 inclusive to be prefixed
  578.   # with a the number given by $lnum, which is also incremented for
  579.   # each line processed.  You'll probably want to initialize $lnum to
  580.   # some appropriate value via the I<perl> command first, perhaps
  581.   # like this:
  582.   #
  583.   #     :perl $lnum = 142;
  584.   #
  585.   # [I include this example, because this is something that I've
  586.   # wanted to do from time to time, when citing snippets of code
  587.   # which I want to discuss in an email message.]
  588.   #
  589.   # =item perldo options
  590.   #
  591.   # =over 4
  592.   #
  593.   # =item -n
  594.   #
  595.   # Enclose the perl statement(s) in a loop which iterates of the records
  596.   # (usually lines) of the region.  Each record in the region will
  597.   # be placed in $_.
  598.   #
  599.   # =item -p
  600.   #
  601.   # Like B<-n>, but do a print (of $_) at the end of the loop.
  602.   #
  603.   # =item -i
  604.   #
  605.   # Enable the I<inplace_edit> flag for the buffer.  When used with
  606.   # either B<-n> or B<-p>, this will cause the lines to be deleted from the
  607.   # buffer as they are read.
  608.   #
  609.   # Unlike the corresponding perl command line switch, it is not possible
  610.   # to specify a backup file.  If you don't like what happens, just hit
  611.   # the 'B<u>' key to undo it.
  612.   #
  613.   # =item -l
  614.   #
  615.   # Only meaningful when used with either B<-n> or B<-p>.  This will
  616.   # perform an initial chomp on $_ after a record has been read.
  617.   #
  618.   # =item -0
  619.   #
  620.   # This must be followed by one or more digits which represent the
  621.   # value with which to set $/ (which is the input record separator).
  622.   # The special value B<00> indicates that $/ should be set to the
  623.   # empty string which will cause Perl to slurp input in paragraph
  624.   # mode.  The special value 0777 indicates that perl should slurp
  625.   # the entire region without paying attention to record separators.
  626.   # Normally, $/ is set to '\n' which corresponds to -012
  627.   #
  628.   # =item -a
  629.   #
  630.   # Turn on autosplit mode.  Upon being read, each record is split
  631.   # into the @F array.
  632.   #
  633.   # =item -F
  634.   #
  635.   # When used with B<-a>, specify an alternate pattern to split on.
  636.   #
  637.   # =back
  638.   #
  639.   # The default region for the perldo command is the line on which
  640.   # the cursor is currently on.  The reason for this is that it is
  641.   # often used like vile's builtin substitute operator is and this
  642.   # is the default region for the substitute command.  You can of
  643.   # course use any of the standard means to operate over larger
  644.   # regions, e.g,
  645.   #
  646.   #     :1,$perldo s/a/b/g
  647.   #
  648.   #
  649.  */
  650.  
  651. int
  652. perldo(int f GCC_UNUSED, int n GCC_UNUSED)
  653. {
  654.     int status;
  655.  
  656. #if OPT_HISTORY
  657.     hst_init(EOS);
  658. #endif
  659.  
  660.     status = perldo_prompt();
  661.  
  662. #if OPT_HISTORY
  663.     hst_flush();
  664. #endif
  665.  
  666.     return status;
  667. }
  668.  
  669. static int
  670. perldo_prompt(void)
  671. {
  672.     register int status;
  673.     char buf[NLINE];    /* buffer to receive command into */
  674.     char obuf[NLINE];    /* buffer for options */
  675.     SV *cmd;        /* constructed command string */
  676.  
  677. #define    OPT_i    001
  678. #define    OPT_n    002
  679. #define    OPT_p    004
  680. #define    OPT_l    010
  681. #define    OPT_a    020
  682.     int opts = 0;
  683.     char *o = obuf;
  684.     char *split = "' '";
  685.  
  686. #define    RS_PARA    0776
  687. #define    RS_NONE    0777
  688.     int i_rs = '\n';
  689.     int o_rs = RS_NONE;
  690.  
  691.     buf[0] = EOS;
  692.     if ((status = mlreply_no_opts("Perl command: ", buf, sizeof(buf))) != TRUE)
  693.     return status;
  694.  
  695. #if OPT_HISTORY
  696.     hst_glue('\r');
  697. #endif
  698.  
  699.     strcpy(obuf, "-lpi");
  700.     if ((status = mlreply_no_opts("options: ", obuf, sizeof(obuf))) != TRUE)
  701.     return status;
  702.  
  703.     /* skip optional leading `-' */
  704.     if (*o == '-')
  705.     o++;
  706.  
  707.     /* parse options */
  708.     while (*o)
  709.     switch (*o)
  710.     {
  711.     case 'a': opts |= OPT_a; o++; break;
  712.     case 'i': opts |= OPT_i; o++; break;
  713.     case 'n': opts &= ~OPT_p; opts |= OPT_n; o++; break;
  714.     case 'p': opts &= ~OPT_n; opts |= OPT_p; o++; break;
  715.     case 'l':
  716.         opts |= OPT_l;
  717.         o++;
  718.         if (isoctal(*o))
  719.         o_rs = octal(&o);
  720.         else
  721.         o_rs = i_rs;
  722.  
  723.         break;
  724.  
  725.     case '0':
  726.         /* special cases: 00, 0777 */
  727.         if (*++o == '0' && !isoctal(*(o+1)))
  728.         {
  729.         i_rs = RS_PARA;
  730.         o++;
  731.         }
  732.         else if (!strncmp(o, "777", 3))
  733.         {
  734.         i_rs = RS_NONE;
  735.         o += 3;
  736.         }
  737.         else
  738.         i_rs = octal(&o);
  739.  
  740.         break;
  741.  
  742.     case 'F':
  743.         opts |= OPT_a; /* implied */
  744.         if (*++o == '/' || *o == '"' || *o == '\'')
  745.         {
  746.         char sep = *o;
  747.         char esc = 0;
  748.  
  749.         split = o++;
  750.         while (*o)
  751.         {
  752.             if (*o == sep && !esc)
  753.             {
  754.             o++;
  755.             break;
  756.             }
  757.  
  758.             if (*o++ == '\\')
  759.             esc ^= 1;
  760.             else
  761.             esc = 0;
  762.         }
  763.  
  764.         if (*o && *o != ' ')
  765.         {
  766.             mlforce("[no closing %c]", sep);
  767.             return FALSE;
  768.         }
  769.         }
  770.         else if (*o)
  771.         {
  772.         split = o++;
  773.         while (*o && *o != ' ') o++;
  774.         }
  775.         else
  776.         {
  777.         mlforce("[-F requires an argument]");
  778.         return FALSE;
  779.         }
  780.  
  781.         if (*o)
  782.         *o++ = 0; /* terminate */
  783.         /* FALLTHRU */
  784.         else
  785.         break;
  786.  
  787.     case ' ':
  788.         while (*o == ' ') o++;
  789.         if (!*o)
  790.         break; /* trailing spaces */
  791.  
  792.         if (*o == '-' && *(o+1))
  793.         {
  794.         o++;
  795.         break;
  796.         }
  797.  
  798.         /* FALLTHRU */
  799.  
  800.     default:
  801.         mlforce("[invalid option -%s]", o);
  802.         return FALSE;
  803.     }
  804.  
  805.     /* construct command: block with localised $/ and $\ */
  806.     cmd = newSVpv("{local $/=", 0); /*}*/
  807.     if (i_rs == RS_NONE)
  808.     sv_catpv(cmd, "undef");
  809.     else if (i_rs == RS_PARA)
  810.     sv_catpv(cmd, "''");
  811.     else
  812.     sv_catpvf(cmd, "\"\\x%02x\"", i_rs);
  813.  
  814.     sv_catpv(cmd, ";local $\\=");
  815.     if (o_rs == RS_NONE)
  816.     sv_catpv(cmd, "undef");
  817.     else if (o_rs == RS_PARA)
  818.     sv_catpv(cmd, "\"\\n\\n\"");
  819.     else
  820.     sv_catpvf(cmd, "\"\\x%02x\"", o_rs);
  821.  
  822.     /* set default output handle */
  823.     sv_catpv(cmd, ";my $_save_fh=select ");
  824.     if (opts & OPT_i)
  825.     sv_catpv(cmd, "$Vile::current_buffer"); /* -i goes to buffer */
  826.     else
  827.     sv_catpv(cmd, "STDOUT"); /* mini */
  828.  
  829.     /* implicit loop for -n/-p */
  830.     if (opts & (OPT_n|OPT_p))
  831.     {
  832.     sv_catpv(cmd, ";LINE:while(<$Vile::current_buffer>){"); /*}*/
  833.     if (opts & OPT_l)
  834.         sv_catpv(cmd, "chomp;");
  835.  
  836.     /* autosplit to @F */
  837.     if (opts & OPT_a)
  838.     {
  839.         sv_catpv(cmd, "@F=split ");
  840.         if (*split == '/' || *split == '"' || *split == '\'')
  841.         sv_catpv(cmd, split);
  842.         else
  843.         {
  844.         char delim;
  845.         char *try = "'~#\200\1";
  846.         /* try to find a delimiter not in the string */
  847.         while (*try && strchr(split, *try)) try++;
  848.         delim = *try;
  849.         sv_catpvf(cmd, "q%c%s%c", delim, split, delim);
  850.         }
  851.  
  852.         sv_catpv(cmd, ";");
  853.     }
  854.     }
  855.     else
  856.     sv_catpv(cmd, ";");
  857.  
  858.     /* add the command */
  859.     sv_catpv(cmd, buf);
  860.  
  861.     /* close the loop */
  862.     if (opts & (OPT_n|OPT_p))
  863.     {
  864. /*{*/    sv_catpv(cmd, "}");
  865.     if (opts & OPT_p)
  866.         sv_catpv(cmd, "continue{print}");
  867.     }
  868.     else
  869.     sv_catpv(cmd, ";");
  870.  
  871.     /* reset handle and close block */
  872. /*{*/ sv_catpv(cmd, "select $_save_fh}");
  873.  
  874.     status = do_perl_cmd(cmd, opts & OPT_i);
  875.     SvREFCNT_dec(cmd);
  876.  
  877.     return status;
  878. }
  879.  
  880. static int
  881. svcurbuf_set(SV *sv, MAGIC *mg)
  882. {
  883.     VileBuf *vbp;
  884.     if (sv_isa(sv, "Vile::Buffer")
  885.         && (vbp = (VileBuf *) SvIV((SV*)GvSV((GV*)SvRV(sv)))) != NULL)
  886.     {
  887.     api_swscreen(NULL, vbp);
  888.     }
  889.     else {
  890.     /* FIXME: Print out warning about reseting things */
  891.     /* Reset to curbp */
  892.     sv_setsv(svcurbuf, newVBrv(sv_2mortal(newSV(0)), api_bp2vbp(curbp)));
  893.     }
  894.     return 1;
  895. }
  896.  
  897. static int
  898. perl_init(void)
  899. {
  900.     char *embedding[] = { "", "-e", "0" };
  901.     char *bootargs[]  = { "Vile", NULL };
  902.     SV   *svminibuf;
  903.     AV   *av;
  904.     SV   *sv;
  905.     int  len;
  906.     char  temp[NFILEN];
  907.     char *vile_path;
  908. #ifdef _WIN32
  909.     const char *perl_subdir = "\\perl";
  910. #else
  911.     const char *perl_subdir = "/perl";
  912. #endif
  913.     static char svcurbuf_name[] = "Vile::current_buffer";
  914.  
  915.     perl_interp = perl_alloc();
  916.     perl_construct(perl_interp);
  917.  
  918.     if (perl_parse(perl_interp, xs_init, 3, embedding, NULL)) {
  919.     perl_destruct(perl_interp);
  920.     perl_free(perl_interp);
  921.     perl_interp = NULL;
  922.     return FALSE;
  923.     }
  924.     perl_call_argv("Vile::bootstrap", G_DISCARD, bootargs);
  925.  
  926.     /* Add our own paths to the front of @INC */
  927. #ifdef HELP_LOC
  928.     av_unshift(av = GvAVn(PL_incgv), 2);
  929.     av_store(av, 0, newSVpv(lengthen_path(strcpy(temp,"~/.vile/perl")),0));
  930.     sv = newSVpv(HELP_LOC,0);
  931.     sv_catpv(sv, "perl");
  932.     av_store(av, 1, sv);
  933. #endif
  934.     /* Always recognize environment variable */
  935.     if ((vile_path = getenv("VILE_LIBRARY_PATH")) != 0)
  936.     {
  937.     /*
  938.      * "patch" @INC to look (first) for scripts in the directory
  939.      * %VILE_LIBRARY_PATH%\\perl .
  940.      */
  941.     len = strlen(vile_path) - 1;
  942.     if (len >= 0 && is_slashc(vile_path[len]))
  943.         vile_path[len] = '\0'; /* Chop trailing path delim */
  944.     av_unshift(av = GvAVn(PL_incgv), 1);
  945.     sv = newSVpv(vile_path, 0);
  946.     sv_catpv(sv, (char *) perl_subdir);
  947.     av_store(av, 0, sv);
  948.     }
  949.  
  950.     /* Obtain handles to specific perl variables, creating them
  951.        if they do not exist. */
  952.     svcurbuf  = perl_get_sv(svcurbuf_name,  TRUE);
  953.  
  954.     svminibuf   = newVBrv(newSV(0), api_bp2vbp(bminip));
  955.  
  956.     /* Tie STDOUT and STDERR to miniscr->PRINT() function */
  957.     sv_magic((SV *) gv_fetchpv("STDOUT", TRUE, SVt_PVIO), svminibuf, 'q',
  958.          Nullch, 0);
  959.     sv_magic((SV *) gv_fetchpv("STDERR", TRUE, SVt_PVIO), svminibuf, 'q',
  960.          Nullch, 0);
  961.     sv_magic((SV *) gv_fetchpv("STDIN", TRUE, SVt_PVIO), svminibuf, 'q',
  962.          Nullch, 0);
  963.  
  964.     sv_magic(svcurbuf, NULL, '~', svcurbuf_name, strlen(svcurbuf_name));
  965.     mg_find(svcurbuf, '~')->mg_virtual = &svcurbuf_accessors;
  966.     SvMAGICAL_on(svcurbuf);
  967.  
  968.     /* Some things are better (or easier) to do in perl... */
  969.     perl_eval_pv("$SIG{__WARN__}='Vile::Warn';"
  970.          "sub Vile::Buffer::PRINTF {"
  971.          "    my $fh=shift; my $fmt=shift;"
  972.          "    print $fh sprintf($fmt,@_);"
  973.          "}", G_DISCARD);
  974.  
  975.     /* Load user or system wide initialization script */
  976.     require("vileinit.pl", TRUE);
  977.     return TRUE;
  978. }
  979.  
  980. /* Register any extra external extensions */
  981.  
  982. extern void boot_DynaLoader _((CV* cv));
  983. extern void boot_Vile _((CV* cv));
  984.  
  985. static void
  986. xs_init()
  987. {
  988.     char *file = __FILE__;
  989.     dXSUB_SYS;
  990.     newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
  991.     newXS("Vile::bootstrap", boot_Vile, file);
  992. }
  993.  
  994. /*
  995.  * Stringify a code ref so it may be called from vile.
  996.  */
  997.  
  998. static char *CRfmtstr = "perl \"&{$Vile::CRs[%d]}\"";
  999. static AV *CRarray   = 0;
  1000. static int freeCRidx = 0;
  1001.  
  1002. static char *
  1003. stringify_coderef(SV *coderef) {
  1004.     char buf[40];
  1005.     int idx = 0;
  1006.     int badstore = 0;
  1007.  
  1008.     if (CRarray == 0) {
  1009.     /* Short name to keep the size of strings short on the vile side */
  1010.     CRarray = perl_get_av("Vile::CRs", TRUE);
  1011.     freeCRidx = -1;
  1012.     }
  1013.  
  1014.     if (freeCRidx >= 0) {
  1015.     SV **svp;
  1016.     idx = freeCRidx;
  1017.     svp = av_fetch(CRarray, (I32) idx, 0);
  1018.     if (svp == 0) {
  1019.         /* Something's screwy... */
  1020.         freeCRidx = -1;
  1021.     }
  1022.     else {
  1023.         freeCRidx = SvIV(*svp);
  1024.         SvREFCNT_dec(*svp);
  1025.     }
  1026.     if (av_store(CRarray, (I32) idx, SvREFCNT_inc(coderef)) == 0) {
  1027.         badstore = 1;
  1028.         SvREFCNT_dec(coderef);
  1029.     }
  1030.     }
  1031.  
  1032.     if (freeCRidx < 0 || badstore) {
  1033.     av_push(CRarray, SvREFCNT_inc(coderef));
  1034.     idx = av_len(CRarray);
  1035.     }
  1036.  
  1037.     sprintf(buf, CRfmtstr, idx);
  1038.     return strdup(buf);
  1039. }
  1040.  
  1041. void
  1042. perl_free_callback(char *callback)
  1043. {
  1044.     int idx;
  1045.     if (sscanf(callback, CRfmtstr, &idx) == 1) {
  1046.     SV **svp;
  1047.     SV *svfreeCRidx;
  1048.     svp = av_fetch(CRarray, (I32) idx, 0);
  1049.     if (svp == 0)
  1050.         return;    /* Something screwy, bail... */
  1051.  
  1052.     if (!SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVCV)
  1053.         return;    /* Most likely freed already (?) */
  1054.  
  1055.     SvREFCNT_dec(*svp);    /* This should deallocate it */
  1056.  
  1057.     svfreeCRidx = SvREFCNT_inc(newSViv(freeCRidx));
  1058.     if (av_store(CRarray, (I32) idx, svfreeCRidx) == 0) {
  1059.         /* Not successful (!) */
  1060.         SvREFCNT_dec(svfreeCRidx);
  1061.     }
  1062.     else {
  1063.         freeCRidx = idx;
  1064.     }
  1065.     }
  1066. }
  1067.  
  1068. /*
  1069.  * Returns a line number given an SV.  '$' represents the last line
  1070.  * in the file. '$$' represents the line after the last line.  The
  1071.  * only time that '$' and '$$' represent the same line is when the
  1072.  * buffer is empty.
  1073.  */
  1074.  
  1075. static I32
  1076. sv2linenum(SV *sv)
  1077. {
  1078.     I32 linenum;
  1079.  
  1080.     if (!SvIOKp(sv) && strcmp(SvPV(sv,na),"$") == 0) {
  1081.     linenum = line_count(curbp);
  1082.     }
  1083.     else if (!SvIOKp(sv) && strcmp(SvPV(sv,na),"$$") == 0) {
  1084.     linenum = line_count(curbp) + 1;
  1085.     }
  1086.     else {
  1087.     linenum = SvIV(sv);
  1088.     if (linenum < 1) {
  1089.         linenum = 1;
  1090.     }
  1091.     else if (linenum > line_count(curbp)) {
  1092.         linenum = line_count(curbp);
  1093.     }
  1094.     }
  1095.     return linenum;
  1096. }
  1097.  
  1098.  
  1099. /*
  1100.  * Returns an offset within the current line (where DOT is) given an
  1101.  * SV.  '$' represents the last non-newline character in the line.  '$$'
  1102.  * represents the newline character.  The only time '$' and '$$' represent
  1103.  * the same position is when the line is empty.
  1104.  */
  1105.  
  1106. static I32
  1107. sv2offset(SV *sv)
  1108. {
  1109.     I32 offset;
  1110.     if (!SvIOKp(sv) && strcmp(SvPV(sv,na),"$") == 0) {
  1111.     offset = llength(DOT.l) - 1;
  1112.     if (offset < 0)
  1113.         offset = 0;
  1114.     }
  1115.     else if (!SvIOKp(sv) && strcmp(SvPV(sv,na),"$$") == 0) {
  1116.     offset = llength(DOT.l);
  1117.     }
  1118.     else {
  1119.     offset = SvIV(sv);
  1120.     if (offset < 0) {
  1121.         offset = 0;
  1122.     }
  1123.     else if (offset > llength(DOT.l)) {
  1124.         offset = llength(DOT.l);
  1125.     }
  1126.     }
  1127.     return offset;
  1128. }
  1129.  
  1130. /*
  1131.  * Fetch a line or portion thereof from the current buffer.  Like
  1132.  * api_dotgline(), except it's faster because it creates an SV of
  1133.  * the right size from the outset.  It's also faster because it
  1134.  * relies on the caller to set up the fake window properly.  (Not
  1135.  * a big deal if only getting a scalar, but it can be if fetching
  1136.  * an entire array.)
  1137.  *
  1138.  * Does not handle rectangular regions.
  1139.  *
  1140.  * Implementation notes:  In my first attempts at implementing these
  1141.  * functions, I used the region's end mark to determine when/where to
  1142.  * stop.  This usually worked, but there were times (particularly
  1143.  * when the inplace_edit flag was set to true) when the end marker
  1144.  * would either disappear entirely or would move to some undesirable
  1145.  * location.  I considered "fixing" the mark machinery so that it
  1146.  * would work as I desired.  The only problem with this is that my
  1147.  * attempts to do this could either destabilize the rest of the editor
  1148.  * or cause vile to be incompatible with real vi.
  1149.  *
  1150.  * So I decided that a lot of the code would be cleaner if I simply
  1151.  * gave up trying to use the end marker.  Instead I rely on the
  1152.  * length field, r_size, located in the region structure to determine
  1153.  * the right time to stop.  The only problem I see with this approach
  1154.  * is that motions could screw it up... but I suppose we can adjust
  1155.  * the r_size field in one way or another to account for this.
  1156.  *
  1157.  * In any event, I've decided that it is a bad idea to rely on
  1158.  * either of the marks once buffer modifications have started.
  1159.  */
  1160.  
  1161. static int
  1162. svgetline(SV **svp, VileBuf *vbp, char *rsstr, int rslen)
  1163. {
  1164.     int len;
  1165.     int nllen;
  1166.     char *text;
  1167.     SV *sv;
  1168.     if (   is_header_line(DOT, curbp) || vbp->region.r_size <= 0) {
  1169.     *svp = newSVsv(&sv_undef);
  1170.     return FALSE;
  1171.     }
  1172.  
  1173.     len = llength(DOT.l) - DOT.o;
  1174.     text = DOT.l->l_text + DOT.o;
  1175.  
  1176.     if (len > vbp->region.r_size)
  1177.     len = vbp->region.r_size;
  1178.  
  1179.     if (   vbp->region.r_size > 0
  1180.         && (   lforw(DOT.l) != buf_head(curbp)
  1181.         || b_val(curbp, MDNEWLINE)))
  1182.     {
  1183.     nllen = 1;
  1184.     DOT.o = 0;
  1185.     DOT.l = lforw(DOT.l);
  1186.     }
  1187.     else {
  1188.     nllen = 0;
  1189.     DOT.o += len;
  1190.     }
  1191.  
  1192.     vbp->region.r_size -= len + (nllen != 0);
  1193.  
  1194.     if (vbp->inplace_edit)
  1195.     vbp->ndel += len + (nllen != 0);
  1196.  
  1197.     if (len < 0)
  1198.     len = 0;        /* shouldn't happen */
  1199.  
  1200.     *svp = sv = newSV(len + nllen + 1);    /* +1 for \0 */
  1201.  
  1202.     if (len > 0) {
  1203.     sv_setpvn(sv, text, len);
  1204.     if (nllen > 0)
  1205.         sv_catpvn(sv, "\n", 1);
  1206.     }
  1207.     else if (nllen > 0) {
  1208.     sv_setpvn(sv, "\n", 1);
  1209.     }
  1210.     else {
  1211.     sv_setpvn(sv, "", 0);
  1212.     }
  1213.  
  1214.     return TRUE;
  1215. }
  1216.  
  1217. /*
  1218.  * Fetch an entire region (or remainder thereof).
  1219.  */
  1220.  
  1221. static int
  1222. svgetregion(SV **svp, VileBuf *vbp, char *rsstr, int rslen)
  1223. {
  1224.     int len;
  1225.     SV *sv;
  1226.     LINEPTR lp;
  1227.     int off;
  1228.  
  1229.     if (is_header_line(DOT, curbp) || vbp->region.r_size <= 0) {
  1230.     *svp = newSVsv(&sv_undef);
  1231.     return FALSE;
  1232.     }
  1233.  
  1234.     len = vbp->region.r_size;
  1235.     vbp->region.r_size = 0;
  1236.  
  1237.     *svp = sv = newSV(len + 1);    /* + 1 for \0 */
  1238.     sv_setpvn(sv, "", 0);
  1239.  
  1240.     if (vbp->inplace_edit)
  1241.     vbp->ndel += len;
  1242.  
  1243.     lp = DOT.l;
  1244.     off = DOT.o;
  1245.     while (len > 0) {
  1246.     int clen = llength(lp) - off;
  1247.  
  1248.     if (clen > len)
  1249.         clen = len;
  1250.  
  1251.     if (clen > 0) {
  1252.         sv_catpvn(sv, lp->l_text + off, clen);
  1253.         len -= clen;
  1254.         off += clen;
  1255.     }
  1256.  
  1257.     if (len > 0) {
  1258.         if (lforw(lp) != buf_head(curbp) || b_val(curbp, MDNEWLINE))
  1259.         sv_catpvn(sv, "\n", 1);
  1260.         len--;
  1261.         off++;
  1262.     }
  1263.  
  1264.     if (off > llength(lp)) {
  1265.         lp = lforw(lp);
  1266.         off = 0;
  1267.     }
  1268.     }
  1269.     DOT.l = lp;
  1270.     DOT.o = off;
  1271.  
  1272.     return TRUE;
  1273. }
  1274.  
  1275. /*
  1276.  * Gets the next portion of a region up to the next record separator
  1277.  * or the end of region, whichever comes first.
  1278.  */
  1279.  
  1280. static int
  1281. svgettors(SV **svp, VileBuf *vbp, char *rsstr, int rslen)
  1282. {
  1283.     int len, reglen;
  1284.     SV *sv;
  1285.     int rs1;
  1286.     int orig_rslen = rslen;
  1287.     LINEPTR lp;
  1288.     int off;
  1289.  
  1290.  
  1291.     /* See if we're already at the end of the region and have nothing
  1292.        to do. */
  1293.     if (is_header_line(DOT, curbp) || vbp->region.r_size <= 0) {
  1294.     *svp = newSVsv(&sv_undef);
  1295.     return FALSE;
  1296.     }
  1297.  
  1298.     /* Adjust rsstr if need be */
  1299.     if (rslen == 0) {
  1300.     rsstr = "\n\n";
  1301.     rslen = 2;
  1302.     }
  1303.  
  1304.     /* Get first separator character */
  1305.     rs1 = *rsstr;
  1306.  
  1307.     /* Compute length of region up to record separator or til
  1308.        end of region, whichever comes first */
  1309.     lp  = DOT.l;
  1310.     off = DOT.o;
  1311.     len = 0;
  1312.     reglen = vbp->region.r_size;
  1313.     for (;;) {
  1314.     int loff;
  1315.     int cont_off;
  1316.     LINEPTR cont_lp;
  1317.     int fidx;
  1318.     int rsidx;
  1319.  
  1320.     if (off > llength(lp)) {
  1321.         off = 0;
  1322.         lp = lforw(lp);
  1323.     }
  1324.  
  1325.     if (lp == buf_head(curbp) || len >= reglen)
  1326.         goto have_length;
  1327.  
  1328.     /* loff is the last offset that we'll do our initial search
  1329.        to on this line */
  1330.     loff = llength(lp);
  1331.     if (loff - off > reglen - len)
  1332.         loff = off + reglen - len;
  1333.  
  1334.     /* Try to find the first record separator character */
  1335.     if (rs1 == '\n') {
  1336.         /* newline; no searching needed, must be at end of line */
  1337.         if (loff < llength(lp)) {
  1338.         len += loff;
  1339.         goto have_length;
  1340.         }
  1341.         else
  1342.         fidx = loff;
  1343.     }
  1344.     else {
  1345.         /* Gotta search */
  1346.         for (fidx = off; fidx < loff && lp->l_text[fidx] != rs1; fidx++)
  1347.         ;
  1348.         if (fidx >= loff) {
  1349.         if (loff < llength(lp)) {
  1350.             len += loff;
  1351.             goto have_length;
  1352.         }
  1353.         len += loff - off + 1;
  1354.         off = loff + 1;
  1355.         continue;
  1356.         }
  1357.     }
  1358.  
  1359.     /* If we get to this point, fidx points at first character in
  1360.        the record separator. */
  1361.     len += fidx - off + 1;
  1362.     cont_lp = lp;
  1363.     cont_off = fidx + 1;
  1364.  
  1365.     /* Attempt to match the rest of the record separator */
  1366.     for (rsidx = 1; rsidx < rslen; rsidx++) {
  1367.         fidx++;
  1368.         if (fidx >= llength(lp)) {
  1369.         lp = lforw(lp);
  1370.         fidx = 0;
  1371.         }
  1372.         if (lp == buf_head(curbp) || len + rsidx - 1 >= reglen) {
  1373.         off = fidx;
  1374.         len += rsidx - 1;
  1375.         goto have_length;
  1376.         }
  1377.         if (rsstr[rsidx] == '\n') {
  1378.         if (fidx < llength(lp))
  1379.             break;
  1380.         }
  1381.         else if (rsstr[rsidx] != lp->l_text[fidx])
  1382.         break;
  1383.     }
  1384.  
  1385.     if (rsidx >= rslen) {
  1386.         len += rslen - 1;
  1387.         off = fidx;
  1388.         goto have_length;
  1389.     }
  1390.     lp = cont_lp;
  1391.     off = cont_off;
  1392.     }
  1393. have_length:
  1394.  
  1395.     /* See if we have the special paragraph separator and if so, consume
  1396.        as many additional newlines as we can */
  1397.     if (orig_rslen == 0) {
  1398.     lp = lforw(lp);
  1399.     off = 0;
  1400.     while (   ! (lp == buf_head(curbp) || len >= reglen)
  1401.            && llength(lp) == 0)
  1402.     {
  1403.         len++;
  1404.         lp = lforw(lp);
  1405.         off = 0;
  1406.     }
  1407.     }
  1408.  
  1409.     /* Make sure there's still something left to return */
  1410.     if (len <= 0) {
  1411.     *svp = newSVsv(&sv_undef);
  1412.     return FALSE;
  1413.     }
  1414.  
  1415.     vbp->region.r_size -= len;
  1416.  
  1417.     /* Now copy the region over to the SV... */
  1418.     *svp = sv = newSV(len + 1);    /* + 1 for \0 */
  1419.     sv_setpvn(sv, "", 0);
  1420.  
  1421.     if (vbp->inplace_edit)
  1422.     vbp->ndel += len;
  1423.  
  1424.     lp = DOT.l;
  1425.     off = DOT.o;
  1426.     while (len > 0) {
  1427.     int clen = llength(lp) - off;
  1428.  
  1429.     if (clen > len)
  1430.         clen = len;
  1431.  
  1432.     if (clen > 0) {
  1433.         sv_catpvn(sv, lp->l_text + off, clen);
  1434.         len -= clen;
  1435.         off += clen;
  1436.     }
  1437.  
  1438.     if (len > 0) {
  1439.         if (lforw(lp) != buf_head(curbp) || b_val(curbp, MDNEWLINE))
  1440.         sv_catpvn(sv, "\n", 1);
  1441.         len--;
  1442.         off++;
  1443.     }
  1444.  
  1445.     if (off > llength(lp)) {
  1446.         lp = lforw(lp);
  1447.         off = 0;
  1448.     }
  1449.     }
  1450.     DOT.l = lp;
  1451.     DOT.o = off;
  1452.  
  1453.     return TRUE;
  1454. }
  1455.  
  1456.  
  1457. MODULE = Vile    PACKAGE = Vile
  1458.  
  1459. PROTOTYPES: DISABLE
  1460.  
  1461.   #
  1462.   # =back
  1463.   #
  1464.   # =head2 Loading Perl Modules from Vile
  1465.   #
  1466.   # A perl module that is usable by vile should probably be
  1467.   # located some place on the @INC path.  For vile, the @INC
  1468.   # array has been augmented to include $HOME/.vile/perl and
  1469.   # /usr/local/share/vile.  (This latter path may differ depending
  1470.   # upon your machine and configuration options.)  If you want to
  1471.   # see what exactly what these paths are, just issue the following
  1472.   # command from within vile:
  1473.   #
  1474.   #     :perl print join ':', @INC[0,1]
  1475.   #
  1476.   # Let us suppose that the following script is stored in
  1477.   # $HOME/.vile/perl/number_lines.pl.
  1478.   #
  1479.   #     sub number_lines {
  1480.   #         my ($lnum, $width) = @_;
  1481.   #
  1482.   #         $lnum = 1 unless defined($lnum);
  1483.   #         $width = 4 unless defined($width);
  1484.   #
  1485.   #         $Vile::current_buffer->inplace_edit(1);
  1486.   #
  1487.   #         while (<$Vile::current_buffer>) {
  1488.   #             print $Vile::current_buffer
  1489.   #                   ' ' x ($width - length($lnum) - 1),
  1490.   #                   $lnum, ' ', $_;
  1491.   #             $lnum++;
  1492.   #         }
  1493.   #     }
  1494.   #
  1495.   #     1;
  1496.   #
  1497.   # Note the trailing "1;" at the end.  The reason for this is so
  1498.   # that I<true> is returned as the result of the script.  If things
  1499.   # are not done this way, the loading mechansim might flag an
  1500.   # error.  (All it needs to do is return a true value somehow.)
  1501.   #
  1502.   # Assuming the above code has been placed in the file
  1503.   # 'number_lines.pl', the following vile command may be used
  1504.   # to load it:
  1505.   #
  1506.   #         :perl require 'number_lines.pl'
  1507.   #
  1508.   # When writing a new script, I will often test it in the same
  1509.   # editor session that I've created the script in.  My script
  1510.   # may have a bug in it and I'll fix it.  In order to reload
  1511.   # the script, you can do the following:
  1512.   #
  1513.   #         :perl do 'number_lines.pl'
  1514.   #
  1515.   # Perl's builtin 'require' function wouldn't have worked to
  1516.   # reload the file because it keeps track of files that have
  1517.   # been loaded via this facility and refuses to load a file
  1518.   # twice.  The 'do' function on the other hand is a more general
  1519.   # facility for executing the contents of a file and doesn't
  1520.   # care how often it's called.
  1521.   #
  1522.   # Caveat: Sometimes it's better to start with a clean slate,
  1523.   # particularly if you've renamed your subroutines or if there
  1524.   # are global variables involved.  Just start a fresh copy of
  1525.   # vile and start over.
  1526.   #
  1527.   # Now to invoke our number_lines program, we do it as follows:
  1528.   #
  1529.   #         :perl number_lines(1)
  1530.   #
  1531.   # It is also possible to use vile's builtin macro language to
  1532.   # load perl modules and call them.  The hgrep.pl module comes
  1533.   # with the I<vile> distribution.  You may want to put this
  1534.   # macro in your F<.vilerc> file:
  1535.   #
  1536.   #     store-procedure hgrep
  1537.   #         perl "require 'hgrep.pl'"
  1538.   #         perl hgrep
  1539.   #         error-buffer $cbufname
  1540.   #     ~endm
  1541.   #
  1542.   # Notice that there are two perl commands in the above macro.
  1543.   # The first will make sure that the script hgrep.pl is loaded.
  1544.   # The second will actually call the main subroutine of the
  1545.   # script.
  1546.   #
  1547.   # See also the Vile::C<register> functions.
  1548.   #
  1549.  
  1550.  
  1551. MODULE = Vile    PACKAGE = Vile
  1552.  
  1553.   #
  1554.   # =head2 Package Vile
  1555.   #
  1556.   # The B<Vile> package contains subroutines and methods of a
  1557.   # general nature.  They range from providing an interface to
  1558.   # I<vile's> modes to providing facilities for obtaining user input.
  1559.   #
  1560.   # =head2 Package Vile Subroutines and Methods
  1561.   #
  1562.   # =over 4
  1563.   #
  1564.  
  1565. void
  1566. Warn(warning)
  1567.     char *warning
  1568.  
  1569.     CODE:
  1570.     write_message(GvSV(errgv));
  1571.     sv_catpv(GvSV(errgv),warning);
  1572.  
  1573.   #
  1574.   # =item beep
  1575.   #
  1576.   # Rings terminal bell (or equivalent).
  1577.   #
  1578.  
  1579. void
  1580. beep()
  1581.     CODE:
  1582.         kbd_alarm();
  1583.  
  1584.   #
  1585.   # =item buffers
  1586.   #
  1587.   # Returns a list of the editor's buffers.
  1588.   #
  1589.  
  1590. void
  1591. buffers(...)
  1592.  
  1593.     PREINIT:
  1594.     BUFFER *bp;
  1595.  
  1596.     PPCODE:
  1597.  
  1598.     if (! (items == 0
  1599.            || (items == 1 && strcmp(SvPV(ST(0), na), "Vile") == 0)) )
  1600.     {
  1601.         /* Must be called as either Vile::buffers() or Vile->buffers() */
  1602.         croak("buffers: called with too many arguments");
  1603.     }
  1604.  
  1605.     for_each_buffer(bp) {
  1606.         XPUSHs(sv_2mortal(newVBrv(newSV(0), api_bp2vbp(bp))));
  1607.     }
  1608.  
  1609.   #
  1610.   # =item command CMDLINE
  1611.   #
  1612.   # executes the given vile command line (as if it were typed on the :
  1613.   # line).
  1614.   #
  1615.   # This is not exactly safe in all contexts.  (It is easy to cause
  1616.   # seg faults.) If you need access to some portion of vile that would
  1617.   # lead you to want to use this subroutine, let me know and I will
  1618.   # work on suitable facilities.
  1619.   #
  1620.  
  1621. int
  1622. command(cline)
  1623.     char *cline
  1624.  
  1625.     PREINIT:
  1626.         int old_discmd;
  1627.  
  1628.     CODE:
  1629.     old_discmd = discmd;
  1630.     discmd = FALSE;
  1631.     RETVAL = docmd(cline, TRUE, FALSE, 1);
  1632.     discmd = old_discmd;
  1633.  
  1634.     OUTPUT:
  1635.     RETVAL
  1636.  
  1637.   #
  1638.   # =item keystroke
  1639.   #
  1640.   # =item keystroke WAITVAL
  1641.   #
  1642.   # Returns a single, fairly raw keystroke from the keyboard.
  1643.   #
  1644.   # The optional WAITVAL indicates if the editor should wait for the
  1645.   # next keystroke.  When WAITVAL is false, undef will
  1646.   # be returned if no input is ready.
  1647.   #
  1648.  
  1649. void
  1650. keystroke(...)
  1651.  
  1652.     PREINIT:
  1653.         int noget;
  1654.     PPCODE:
  1655.     if (items > 1)
  1656.         croak("Too many arguments to keystroke");
  1657.  
  1658.     curwp = curwp_visible ? curwp_visible : curwp;
  1659.     curbp = curwp->w_bufp;
  1660.  
  1661.     noget = FALSE;
  1662.  
  1663.     if (items == 1 && !SvTRUE(ST(0))) {
  1664.         if (!sysmapped_c_avail()) {
  1665.         XPUSHs(&sv_undef);
  1666.         noget = TRUE;
  1667.         }
  1668.     }
  1669.  
  1670.     if (!noget)
  1671.         XPUSHs(sv_2mortal(newSViv(sysmapped_c())));
  1672.  
  1673.     curwp_visible = curwp;
  1674.  
  1675.   #
  1676.   # =item mlreply PROMPT
  1677.   #
  1678.   # =item mlreply PROMPT, INITIALVALUE
  1679.   #
  1680.   # Prompts the user with the given prompt and (optional) supplied
  1681.   # initial value.  Certain characters that the user may input have
  1682.   # special meanings to mlreply and may have to be escaped by the
  1683.   # user to be input.  If this is unacceptable, use mlreply_no_opts
  1684.   # instead.
  1685.   #
  1686.   # Returns the user's response string.  If the user aborts
  1687.   # (via the use of the escape key) the query, an undef is
  1688.   # returned.
  1689.   #
  1690.  
  1691. void
  1692. mlreply(prompt, ...)
  1693.     char *prompt
  1694.  
  1695.     PREINIT:
  1696.     char buf[NLINE];
  1697.     int status;
  1698.  
  1699.     PPCODE:
  1700.     if (items == 2) {
  1701.         strncpy(buf, SvPV(ST(1),na), NLINE-1);
  1702.         buf[NLINE-1] = EOS;
  1703.     }
  1704.     else if (items > 2)
  1705.         croak("Too many arguments to mlreply");
  1706.     else
  1707.         buf[0] = EOS;
  1708.  
  1709.     status = mlreply(prompt, buf, sizeof(buf));
  1710. #if OPT_HISTORY
  1711.     if (status == TRUE)
  1712.         hst_glue('\r');
  1713. #endif
  1714.     XPUSHs((status == TRUE || status == FALSE)
  1715.              ? sv_2mortal(newSVpv(buf, 0))
  1716.          : &sv_undef);
  1717.  
  1718.  
  1719.   #
  1720.   # =item mlreply_dir PROMPT
  1721.   #
  1722.   # =item mlreply_dir PROMPT, INITIALVALUE
  1723.   #
  1724.   # Prompts the user for a directory name with the given prompt
  1725.   # and (optional) initial value.  Filename completion (via the
  1726.   # TAB key, if enabled) may be used to assist in entering
  1727.   # the directory name.
  1728.   #
  1729.   # Returns the user's response string.  If the user aborts
  1730.   # (via the use of the escape key) the query, an undef is
  1731.   # returned.
  1732.   #
  1733.  
  1734. void
  1735. mlreply_dir(prompt, ...)
  1736.     char *prompt
  1737.  
  1738.     PREINIT:
  1739.     char buf[NFILEN];
  1740.     static TBUFF *last;
  1741.     int status;
  1742.  
  1743.     PPCODE:
  1744.     if (items == 2) {
  1745.         tb_scopy(&last, SvPV(ST(1),na));
  1746.     }
  1747.     else if (items > 2) {
  1748.         croak("Too many arguments to mlreply_dir");
  1749.     }
  1750.  
  1751.     buf[0] = EOS;
  1752.     status = mlreply_dir(prompt, &last, buf);
  1753. #if OPT_HISTORY
  1754.     if (status == TRUE)
  1755.         hst_glue('\r');
  1756. #endif
  1757.     XPUSHs((status == TRUE || status == FALSE)
  1758.              ? sv_2mortal(newSVpv(buf, 0))
  1759.          : &sv_undef);
  1760.  
  1761.  
  1762.   #
  1763.   # =item mlreply_file PROMPT
  1764.   #
  1765.   # =item mlreply_file PROMPT, INITIALVALUE
  1766.   #
  1767.   # Prompts the user for a filename with the given prompt and
  1768.   # (optional) initial value.  Filename completion (via the
  1769.   # TAB key, if enabled) may be used to assist in entering
  1770.   # the filename.
  1771.   #
  1772.   # Returns the user's response string.  If the user aborts
  1773.   # (via the use of the escape key) the query, an undef is
  1774.   # returned.
  1775.   #
  1776.  
  1777. void
  1778. mlreply_file(prompt, ...)
  1779.     char *prompt
  1780.  
  1781.     PREINIT:
  1782.     char buf[NFILEN];
  1783.     static TBUFF *last;
  1784.     int status;
  1785.  
  1786.     PPCODE:
  1787.     if (items == 2) {
  1788.         tb_scopy(&last, SvPV(ST(1),na));
  1789.     }
  1790.     else if (items > 2) {
  1791.         croak("Too many arguments to mlreply_file");
  1792.     }
  1793.  
  1794.     buf[0] = EOS;
  1795.     status = mlreply_file(prompt, &last, FILEC_UNKNOWN, buf);
  1796. #if OPT_HISTORY
  1797.     if (status == TRUE)
  1798.         hst_glue('\r');
  1799. #endif
  1800.     XPUSHs((status == TRUE || status == FALSE)
  1801.              ? sv_2mortal(newSVpv(buf, 0))
  1802.          : &sv_undef);
  1803.  
  1804.  
  1805.   #
  1806.   # =item mlreply_no_opts PROMPT
  1807.   #
  1808.   # =item mlreply_no_opts PROMPT, INITIALVALUE
  1809.   #
  1810.   # Prompts the user with the given prompt and (optional) supplied
  1811.   # initial value.  All printable characters may be entered by the
  1812.   # without any special escapes.
  1813.   #
  1814.   # Returns the user's response string.  If the user aborts
  1815.   # (via the use of the escape key) the query, an undef is
  1816.   # returned.
  1817.   #
  1818.  
  1819. void
  1820. mlreply_no_opts(prompt, ...)
  1821.     char *prompt
  1822.  
  1823.     PREINIT:
  1824.     char buf[NLINE];
  1825.     int status;
  1826.  
  1827.     PPCODE:
  1828.     if (items == 2) {
  1829.         strncpy(buf, SvPV(ST(1),na), NLINE-1);
  1830.         buf[NLINE-1] = EOS;
  1831.     }
  1832.     else if (items > 2)
  1833.         croak("Too many arguments to mlreply_no_opts");
  1834.     else
  1835.         buf[0] = EOS;
  1836.  
  1837.     status = mlreply_no_opts(prompt, buf, sizeof(buf));
  1838. #if OPT_HISTORY
  1839.     if (status == TRUE)
  1840.         hst_glue('\r');
  1841. #endif
  1842.     XPUSHs((status == TRUE || status == FALSE)
  1843.              ? sv_2mortal(newSVpv(buf, 0))
  1844.          : &sv_undef);
  1845.  
  1846.  
  1847.  #
  1848.  # =item selection_buffer
  1849.  #
  1850.  # =item selection_buffer BUFOBJ
  1851.  #
  1852.  # =item Vile::Buffer::set_selection BUFOBJ
  1853.  #
  1854.  # Gets or sets the buffer associated with the current selection.
  1855.  #
  1856.  # When getting the selection, the buffer object that has the current
  1857.  # selection is returned and its region is set to be the same region
  1858.  # as is occupied by the selection.  If there is no current selection, undef
  1859.  # is returned.
  1860.  #
  1861.  # When setting the selection, a buffer object must be passed in.  The
  1862.  # editor's selection is set to the region associated with the buffer object.
  1863.  # If successful, the buffer object is returned; otherwise undef will be
  1864.  # returned.
  1865.  #
  1866.  # Examples:
  1867.  #
  1868.  #      $sel = Vile->selection_buffer->fetch;
  1869.  #                                      # Put the current selection in $sel
  1870.  #
  1871.  #      Vile->selection_buffer($Vile::current_buffer);
  1872.  #                                      # Set the selection to the region
  1873.  #                                      # contained in the current buffer
  1874.  #
  1875.  # Vile::Buffer::set_selection is an alias for Vile::selection_buffer, but
  1876.  # can only function as a setter.  It may be used like this:
  1877.  #
  1878.  #      Vile->current_buffer->set_region('w')->set_selection;
  1879.  #                                      # set the selection to be the word
  1880.  #                                      # starting at the current position
  1881.  #                                      # in the current buffer
  1882.  #
  1883.  #      Vile->current_buffer->motion('?\/\*' . "\n")
  1884.  #                          ->set_region('%')
  1885.  #                          ->set_selection();
  1886.  #                                      # set the selection to be the nearest
  1887.  #                                      # C-style comment above or at the
  1888.  #                                      # current position.
  1889.  #
  1890.  
  1891. void
  1892. selection_buffer(...)
  1893.  
  1894.     ALIAS:
  1895.     Vile::Buffer::set_selection = 1
  1896.  
  1897.     PREINIT:
  1898.     int argno;
  1899.  
  1900.     PPCODE:
  1901. #if OPT_SELECTIONS
  1902.     argno = 0;
  1903.  
  1904.     if (strcmp(SvPV(ST(argno), na), "Vile") == 0)
  1905.         argno++;
  1906.  
  1907.     if (items - argno == 0) { /* getter */
  1908.         BUFFER *bp;
  1909.         AREGION aregion;
  1910.  
  1911.         bp = get_selection_buffer_and_region(&aregion);
  1912.         if (bp != NULL) {
  1913.         VileBuf *vbp = api_bp2vbp(bp);
  1914.         vbp->region = aregion.ar_region;
  1915.         vbp->regionshape =  aregion.ar_shape;
  1916.         XPUSHs(sv_2mortal(newVBrv(newSV(0), vbp)));
  1917.         }
  1918.         else {
  1919.         XPUSHs(&sv_undef);
  1920.         }
  1921.     }
  1922.     else if (items - argno == 1) { /* setter */
  1923.         VileBuf *vbp;
  1924.         char *croakmess;
  1925.         /* Need a buffer object */
  1926.         vbp = getVB(ST(argno), &croakmess);
  1927.  
  1928.         if (vbp == 0)
  1929.         croak("Vile::%sselection: %s",
  1930.               ix == 1 ? "Buffer::" : "",
  1931.               croakmess);
  1932.         api_setup_fake_win(vbp, TRUE);
  1933.         DOT = vbp->region.r_orig;
  1934.         sel_begin();
  1935.         DOT = vbp->region.r_end;
  1936.         if (sel_extend(FALSE, FALSE) == TRUE) {
  1937.         XPUSHs(ST(argno));
  1938.         }
  1939.         else {
  1940.         XPUSHs(&sv_undef);
  1941.         }
  1942.     }
  1943.     else {
  1944.         croak("Vile::selection: Incorrect number of arguments");
  1945.     }
  1946. #else
  1947.     croak("%s requires vile to be compiled with OPT_SELECTIONS",
  1948.           GvNAME(CvGV(cv)));
  1949. #endif
  1950.  
  1951.  #
  1952.  # =item set PAIRLIST
  1953.  #
  1954.  # =item get LIST
  1955.  #
  1956.  # =item Vile::Buffer::set BUFOBJ PAIRLIST
  1957.  #
  1958.  # =item Vile::Buffer::get BUFOBJ LIST
  1959.  #
  1960.  # Provides access to Vile's various modes, buffer and otherwise.
  1961.  #
  1962.  # For the set methods, PAIRLIST should be a list of key => value
  1963.  # pairs, where key is a mode name and value is an appropriate value
  1964.  # for that mode.  When used in an array context, the resulting key =>
  1965.  # value pairs are returned.  (The value may be a different, but
  1966.  # equivalent string than originally specified.) When used in an array
  1967.  # context, either the package name or buffer object is returned
  1968.  # (depending on how it was invoked) in order that the result may be
  1969.  # used as the target of further method calls.
  1970.  #
  1971.  # When one of the get forms is used, a list of modes should be
  1972.  # supplied.  When used in an array context, a list of key => value
  1973.  # pairs is returned.  When used in a scalar context, only one mode
  1974.  # name may be supplied and the value associated with this mode is
  1975.  # returned.
  1976.  #
  1977.  # The methods in Vile::Buffer attempt to get the local modes
  1978.  # associated with the buffer (falling back to the global ones if no
  1979.  # specific local mode has been specified up to this point).
  1980.  #
  1981.  # Note:  Access to certain internal attributes such as the buffer
  1982.  # name and file name are not provided via this mechanism yet.  There
  1983.  # is no good reason for this other than that vile does not provide
  1984.  # access to these attributes via its set command.
  1985.  #
  1986.  
  1987. void
  1988. set(...)
  1989.  
  1990.     ALIAS:
  1991.     Vile::get = 1
  1992.     Vile::Buffer::set = 2
  1993.     Vile::Buffer::get = 3
  1994.  
  1995.     PREINIT:
  1996.     int argno;
  1997.     int isglobal;
  1998.     int issetter;
  1999.     char *mode;
  2000.     int status;
  2001.     VALARGS args;
  2002.     I32 gimme;
  2003.     char **modenames;
  2004.     int nmodenames = 0;
  2005.  
  2006.     PPCODE:
  2007. #if OPT_EVAL
  2008.     argno    = 0;
  2009.     isglobal = (ix == 0 || ix == 1);
  2010.     issetter = (ix == 0 || ix == 2);
  2011.     gimme    = GIMME_V;
  2012.     mode     = NULL;        /* just in case it never gets set */
  2013.  
  2014.     if (!isglobal /* one of the Vile::Buffer methods */) {
  2015.         char *croakmess;
  2016.         VileBuf *vbp;
  2017.  
  2018.         /* Need a buffer object */
  2019.         vbp = getVB(ST(argno), &croakmess);
  2020.         argno++;
  2021.  
  2022.         if (vbp == 0)
  2023.         croak("Vile::Buffer::set: %s", croakmess);
  2024.  
  2025.         isglobal = 0;
  2026.         api_setup_fake_win(vbp, TRUE);
  2027.     }
  2028.     else {
  2029.         /* We're in the Vile package.  See if we're called via
  2030.            Vile->set */
  2031.         if (strcmp(SvPV(ST(argno), na), "Vile") == 0)
  2032.         argno++;
  2033.     }
  2034.  
  2035.     nmodenames = 0;
  2036.     modenames = NULL;
  2037.     if (gimme == G_ARRAY) {
  2038.         int n = items - argno + 1;        /* +1 in case of odd set */
  2039.         if (!issetter)
  2040.         n *= 2;
  2041.         if (n > 0) {
  2042.         modenames = typeallocn(char *, n);
  2043.         if (modenames == NULL)
  2044.             croak("Can't allocate space");
  2045.         }
  2046.     }
  2047.  
  2048.     while (argno < items) {
  2049.         mode = SvPV(ST(argno), na);
  2050.         argno++;
  2051.  
  2052.         /* Look for a mode first */
  2053.         status = find_mode(mode, isglobal, &args);
  2054.  
  2055.  
  2056.         if (status == TRUE) {
  2057.         if (modenames)
  2058.             modenames[nmodenames++] = mode;
  2059.  
  2060.         if (issetter) {
  2061.             char *val;
  2062.             val = NULL;
  2063.             if (argno >= items) {
  2064.             if (args.names->type == VALTYPE_BOOL) {
  2065.                 val = "1";
  2066.             }
  2067.             else {
  2068.                 if (modenames) free(modenames);
  2069.                 croak("set: value required for %s", mode);
  2070.             }
  2071.             }
  2072.             else {
  2073.             val = SvPV(ST(argno), na);
  2074.             argno++;
  2075.             }
  2076.  
  2077.             if (set_mode_value(mode, TRUE, isglobal, &args, val) != TRUE) {
  2078.             if (modenames) free(modenames);
  2079.             croak("set: Invalid value %s for mode %s", val, mode);
  2080.             }
  2081.         }
  2082.         } else {
  2083.         char *val;
  2084.         val = gtenv(mode);
  2085.         if (val == errorm) {
  2086.             if (modenames)
  2087.             free(modenames);
  2088.             croak("set: Invalid mode or variable %s", mode);
  2089.         }
  2090.  
  2091.         if (modenames)
  2092.             modenames[nmodenames++] = mode;
  2093.  
  2094.         if (issetter) {
  2095.             if (argno >= items) {
  2096.             if (modenames) free(modenames);
  2097.             croak("set: value required for %s", mode);
  2098.             }
  2099.             else {
  2100.             val = SvPV(ST(argno), na);
  2101.             argno++;
  2102.             }
  2103.             status = stenv(mode, val);
  2104.  
  2105.             if (status != TRUE) {
  2106.             if (modenames) free(modenames);
  2107.             croak("set: Unable to set variable %s to value %s",
  2108.                   mode, val);
  2109.             }
  2110.         }
  2111.         }
  2112.     }
  2113.  
  2114.     if (modenames == NULL) {
  2115.         if (issetter) {
  2116.         if (isglobal)
  2117.             XPUSHs(sv_2mortal(newSVpv("Vile", 0)));
  2118.         else
  2119.             XPUSHs(ST(0));    /* Buffer object */
  2120.         }
  2121.         else {
  2122.         if (mode != NULL) {
  2123.             status = find_mode(mode, isglobal, &args);
  2124.             if (status == TRUE)
  2125.             XPUSHs(sv_2mortal(newSVpv(string_mode_val(&args), 0)));
  2126.             else
  2127.             XPUSHs(sv_2mortal(newSVpv(gtenv(mode), 0)));
  2128.         }
  2129.         }
  2130.     }
  2131.     else {
  2132.         int i;
  2133.         for (i = 0; i < nmodenames; i++) {
  2134.         mode = modenames[i];
  2135.         status = find_mode(mode, isglobal, &args);
  2136.         if (status == TRUE) {
  2137.             XPUSHs(sv_2mortal(newSVpv(mode, 0)));
  2138.             XPUSHs(sv_2mortal(newSVpv(string_mode_val(&args), 0)));
  2139.         }
  2140.         else {
  2141.             XPUSHs(sv_2mortal(newSVpv(mode, 0)));
  2142.             XPUSHs(sv_2mortal(newSVpv(gtenv(mode), 0)));
  2143.         }
  2144.         }
  2145.         free(modenames);
  2146.     }
  2147. #else
  2148.     croak("%s requires vile to be compiled with OPT_EVAL",
  2149.           GvNAME(CvGV(cv)));
  2150. #endif
  2151.  
  2152.   #
  2153.   # =item update
  2154.   #
  2155.   # Update the editor's display.  It is usually not necessary to
  2156.   # call this if you're returning to the editor in fairly short
  2157.   # order.  It will be necessary to call this, for example, if
  2158.   # you write an input loop in perl which writes things to some
  2159.   # on-screen buffers, but does not return to the editor immediately.
  2160.   #
  2161.  
  2162. void
  2163. update()
  2164.     PPCODE:
  2165.     api_update();
  2166.  
  2167.   #
  2168.   # =item working
  2169.   #
  2170.   # =item working VAL
  2171.   #
  2172.   # Returns value 1 if working message will be printed during
  2173.   # substantial pauses, 0 if disabled.
  2174.   #
  2175.   # When passed an argument, modifies value of the working message.
  2176.   #
  2177.  
  2178. int
  2179. working(...)
  2180.  
  2181.     CODE:
  2182.     if (items > 1)
  2183.         croak("Too many arguments to working");
  2184.     else if (items == 1) {
  2185. #if OPT_WORKING
  2186.         no_working = !SvIV(ST(0));
  2187. #endif
  2188.     }
  2189. #if OPT_WORKING
  2190.     RETVAL = !no_working;
  2191. #else
  2192.     RETVAL = 0;
  2193. #endif
  2194.     OUTPUT:
  2195.     RETVAL
  2196.  
  2197.   #
  2198.   # =item register NAME, [SUB, HELP, REQUIRE]
  2199.   #
  2200.   # Register a subroutine SUB as Vile function NAME.  Once registered,
  2201.   # the subroutine may then be invoked as a named command and bound to
  2202.   # keystrokes.
  2203.   #
  2204.   # SUB may be given either as a string to eval, or a reference to a
  2205.   # subroutine.  If omitted, SUB defaults to NAME.
  2206.   #
  2207.   # HELP provides a description of the subroutine for the [Binding
  2208.   # List] functions.
  2209.   #
  2210.   # An optional file to require may be given.
  2211.   #
  2212.   # Example:
  2213.   #
  2214.   #     Vile::register grep => 'hgrep', 'recursive grep', 'hgrep.pl';
  2215.   #
  2216.   # or
  2217.   #
  2218.   #     require 'hgrep.pl';
  2219.   #     Vile::register grep => \&hgrep, 'recursive grep';
  2220.   #
  2221.   # also
  2222.   #
  2223.   #     sub foo { print "foo" }
  2224.   #     Vile::register 'foo';
  2225.   #     Vile::register bar => 'print "bar"';
  2226.   #     Vile::register quux => sub { print "quux" };
  2227.   #
  2228.   # =item register_motion NAME, [SUB, HELP, REQUIRE]
  2229.   #
  2230.   # =item register_oper NAME, [SUB, HELP, REQUIRE]
  2231.   #
  2232.   # These synonyms for Vile::C<register> allow perl subroutines to
  2233.   # behave as motions and operators.  For example, these subroutines
  2234.   # behave like their builtin counterparts:
  2235.   #
  2236.   #     *cb = \$Vile::current_buffer;
  2237.   #     Vile::register_motion 'my-forward-line-at-bol' => sub {
  2238.   #         $cb->dot((scalar $cb->dot) + 1, 0);
  2239.   #     };
  2240.   #
  2241.   #     Vile::register_oper 'my-delete-til' => sub { $cb->delete };
  2242.   #
  2243.  
  2244. void
  2245. register(name, ...)
  2246.     char *name
  2247.  
  2248.     ALIAS:
  2249.     register_motion = MOTION
  2250.     register_oper = OPER
  2251.  
  2252.     PREINIT:
  2253.     CMDFUNC *cmd;
  2254.     AV *av;
  2255.     char *p;
  2256.  
  2257.     PPCODE:
  2258. #if OPT_NAMEBST
  2259.     if (items > 4)
  2260.         croak("Too many arguments to %s", GvNAME(CvGV(cv)));
  2261.  
  2262.     for (p = name; *p; p++)
  2263.         if (!isalnum(*p) && *p != '-' && *p != '_')
  2264.         croak("invalid subroutine name");
  2265.  
  2266.     if (!(cmd = typealloc(CMDFUNC)))
  2267.         croak("Can't allocate space");
  2268.  
  2269.     cmd->cu.c_perl = av = newAV();
  2270.     cmd->c_flags = REDO|UNDO|VIEWOK|CMD_PERL|ix;
  2271. #if OPT_ONLINEHELP
  2272.     cmd->c_help = strmalloc((items > 2 && SvTRUE(ST(2)))
  2273.                 ? SvPV(ST(2), na)
  2274.                 : "Perl subroutine");
  2275. #endif
  2276.  
  2277.     if (insert_namebst(name, cmd, FALSE) != TRUE)
  2278.     {
  2279. #if OPT_ONLINEHELP
  2280.         free((char *) cmd->c_help);
  2281. #endif
  2282.         free(cmd);
  2283.         av_undef(av);
  2284.     }
  2285.     else
  2286.     {
  2287.         /* push the name */
  2288.         av_push(av, newSVpv(name, 0));
  2289.  
  2290.         /* push the subroutine */
  2291.         if (items > 1 && SvTRUE(ST(1)))
  2292.         {
  2293.         SvREFCNT_inc(ST(1));
  2294.         av_push(av, ST(1));
  2295.  
  2296.         /* push the require */
  2297.         if (items > 3 && SvTRUE(ST(3)))
  2298.         {
  2299.             SvREFCNT_inc(ST(3));
  2300.             av_push(av, ST(3));
  2301.         }
  2302.         }
  2303.         else /* sub = name */
  2304.         av_push(av, newSVpv(name, 0));
  2305.     }
  2306. #else
  2307.     croak("%s requires vile to be compiled with OPT_NAMBST",
  2308.           GvNAME(CvGV(cv)));
  2309. #endif
  2310.  
  2311.   #
  2312.   # =item watchfd FD, WATCHTYPE, CALLBACK
  2313.   #
  2314.   # Adds a callback so that when the file descriptor FD is available
  2315.   # for a particular type of I/O activity (specified by WATCHTYPE),
  2316.   # the callback associated with CALLBACK is called.
  2317.   #
  2318.   # WATCHTYPE must be one of 'read', 'write', or 'except' and have
  2319.   # the obvious meanings.
  2320.   #
  2321.   # The callback should either be a string representing a vile
  2322.   # command to execute (good luck) or (more usefully) a Perl subroutine
  2323.   # reference.
  2324.   #
  2325.  
  2326. void
  2327. watchfd(fd, watchtypestr, ...)
  2328.     int fd
  2329.     char *watchtypestr
  2330.  
  2331.     PREINIT:
  2332.     char *cmd;
  2333.     int   watchtype;
  2334.  
  2335.  
  2336.     PPCODE:
  2337.     if (items != 3)
  2338.         croak("Wrong number of arguments to watchfd");
  2339.  
  2340.     if (strcmp(watchtypestr, "read") == 0)
  2341.         watchtype = WATCHREAD;
  2342.     else if (strcmp(watchtypestr, "write") == 0)
  2343.         watchtype = WATCHWRITE;
  2344.     else if (strcmp(watchtypestr, "except") == 0)
  2345.         watchtype = WATCHEXCEPT;
  2346.     else
  2347.         croak("Second argument to watchfd must be one of \"read\", \"write\", or \"except\".");
  2348.  
  2349.     if (SvROK(ST(2))
  2350.         && SvTYPE(SvRV(ST(2))) == SVt_PVCV)
  2351.     {
  2352.         /* We have a code ref (cool) */
  2353.         cmd = stringify_coderef(ST(2));
  2354.     }
  2355.     else {
  2356.         /* It's just a string (how boring) */
  2357.         cmd = strdup(SvPV(ST(2),na));
  2358.     }
  2359.     watchfd(fd, watchtype, cmd);
  2360.  
  2361.   #
  2362.   # =item unwatchfd FD
  2363.   #
  2364.   # Removes the callback associated with FD and frees up the
  2365.   # associated data structures.
  2366.   #
  2367.  
  2368. void
  2369. unwatchfd(fd)
  2370.     int fd
  2371.  
  2372.     PPCODE:
  2373.     unwatchfd(fd);
  2374.  
  2375.  
  2376. MODULE = Vile    PACKAGE = Vile::Buffer
  2377.  
  2378.   #
  2379.   # =back
  2380.   #
  2381.   # =head2 Package Vile::Buffer
  2382.   #
  2383.   # The Vile::Buffer package contains methods for creating new buffers
  2384.   # and for accessing already existing buffers in various ways.
  2385.   #
  2386.   # A Vile::Buffer object may be viewed as a filehandle.  Therefore,
  2387.   # the usual sorts of methods for reading from and writing to
  2388.   # filehandles will work as expected.
  2389.   #
  2390.   # Example:
  2391.   #
  2392.   # A word count program that you might invoke from your favorite
  2393.   # shell could be written as follows:
  2394.   #
  2395.   #     #!/usr/local/bin/perl -w
  2396.   #
  2397.   #     my $words;
  2398.   #     while (<>) {
  2399.   #         $words += split;
  2400.   #     }
  2401.   #     print "$words words\n";
  2402.   #
  2403.   # A programmer accustomed to the above, will find Vile's perl
  2404.   # interface to be a comfortable one.  Here is the above script
  2405.   # modified slightly to count the words in the current buffer:
  2406.   #
  2407.   #     sub wc {
  2408.   #         my $words;
  2409.   #         while (<$Vile::current_buffer>) {
  2410.   #             $words+=split;
  2411.   #         }
  2412.   #         print "$words words";
  2413.   #     }
  2414.   #
  2415.   # =head2 Package Vile::Buffer Methods
  2416.   #
  2417.   # =over 4
  2418.   #
  2419.  
  2420.  
  2421.  
  2422.   #
  2423.   # =item E<lt>BUFOBJE<gt>
  2424.   #
  2425.   # When used in a scalar context, returns the next line or portion of
  2426.   # thereof in the current region.
  2427.   #
  2428.   # When used in an array context, returns the rest of the lines (or
  2429.   # portions thereof) in the current region.
  2430.   #
  2431.   # The current region is either set with set_region or set by default
  2432.   # for you when perl is invoked from vile.  This region will either
  2433.   # be the region that the user specified or the whole buffer if not
  2434.   # user specified.  Unless you know for sure that the region is set
  2435.   # properly, it is probably best to set it explicitly.
  2436.   #
  2437.   # After a line is read, DOT is left at the next location in the
  2438.   # buffer at which to start reading.  Note, however, that the value
  2439.   # of DOT (which a convenient name for the current position in the
  2440.   # buffer) is not propogated back to any of the users windows unless
  2441.   # it has been explicitly set by calling dot (the method).
  2442.   #
  2443.   # When the I<inplace_edit> flag has been set via the C<inplace_edit>
  2444.   # method, text that is retrieved from the buffer is deleted
  2445.   # immediately after retrieval.
  2446.   #
  2447.   # Examples:
  2448.   #
  2449.   #     # Example 1: Put all lines of the current buffer into
  2450.   #     #            an array
  2451.   #
  2452.   #     $Vile::current_buffer->set_region(1,'$$');
  2453.   #                                     # Set the region to be the
  2454.   #                                     # entire buffer.
  2455.   #     my @lines = <$Vile::current_buffer>;
  2456.   #                                     # Fetch all lines and put them
  2457.   #                                     # in the @lines array.
  2458.   #     print $lines[$#lines/2] if @lines;
  2459.   #                                     # Print the middle line to
  2460.   #                                     # the status line
  2461.   #
  2462.   #
  2463.   #     # Example 2: Selectively delete lines from a buffer
  2464.   #
  2465.   #     my $curbuf = $Vile::current_buffer;
  2466.   #                                     # get an easier to type handle
  2467.   #                                     # for the current buffer
  2468.   #     $curbuf->inplace_edit(1);       # set the inplace_edit flag
  2469.   #                                     # so that lines will be deleted
  2470.   #                                     # as they are read
  2471.   #
  2472.   #     while (<$curbuf>) {             # fetch line into $_
  2473.   #         unless (/MUST\s+DELETE/) {  # see if we should keep the line
  2474.   #             print $curbuf $_;       # put it back if we should keep it
  2475.   #         }
  2476.   #     }
  2477.   #
  2478.  
  2479. void
  2480. READLINE(vbp)
  2481.     VileBuf * vbp
  2482.  
  2483.     PPCODE:
  2484.     if (vbp2bp(vbp) == bminip) {
  2485.         int status;
  2486.         char buf[NLINE];
  2487.         char prompt[NLINE];
  2488.         buf[0] = EOS;
  2489.         strcpy(prompt, "(perl input) ");
  2490.         if (use_ml_as_prompt && !is_empty_buf(bminip)) {
  2491.         LINE *lp = lback(buf_head(bminip));
  2492.         int len = llength(lp);
  2493.         if (len > NLINE-1)
  2494.             len = NLINE-1;
  2495.         strncpy(prompt, lp->l_text, len);
  2496.         prompt[len] = 0;
  2497.         }
  2498.         status = mlreply_no_opts(prompt, buf, sizeof(buf));
  2499. #if OPT_HISTORY
  2500.         if (status == TRUE)
  2501.         hst_glue('\r');
  2502. #endif
  2503.         EXTEND(sp,1);
  2504.         if (status != TRUE && status != FALSE) {
  2505.         PUSHs(&sv_undef);
  2506.         }
  2507.         else {
  2508.         use_ml_as_prompt = 0;
  2509.         PUSHs(sv_2mortal(newSVpv(buf,0)));
  2510.         }
  2511.     }
  2512.     else {
  2513.         I32 gimme = GIMME_V;
  2514.         struct MARK old_DOT;
  2515.         int (*f)(SV**,VileBuf*,char*,int);
  2516.         char *rsstr;
  2517.         int rslen;
  2518. #ifdef HAVE_BROKEN_PERL_RS
  2519.         /* The input record separator, or $/ Normally, this is
  2520.          * available via the rs macro, but apparently perl5.00402
  2521.          * on win32 systems don't export the necessary symbol from
  2522.          * the DLL.  So we have our own...  */
  2523.         SV *svrs = perl_get_sv("main::/", FALSE);
  2524. #else
  2525. #           define svrs PL_rs
  2526. #endif
  2527.  
  2528.         if (RsSNARF(svrs)) {
  2529.         f = svgetregion;
  2530.         rsstr = 0;
  2531.         rslen = 0;
  2532.         }
  2533.         else {
  2534.         rsstr = SvPV(svrs, rslen);
  2535.         if (rslen == 1 && *rsstr == '\n')
  2536.             f = svgetline;
  2537.         else
  2538.             f = svgettors;
  2539.         }
  2540.  
  2541.         /* Set up the fake window */
  2542.         api_setup_fake_win(vbp, TRUE);
  2543.         if (!vbp->dot_inited) {
  2544.         DOT = vbp->region.r_orig;    /* set DOT to beginning of region */
  2545.         vbp->dot_inited = 1;
  2546.         }
  2547.  
  2548.         old_DOT = DOT;
  2549.  
  2550.         if (gimme == G_VOID || gimme == G_SCALAR) {
  2551.         SV *sv;
  2552.         if (f(&sv, vbp, rsstr, rslen))
  2553.             IoLINES(GvIO((GV*)vbp->perl_handle))++; /* increment $. */
  2554.  
  2555.         if (gimme == G_SCALAR) {
  2556.             XPUSHs(sv_2mortal(sv));
  2557.         }
  2558.         }
  2559.         else { /* wants an array */
  2560.         SV *sv;
  2561.         int lines = 0;
  2562.  
  2563.         while (f(&sv, vbp, rsstr, rslen)) {
  2564.             XPUSHs(sv_2mortal(sv));
  2565.             lines++;
  2566.         }
  2567.         IoLINES(GvIO((GV*)vbp->perl_handle)) = lines; /* set $. */
  2568.         }
  2569.         if (vbp->inplace_edit) {
  2570.         DOT = old_DOT;
  2571.         }
  2572.     }
  2573.  
  2574.   #
  2575.   # =item attribute BUFOBJ LIST
  2576.   #
  2577.   # Attach an attributed region to the region associated with BUFOBJ
  2578.   # with the attributes found in LIST.
  2579.   #
  2580.   # These attributes may be any of the following:
  2581.   #
  2582.   #     'color' => NUM          (where NUM is the color number
  2583.   #                              from 0 to 15)
  2584.   #     'underline'
  2585.   #     'bold'
  2586.   #     'reverse'
  2587.   #     'italic'
  2588.   #     'hyper' => HYPERCMD     (where HYPERCMD is a string
  2589.   #                             representing a vile command to
  2590.   #                             execute.  It may also be a
  2591.   #                             (perl) subroutine reference.
  2592.   #     'normal'
  2593.   #
  2594.   # Normal is a special case.  It will override any other arguments
  2595.   # passed in and remove all attributes associated with the region.
  2596.   #
  2597.  
  2598. void
  2599. attribute(vbp, ...)
  2600.     VileBuf *vbp
  2601.  
  2602.     PPCODE:
  2603. #if OPT_SELECTIONS
  2604.     if (items <= 1) {
  2605.         /* Hmm.  What does this mean?  Should we attempt to fetch
  2606.            the attributes for this region?  Should we turn off all
  2607.            the attributes?
  2608.  
  2609.            Personally, I think it'd be cool to return a list of
  2610.            all the regions and their attributes.  But I'll save
  2611.            that exercise for another night...
  2612.         */
  2613.     }
  2614.     else {
  2615.         int i;
  2616.         char *atname;
  2617.         VIDEO_ATTR vattr = 0;
  2618.         int normal = 0;
  2619.         char *hypercmd = 0;
  2620.         int status;
  2621.  
  2622.         for (i = 1; i < items; i++) {
  2623.         atname = SvPV(ST(i), na);
  2624.         if (       strcmp(atname, "underline") == 0) {
  2625.             vattr |= VAUL;
  2626.         } else if (strcmp(atname, "bold"     ) == 0) {
  2627.             vattr |= VABOLD;
  2628.         } else if (strcmp(atname, "reverse"  ) == 0) {
  2629.             vattr |= VAREV;
  2630.         } else if (strcmp(atname, "italic"   ) == 0) {
  2631.             vattr |= VAITAL;
  2632.         } else if (strcmp(atname, "normal"   ) == 0) {
  2633.             normal = 1;
  2634.         } else if (strcmp(atname, "color"    ) == 0) {
  2635.             i++;
  2636.             if (i < items) {
  2637.             vattr |= VCOLORATTR(SvIV(ST(i)) & 0xf);
  2638.             }
  2639.             else {
  2640.             croak("Color attribute not supplied");
  2641.             }
  2642.         } else if (strcmp(atname, "hyper"    ) == 0
  2643.                 || strcmp(atname, "hypertext") == 0) {
  2644.             i++;
  2645.             if (i < items) {
  2646.             if (SvROK(ST(i))
  2647.                 && SvTYPE(SvRV(ST(i))) == SVt_PVCV)
  2648.             {
  2649.                 /* We have a code ref */
  2650.                 hypercmd = stringify_coderef(ST(i));
  2651.             }
  2652.             else {
  2653.                 /* It's just a string */
  2654.                 hypercmd = strdup(SvPV(ST(i),na));
  2655.             }
  2656.             }
  2657.             else {
  2658.             croak("Hypertext command not supplied");
  2659.             }
  2660.         } else {
  2661.             croak("Invalid attribute");
  2662.         }
  2663.         }
  2664.  
  2665.         if (normal) {
  2666.         vattr = 0;
  2667.         hypercmd = 0;
  2668.         }
  2669.  
  2670.         status = attributeregion_in_region(
  2671.                 &vbp->region, vbp->regionshape, vattr, hypercmd);
  2672.  
  2673.         if (status == TRUE)        /* not the same as "if (status)" */
  2674.         XPUSHs(ST(0));        /* return buffer object */
  2675.         else
  2676.         XPUSHs(&sv_undef);    /* else return undef */
  2677.     }
  2678. #else
  2679.     croak("%s requires vile to be compiled with OPT_SELECTIONS",
  2680.           GvNAME(CvGV(cv)));
  2681. #endif
  2682.  
  2683.   #
  2684.   # =item attribute_cntl_a_sequences BUFOBJ
  2685.   #
  2686.   # Causes the editor to attach attributes to the <Ctrl>A
  2687.   # sequences found in the buffer for the current region (which
  2688.   # may be set via set_region).
  2689.   #
  2690.   # Returns the buffer object.
  2691.   #
  2692.  
  2693. VileBuf *
  2694. attribute_cntl_a_sequences(vbp)
  2695.     VileBuf *vbp
  2696.  
  2697.     CODE:
  2698. #if OPT_SELECTIONS
  2699.     api_setup_fake_win(vbp, TRUE);
  2700.     attribute_cntl_a_seqs_in_region(&vbp->region, vbp->regionshape);
  2701.     RETVAL = vbp;
  2702. #else
  2703.     croak("%s requires vile to be compiled with OPT_SELECTIONS",
  2704.           GvNAME(CvGV(cv)));
  2705. #endif
  2706.  
  2707.     OUTPUT:
  2708.     RETVAL
  2709.  
  2710.   #
  2711.   # =item buffername BUFOBJ
  2712.   #
  2713.   # Returns the buffer name associated with BUFOBJ.
  2714.   #
  2715.   # =item buffername BUFOBJ BUFNAME
  2716.   #
  2717.   # Sets the buffer name associated with BUFOBJ to the string
  2718.   # given by BUFNAME.  This string must be unique.  If the name
  2719.   # given is already being used by another buffer, or if it's
  2720.   # malformed in some way, undef will be returned.  Otherwise
  2721.   # the name of the buffer will be returned.
  2722.   #
  2723.   # Note: The name of the buffer returned may be different than
  2724.   # that passed in due some adjustments that may be done on the
  2725.   # buffer name.  (It will be trimmed of spaces and a length limit
  2726.   # is imposed.)
  2727.   #
  2728.   # =item filename BUFOBJ
  2729.   #
  2730.   # Returns the file name associated with BUFOBJ.
  2731.   #
  2732.   # =item filename BUFOBJ FILENAME
  2733.   #
  2734.   # Sets the name of the file associated with BUFOBJ to the string
  2735.   # given by FILENAME.
  2736.   #
  2737.  
  2738. void
  2739. buffername(vbp,...)
  2740.     VileBuf *vbp
  2741.  
  2742.     ALIAS:
  2743.     filename = 1
  2744.  
  2745.     PREINIT:
  2746.     int status;
  2747.  
  2748.     PPCODE:
  2749.  
  2750.     status = TRUE;
  2751.     api_setup_fake_win(vbp, TRUE);
  2752.  
  2753.     if (items > 2)
  2754.         croak("Too many arguments to %s",
  2755.               ix == 0 ? "buffername" : "filename");
  2756.     else if (items == 2) {
  2757.         if (ix == 0)
  2758.         status = renamebuffer(curbp, SvPV(ST(1),na));
  2759.         else
  2760.         ch_fname(curbp, SvPV(ST(1),na));
  2761.     }
  2762.  
  2763.     if (status == TRUE) {
  2764.         XPUSHs(sv_2mortal(newSVpv(ix == 0 ?
  2765.                                   curbp->b_bname : curbp->b_fname, 0)));
  2766.     }
  2767.     else {
  2768.         XPUSHs(&sv_undef);        /* return undef */
  2769.     }
  2770.  
  2771.   #
  2772.   # =item command BUFOBJ CMDLINE
  2773.   #
  2774.   # executes the given vile command line (as if it were typed
  2775.   # on the : line) with BUFOBJ as the current buffer.
  2776.   #
  2777.   # Returns BUFOBJ if successful, otherwise returns undef.
  2778.   #
  2779.  
  2780. void
  2781. command(vbp,cline)
  2782.     VileBuf *vbp
  2783.     char *cline
  2784.  
  2785.     PREINIT:
  2786.     int status;
  2787.     int old_discmd;
  2788.     PPCODE:
  2789.     old_discmd = discmd;
  2790.     discmd = FALSE;
  2791.     api_setup_fake_win(vbp, TRUE);
  2792.     status = docmd(cline, TRUE, FALSE, 1);
  2793.     discmd = old_discmd;
  2794.     if (status) {
  2795.         XPUSHs(ST(0));        /* return buffer object */
  2796.     }
  2797.     else {
  2798.         XPUSHs(&sv_undef);        /* return undef */
  2799.     }
  2800.  
  2801.   #
  2802.   # =item current_buffer
  2803.   #
  2804.   # =item current_buffer BUFOBJ
  2805.   #
  2806.   # =item current_buffer PKGNAME
  2807.   #
  2808.   # =item current_buffer BUFOBJ   NEWBUFOBJ
  2809.   #
  2810.   # =item current_buffer PKGNAME  NEWBUFOBJ
  2811.   #
  2812.   # Returns the current buffer.  When first entering perl from a vile
  2813.   # session, the current buffer is the one that the user is actively
  2814.   # editing.  Several buffers may be on the screen at once, but only one
  2815.   # of them is current.  The current one will be the one in which the
  2816.   # cursor appears.
  2817.   #
  2818.   # This method may also be used to set the current buffer.  When used in
  2819.   # the form
  2820.   #
  2821.   #     $oldbuf->current_buffer($newbuf)
  2822.   #
  2823.   # then $newbuf will replace $oldbuf in one of the visible windows.
  2824.   # (This only makes sense when $oldbuf was visible in some window on the
  2825.   # screen.  If it wasn't visible, it'll just replace whatever buffer was
  2826.   # last both current and visible.)
  2827.   #
  2828.   # When used as a setter, the current buffer is still returned.  In this
  2829.   # case it will be the new buffer object which becomes the current
  2830.   # buffer.
  2831.   #
  2832.   # Note also that the current_buffer method is in both the Vile package
  2833.   # and the Vile::Buffer package.  I couldn't decide which package it should
  2834.   # be in so I put it into both.  It seemed like a real hassle to have to
  2835.   # say
  2836.   #
  2837.   #     my $curbuf = Vile::Buffer->current_buffer
  2838.   #
  2839.   # So instead, you can just say
  2840.   #
  2841.   #     my $curbuf = Vile->current_buffer;
  2842.   #
  2843.   # current_buffer is also a variable, so you can also do it this way:
  2844.   #
  2845.   #     my $curbuf = $Vile::current_buffer;
  2846.   #
  2847.   # If you want $main::curbuf (or some other variable) to be an alias to
  2848.   # the current buffer, you can do it like this:
  2849.   #
  2850.   #     *main::curbuf = \$Vile::current_buffer;
  2851.   #
  2852.   # Put this in some bit of initialization code and then you'll never have
  2853.   # to call the current_buffer method at all.
  2854.   #
  2855.   # One more point, since $Vile::current_buffer is magical, the alias
  2856.   # above will be magical too, so you'll be able to do
  2857.   #
  2858.   #     $curbuf = $newbuf;
  2859.   #
  2860.   # in order to set the buffer.  (Yeah, this looks obvious, but realize
  2861.   # that doing the assignment actually causes some vile specific code to
  2862.   # run which will cause $newbuf to become the new current buffer upon
  2863.   # return.)
  2864.   #
  2865.  
  2866. VileBuf *
  2867. current_buffer(...)
  2868.  
  2869.     ALIAS:
  2870.     Vile::current_buffer = 1
  2871.  
  2872.     PREINIT:
  2873.     VileBuf *callbuf;
  2874.     VileBuf *newbuf;
  2875.  
  2876.     PPCODE:
  2877.     if (items > 2)
  2878.         croak("Too many arguments to current_buffer");
  2879.     else if (items == 2) {
  2880.         if (sv_isa(ST(0), "Vile::Buffer")) {
  2881.         callbuf = (VileBuf *)SvIV((SV*)GvSV((GV*)SvRV(ST(0))));
  2882.         if (callbuf == 0) {
  2883.             croak("buffer no longer exists");
  2884.         }
  2885.         }
  2886.         else
  2887.         callbuf = 0;
  2888.  
  2889.         if (sv_isa(ST(1), "Vile::Buffer")) {
  2890.         newbuf = (VileBuf *)SvIV((SV*)GvSV((GV*)SvRV(ST(1))));
  2891.         if (newbuf == 0) {
  2892.             croak("switched to buffer no longer exists");
  2893.         }
  2894.         }
  2895.         else {
  2896.         croak("switched to buffer of wrong type");
  2897.         }
  2898.  
  2899.         if (api_swscreen(callbuf, newbuf))
  2900.         sv_setsv(svcurbuf, ST(1));
  2901.     }
  2902.  
  2903.     XPUSHs(svcurbuf);
  2904.  
  2905.   #
  2906.   # =item delete BUFOBJ
  2907.   #
  2908.   # Deletes the currently set region.
  2909.   #
  2910.   # Returns the buffer object if all went well, undef otherwise.
  2911.   #
  2912.  
  2913. VileBuf *
  2914. delete(vbp)
  2915.     VileBuf *vbp
  2916.  
  2917.     CODE:
  2918.     if (api_delregion(vbp))
  2919.         RETVAL = vbp;
  2920.     else
  2921.         RETVAL = 0;        /* which gets turned into undef */
  2922.     OUTPUT:
  2923.     RETVAL
  2924.  
  2925.   #
  2926.   # =item dot BUFOBJ
  2927.   #
  2928.   # =item dot BUFOBJ LINENUM
  2929.   #
  2930.   # =item dot BUFOBJ LINENUM, OFFSET
  2931.   #
  2932.   # Returns the current value of dot (which represents the the current
  2933.   # position in the buffer).  When used in a scalar context returns,
  2934.   # the line number of dot.  When used in an array context, returns
  2935.   # the line number and position within the line.
  2936.   #
  2937.   # When supplied with one argument, the line number, dot is set to
  2938.   # the beginning of that line.  When supplied with two arguments,
  2939.   # both the line number and offset components are set.
  2940.   #
  2941.   # Either the line number or offset (or both) may be the special
  2942.   # string '$' which represents the last line in the buffer and the
  2943.   # last character on a line.
  2944.   #
  2945.   # Often times, however, the special string '$$' will be more useful.
  2946.   # It truly represents the farthest that it possible to go in both
  2947.   # the vertical and horizontal directions.  As a line number, this
  2948.   # represents the line beyond the last line of the buffer.
  2949.   # Characters inserted at this point will form a new line.  As an
  2950.   # offset, '$$' refers to the newline character at the end of a line.
  2951.   # Characters inserted at this point will be inserted before the
  2952.   # newline character.
  2953.   #
  2954.   #
  2955.   # Examples:
  2956.   #
  2957.   #     my $cb = $Vile::current_buffer; # Provide a convenient handle
  2958.   #                                     # for the current buffer.
  2959.   #
  2960.   #     $linenum = $cb->dot;            # Fetch the line number at which dot
  2961.   #                                     # is located.
  2962.   #
  2963.   #     $cb->dot($cb->dot+1);           # Advance dot by one line
  2964.   #     $cb->dot($cb->dot('$') - 1);
  2965.   #                                     # Set dot to the penultimate line of
  2966.   #                                     # the buffer.
  2967.   #
  2968.   #     $cb->dot(25, 6);                # Set dot to line 25, character 6
  2969.   #
  2970.   #     ($ln,$off) = $cb->dot;          # Fetch the current position
  2971.   #     $cb->dot($ln+1,$off-1);         # and advance one line, but
  2972.   #                                     # back one character.
  2973.   #
  2974.   #     $cb->inplace_edit(1);
  2975.   #     $cb->set_region(scalar($cb->dot), $cb->dot+5);
  2976.   #     @lines = <$cb>;
  2977.   #     $cb->dot($cb->dot - 1);
  2978.   #     print $cb @lines;
  2979.   #                                     # The above block takes (at
  2980.   #                                     # most) six lines starting at
  2981.   #                                     # the line DOT is on and moves
  2982.   #                                     # them before the previous
  2983.   #                                     # line.
  2984.   #
  2985.   # Note: current_position is an alias for dot.
  2986.   #
  2987.  
  2988. void
  2989. dot(vbp, ...)
  2990.     VileBuf *vbp
  2991.  
  2992.     ALIAS:
  2993.     current_position = 1
  2994.  
  2995.     PREINIT:
  2996.     I32 gimme;
  2997.  
  2998.     PPCODE:
  2999.     api_setup_fake_win(vbp, TRUE);
  3000.     if ( items > 3) {
  3001.         croak("Invalid number of arguments");
  3002.     }
  3003.     else if (items > 1) {
  3004.         /* Expect a line number or '$' */
  3005.  
  3006.         api_gotoline(vbp, sv2linenum(ST(1)));
  3007.  
  3008.         if (items == 3)
  3009.         DOT.o = sv2offset(ST(2));
  3010.  
  3011.         /* Don't allow api_dotgline to change dot if dot is explicitly
  3012.            set.  OTOH, simply querying dot doesn't count. */
  3013.         vbp->dot_inited = TRUE;
  3014.         /* Indicate that DOT has been explicitly changed which means
  3015.            that changes to DOT will be propogated upon return to vile */
  3016.         vbp->dot_changed = TRUE;
  3017.     }
  3018.     gimme = GIMME_V;
  3019.     if (gimme == G_SCALAR) {
  3020.         XPUSHs(sv_2mortal(newSViv(line_no(curbp, DOT.l))));
  3021.     }
  3022.     else if (gimme == G_ARRAY) {
  3023.         XPUSHs(sv_2mortal(newSViv(line_no(curbp, DOT.l))));
  3024.         XPUSHs(sv_2mortal(newSViv(DOT.o)));
  3025.     }
  3026.  
  3027.   #
  3028.   # =item fetch BUFOBJ
  3029.   #
  3030.   # Returns the current region or remainder thereof.  The same effect
  3031.   # could be achieved by setting $/ to undef and then evaluating the
  3032.   # buffer object between angle brackets.
  3033.   #
  3034.   # Example:
  3035.   #
  3036.   #     $word = $Vile::current_buffer->set_region('w')->fetch;
  3037.   #                             # Fetch the next word and put it in $word
  3038.   #
  3039.  
  3040. void
  3041. fetch(vbp)
  3042.     VileBuf * vbp
  3043.  
  3044.     PREINIT:
  3045.     SV *sv;
  3046.     struct MARK old_DOT;
  3047.  
  3048.     PPCODE:
  3049.     /* Set up the fake window */
  3050.     api_setup_fake_win(vbp, TRUE);
  3051.     if (!vbp->dot_inited) {
  3052.         DOT = vbp->region.r_orig;    /* set DOT to beginning of region */
  3053.         vbp->dot_inited = 1;
  3054.     }
  3055.  
  3056.     old_DOT = DOT;
  3057.  
  3058.     svgetregion(&sv, vbp, 0, 0);
  3059.  
  3060.     XPUSHs(sv_2mortal(sv));
  3061.  
  3062.     if (vbp->inplace_edit)
  3063.         DOT = old_DOT;
  3064.  
  3065.  
  3066.   #
  3067.   # =item inplace_edit BUFOBJ
  3068.   #
  3069.   # =item inplace_edit BUFOBJ VALUE
  3070.   #
  3071.   # Sets the value of the "inplace edit" flag (either true of false).
  3072.   # Returns the old value.  When used without an argument, merely
  3073.   # returns current value without modifying the current value.
  3074.   #
  3075.   # This flag determines whether a line is deleted after being read.
  3076.   # E.g,
  3077.   #
  3078.   #     my $curbuf = $Vile::current_buffer;
  3079.   #     $curbuf->inplace_edit(1);
  3080.   #     while (<$curbuf>) {
  3081.   #         s/foo/bar/g;
  3082.   #         print;
  3083.   #     }
  3084.   #
  3085.   # The <$curbuf> operation will cause one line to be read and
  3086.   # deleted.  DOT will be left at the beginning of the next line.  The
  3087.   # print statment will cause $_ to get inserted prior the the next
  3088.   # line.
  3089.   #
  3090.   # Setting this flag to true is very similar to setting the
  3091.   # $INPLACE_EDIT flag (or $^I) for normal filehandles or using the B<-i>
  3092.   # switch from the command line.
  3093.   #
  3094.   # Setting it to false (which is its default value) will cause the
  3095.   # lines that are read to be left alone.
  3096.   #
  3097.  
  3098. int
  3099. inplace_edit(vbp, ...)
  3100.     VileBuf *vbp
  3101.  
  3102.     CODE:
  3103.     RETVAL = vbp->inplace_edit;
  3104.     if (items > 1)
  3105.         vbp->inplace_edit = SvIV(ST(1));
  3106.  
  3107.     OUTPUT:
  3108.     RETVAL
  3109.  
  3110.   #
  3111.   # =item motion BUFOBJ MOTIONSTR
  3112.   #
  3113.   # Moves dot (the current position) by the given MOTIONSTR in
  3114.   # BUFOBJ.
  3115.   #
  3116.   # When used in an array context, returns a 4-tuple containing
  3117.   # the beginning and ending positions.  This 4-tuple is suitable
  3118.   # for passing to C<set_region>.
  3119.   #
  3120.   # When used in a scalar context, returns the buffer object that
  3121.   # it was called with.
  3122.   #
  3123.   # In either an array or scalar context, if the motion string was
  3124.   # bad, and undef is returned.  Motions that don't work are okay,
  3125.   # such as 'h' when you're already at the left edge of a line.  But
  3126.   # attempted "motions" like 'inewstring' will result in an error.
  3127.   #
  3128.   # Example:
  3129.   #
  3130.   #     # The following code deletes the previous 2 words and then
  3131.   #     # positions the cursor at the next occurrence of the word
  3132.   #     # "foo".
  3133.   #
  3134.   #     my $cb = $Vile::current_buffer;
  3135.   #     $cb->set_region($cb->motion("2b"))->delete;
  3136.   #                     # delete the previous two words
  3137.   #
  3138.   #     $cb->set_region("2b")->delete;
  3139.   #                     # another way to delete the previous
  3140.   #                     # two words
  3141.   #
  3142.   #     $cb->motion("/foo/");
  3143.   #                     # position DOT at the beginning of
  3144.   #                     # "foo".
  3145.   #
  3146.   #     $cb->dot($cb->dot);
  3147.   #                     # Make sure DOT gets propogated back.
  3148.   #                     # (It won't get propogated unless
  3149.   #                     # explicitly set.)
  3150.   #
  3151.  
  3152. void
  3153. motion(vbp,mstr)
  3154.     VileBuf *vbp
  3155.     char *mstr
  3156.  
  3157.     PREINIT:
  3158.     I32 gimme;
  3159.     struct MARK old_DOT;
  3160.     int status;
  3161.  
  3162.     PPCODE:
  3163.     old_DOT = DOT;
  3164.         status = api_motion(vbp, mstr);
  3165.  
  3166.     gimme = GIMME_V;
  3167.     if (!status) {
  3168.         XPUSHs(&sv_undef);        /* return undef */
  3169.     }
  3170.     else if (gimme == G_SCALAR) {
  3171.         XPUSHs(ST(0));        /* return the buffer object */
  3172.     }
  3173.     else if (gimme == G_ARRAY) {
  3174.         I32 sl, el, so, eo;
  3175.         sl = line_no(curbp, old_DOT.l);
  3176.         so = old_DOT.o;
  3177.         el = line_no(curbp, DOT.l);
  3178.         eo = DOT.o;
  3179.         if (sl > el) {
  3180.         I32 tl = sl;
  3181.         sl = el;
  3182.         el = tl;
  3183.         }
  3184.         if (sl == el && so > eo) {
  3185.         I32 to = so;
  3186.         so = eo;
  3187.         eo = to;
  3188.         }
  3189.         XPUSHs(sv_2mortal(newSViv(sl)));
  3190.         XPUSHs(sv_2mortal(newSViv(so)));
  3191.         XPUSHs(sv_2mortal(newSViv(el)));
  3192.         XPUSHs(sv_2mortal(newSViv(eo)));
  3193.     }
  3194.  
  3195.   #
  3196.   # =item new BUFOBJ
  3197.   #
  3198.   # =item new PKGNAME
  3199.   #
  3200.   # =item new BUFOBJ  FILENAME
  3201.   #
  3202.   # =item new PKGNAME FILENAME
  3203.   #
  3204.   # =item edit BUFOBJ
  3205.   #
  3206.   # =item edit PKGNAME
  3207.   #
  3208.   # =item edit BUFOBJ  FILENAME
  3209.   #
  3210.   # =item edit PKGNAME FILENAME
  3211.   #
  3212.   # These methods create a new buffer and return it.
  3213.   #
  3214.   # When no filename is supplied, an anonymous buffer is created.
  3215.   # These buffer's will be named [unnamed-1], [unnamed-2], etc.  and
  3216.   # will not have a file name associated with them.
  3217.   #
  3218.   # When a name is supplied as an argument to new or edit, a check is
  3219.   # made to see if the name is the same as an already existing buffer.
  3220.   # If so, that buffer is returned.  Otherwise, the name is taken to
  3221.   # be a file name.  If the file exists, it is opened and read into
  3222.   # the newly created buffer.  If the file does not exist, a new
  3223.   # buffer will be created with the associated file name.  The name of
  3224.   # the buffer will be based on the file name.  The file will be
  3225.   # created when the buffer is first written out to disk.
  3226.   #
  3227.   # new and edit are synonyms.  In each case, PKGNAME is Vile::Buffer.
  3228.   # There is no difference between Vile::Buffer->new($fname) and
  3229.   # $buf->new($fname).  These two different forms are merely provided
  3230.   # for convenience.
  3231.   #
  3232.   # Example:
  3233.   #
  3234.   #     $Vile::current_buffer = new Vile::Buffer 'makefile';
  3235.   #                                     # open makefile and make it visible
  3236.   #                                     # on the screen.
  3237.   #
  3238.   #     $abuf = new Vile::Buffer;       # Create an anonymous buffer
  3239.   #     print $abuf "Hello";            # put something in it
  3240.   #     Vile->current_buffer($abuf);    # make the anonymous buffer current
  3241.   #                                     #   (viewable).
  3242.   #
  3243.   #     Vile->current_buffer($abuf->edit('makefile'));
  3244.   #                                     # Now makefile is the current
  3245.   #                                     #   buffer
  3246.   #     $abuf->current_buffer(Vile::Buffer->new('makefile'));
  3247.   #                                     # Same thing
  3248.   #
  3249.  
  3250. VileBuf *
  3251. new(...)
  3252.  
  3253.     ALIAS:
  3254.     edit = 1
  3255.  
  3256.     PREINIT:
  3257.     char *name;
  3258.     VileBuf *newvbp;
  3259.  
  3260.     CODE:
  3261.     if (items > 2)
  3262.         croak("Too many arguments to %s", GvNAME(CvGV(cv)));
  3263.  
  3264.     name = (items == 1) ? NULL : (char *)SvPV(ST(1),na);
  3265.  
  3266.     (void) api_edit(name, &newvbp);
  3267.  
  3268.     RETVAL = newvbp;
  3269.  
  3270.     OUTPUT:
  3271.     RETVAL
  3272.  
  3273.  
  3274.   #
  3275.   # =item print BUFOBJ STR1,..,STRN
  3276.   #
  3277.   # =item insert BUFOBJ STR1,...,STRN
  3278.   #
  3279.   # Inserts one or more strings the buffer object at the current
  3280.   # position of DOT.  DOT will be left at the end of the strings
  3281.   # just inserted.
  3282.   #
  3283.   # When STDERR or STDOUT are printed to, the output will be
  3284.   # directed to the message line.
  3285.   #
  3286.   # Examples:
  3287.   #
  3288.   #     print "Hello, world!";          # Print a well known greeting on
  3289.   #                                     # the message line.
  3290.   #     print $Vile::current_buffer "new text";
  3291.   #                                     # put some new text in the current
  3292.   #                                     # buffer.
  3293.   #
  3294.   #     my $passbuf = new Vile::Buffer '/etc/passwd';
  3295.   #                                     # Fetch the password file
  3296.   #     $passbuf->dot('$$');            # Set the position at the end
  3297.   #     print $passbuf "joeuser::1000:100:Joe User:/home/joeuser:/bin/bash
  3298.   #                                     # Add 'joeuser' to the this buffer
  3299.   #     Vile->current_buffer($passbuf); # Make it visible to the user.
  3300.   #
  3301.  
  3302. void
  3303. PRINT(vbp, ...)
  3304.     VileBuf *vbp
  3305.  
  3306.     ALIAS:
  3307.     insert = 1
  3308.  
  3309.     CODE:
  3310.     if (vbp2bp(vbp) == bminip) {
  3311.         if (items > 0) {
  3312.         SV *tmp = newSVsv(ST(1));
  3313.         int i;
  3314.  
  3315.         for (i = 2; i < items; i++) {
  3316.             if (PL_ofslen > 0)
  3317.             sv_catpvn(tmp, PL_ofs, PL_ofslen);
  3318.  
  3319.             sv_catsv(tmp, ST(i));
  3320.         }
  3321.  
  3322.         if (write_message(tmp))
  3323.             use_ml_as_prompt = 1;
  3324.  
  3325.         SvREFCNT_dec(tmp);
  3326.         }
  3327.     }
  3328.     else {
  3329.         int i;
  3330.         for (i = 1; i < items; ) {
  3331.         STRLEN len;
  3332.         char *arg = SvPV(ST(i), len);
  3333.         api_dotinsert(vbp, arg, len);
  3334.         i++;
  3335.         if (i < items && PL_ofslen > 0)
  3336.             api_dotinsert(vbp, PL_ofs, PL_ofslen);
  3337.         }
  3338.         if (PL_orslen > 0)
  3339.         api_dotinsert(vbp, PL_ors, PL_orslen);
  3340.     }
  3341.  
  3342.   #
  3343.   # =item set_region BUFOBJ
  3344.   #
  3345.   # =item set_region BUFOBJ MOTIONSTR
  3346.   #
  3347.   # =item set_region BUFOBJ STARTLINE, ENDLINE
  3348.   #
  3349.   # =item set_region BUFOBJ STARTLINE, STARTOFFSET, ENDLINE, ENDOFFSET
  3350.   #
  3351.   # =item set_region BUFOBJ STARTLINE, STARTOFFSET, ENDLINE, ENDOFFSET, 'rectangle'
  3352.   #
  3353.   # =item set_region BUFOBJ STARTLINE, STARTOFFSET, ENDLINE, ENDOFFSET, 'exact'
  3354.   #
  3355.   # Sets the region upon which certain other methods will operate and
  3356.   # sets DOT to the beginning of the region.
  3357.   #
  3358.   # Either the line number or offset (or both) may be the special
  3359.   # string '$' which represents the last line in the buffer and the
  3360.   # last character on a line.
  3361.   #
  3362.   # Often times, however, the special string '$$' will be more useful.
  3363.   # It truly represents the farthest that it possible to go in both
  3364.   # the vertical and horizontal directions.  As a line number, this
  3365.   # represents the line beyond the last line of the buffer.
  3366.   # Characters inserted at this point will form a new line.  As an
  3367.   # offset, '$$' refers to the newline character at the end of a line.
  3368.   # Characters inserted at this point will be inserted before the
  3369.   # newline character.
  3370.   #
  3371.   # When used in an array context, returns a five element array with
  3372.   # the start line, start offset, end line, end offset, and a string
  3373.   # indicating the type of region (one of 'line', 'rectangle', or
  3374.   # 'exact').
  3375.   #
  3376.   # When used in a scalar context, returns the buffer object so that
  3377.   # cascading method calls may be performed, i.e,
  3378.   #
  3379.   #     $Vile::current_buffer->set_region(3,4)
  3380.   #                          ->attribute_cntl_a_sequences;
  3381.   #
  3382.   # There is a special form of set_region which may be used as follows:
  3383.   #
  3384.   #     $Vile::current_buffer->set_region('j2w');
  3385.   #
  3386.   # The above statement will set the region beginning at the current
  3387.   # location of DOT and ending at the location arrived at by moving
  3388.   # down one line and over two words.  This may be viewed as a
  3389.   # shorthand way of expressing the following (somewhat cumbersome)
  3390.   # statement:
  3391.   #
  3392.   #     $Vile::current_buffer->set_region(
  3393.   #             $Vile::current_buffer->motion('j2w'));
  3394.   #
  3395.   # Notes:
  3396.   #
  3397.   # =item 1
  3398.   #
  3399.   # rectangular regions are not implemented yet.
  3400.   #
  3401.   # =item 2
  3402.   #
  3403.   # setregion is an alias for set_region.
  3404.   #
  3405.  
  3406. void
  3407. set_region(vbp, ...)
  3408.     VileBuf *vbp
  3409.  
  3410.     ALIAS:
  3411.     setregion = 1
  3412.  
  3413.     PREINIT:
  3414.     I32 gimme;
  3415.     char *shapestr;
  3416.  
  3417.     PPCODE:
  3418.     api_setup_fake_win(vbp, TRUE);
  3419.     switch (items) {
  3420.         case 1:
  3421.         /* set DOT and recompute region */
  3422.         DOT = vbp->region.r_orig;
  3423.         MK  = vbp->region.r_end;
  3424.         regionshape = vbp->regionshape;
  3425.         break;
  3426.         case 2: {
  3427.         /* Set up a "motion" region */
  3428.         vbp->region.r_orig = DOT;    /* Remember DOT */
  3429.         if (api_motion(vbp, SvPV(ST(1), na))) {
  3430.             /* DOT is now at the other end of the motion */
  3431.             MK = vbp->region.r_orig;    /* Put remembered DOT in MK */
  3432.             regionshape = EXACT;
  3433.         }
  3434.         else {
  3435.             croak("set_region: Invalid motion");
  3436.         }
  3437.         break;
  3438.         }
  3439.         case 3:
  3440.         /* Set up a full line region */
  3441.         regionshape = FULLLINE;
  3442.         api_gotoline(vbp, sv2linenum(ST(2)));
  3443.         MK = DOT;
  3444.         api_gotoline(vbp, sv2linenum(ST(1)));
  3445.         break;
  3446.         case 5:
  3447.         /* Set up an exact region */
  3448.         regionshape = EXACT;
  3449.         goto set_region_common;
  3450.         break;
  3451.         case 6:
  3452.         /* Set up any kind of region (exact, fullline, or rectangle) */
  3453.         shapestr = SvPV(ST(5), na);
  3454.         if (strcmp(shapestr, "exact"))
  3455.             regionshape = EXACT;
  3456.         else if (strcmp(shapestr, "rectangle"))
  3457.             regionshape = RECTANGLE;
  3458.         else if (strcmp(shapestr, "fullline"))
  3459.             regionshape = FULLLINE;
  3460.         else {
  3461.             croak("Region shape argument not one of \"exact\", \"fullline\", or \"rectangle\"");
  3462.         }
  3463.         set_region_common:
  3464.         api_gotoline(vbp, sv2linenum(ST(3)));
  3465.         DOT.o = sv2offset(ST(4));
  3466.         MK = DOT;
  3467.         api_gotoline(vbp, sv2linenum(ST(1)));
  3468.         DOT.o = sv2offset(ST(2));
  3469.         break;
  3470.         default:
  3471.         croak("Invalid number of arguments to set_region");
  3472.         break;
  3473.     }
  3474.     haveregion = NULL;
  3475.     if (getregion(&vbp->region) != TRUE) {
  3476.         croak("set_region: Unable to set the region");
  3477.     }
  3478.     if (is_header_line(vbp->region.r_end, curbp)
  3479.         && !b_val(curbp, MDNEWLINE))
  3480.         vbp->region.r_size--;
  3481.     IoLINES(GvIO((GV*)vbp->perl_handle)) = 0;  /* reset $. */
  3482.     vbp->regionshape = regionshape;
  3483.     DOT = vbp->region.r_orig;
  3484.     vbp->dot_inited = 1;
  3485.     gimme = GIMME_V;
  3486.     if (gimme == G_SCALAR) {
  3487.         XPUSHs(ST(0));
  3488.     }
  3489.     else if (gimme == G_ARRAY) {
  3490.         /* Return range information */
  3491.         XPUSHs(sv_2mortal(newSViv(line_no(curbp, vbp->region.r_orig.l))));
  3492.         XPUSHs(sv_2mortal(newSViv(vbp->region.r_orig.o)));
  3493.         XPUSHs(sv_2mortal(newSViv(line_no(curbp, vbp->region.r_end.l)
  3494.                                                  - (vbp->regionshape == FULLLINE))));
  3495.         XPUSHs(sv_2mortal(newSViv(vbp->region.r_end.o)));
  3496.         XPUSHs(sv_2mortal(newSVpv(
  3497.         vbp->regionshape == FULLLINE ? "fullline" :
  3498.         vbp->regionshape == EXACT    ? "exact"
  3499.                                      : "rectangle",  0 )));
  3500.     }
  3501.  
  3502.  
  3503.   #
  3504.   # =item unmark
  3505.   #
  3506.   # Clear the "modified" status of the buffer.
  3507.   #
  3508.   # Returns the buffer object.
  3509.   #
  3510.  
  3511. VileBuf *
  3512. unmark(vbp)
  3513.     VileBuf *vbp
  3514.  
  3515.     CODE:
  3516.     api_setup_fake_win(vbp, TRUE);
  3517.     unmark(0,0);
  3518.     RETVAL = vbp;
  3519.  
  3520.     OUTPUT:
  3521.     RETVAL
  3522.