]> pd.if.org Git - pd_readline/blobdiff - mg/basic.c
Getting close to a basic working readline now.
[pd_readline] / mg / basic.c
diff --git a/mg/basic.c b/mg/basic.c
deleted file mode 100644 (file)
index 160d9c1..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-/*     $OpenBSD: basic.c,v 1.37 2012/06/18 09:26:03 lum Exp $  */
-
-/* This file is in the public domain */
-
-/*
- *             Basic cursor motion commands.
- *
- * The routines in this file are the basic
- * command functions for moving the cursor around on
- * the screen, setting mark, and swapping dot with
- * mark. Only moves between lines, which might make the
- * current buffer framing bad, are hard.
- */
-#include "def.h"
-
-#include <ctype.h>
-
-/*
- * Go to beginning of line.
- */
-/* ARGSUSED */
-int
-gotobol(int f, int n)
-{
-       curwp->w_doto = 0;
-       return (TRUE);
-}
-
-/*
- * Move cursor backwards. Do the
- * right thing if the count is less than
- * 0. Error if you try to move back from
- * the beginning of the buffer.
- */
-/* ARGSUSED */
-int
-backchar(int f, int n)
-{
-       struct line   *lp;
-
-       if (n < 0)
-               return (forwchar(f, -n));
-       while (n--) {
-               if (curwp->w_doto == 0) {
-                       if ((lp = lback(curwp->w_dotp)) == curbp->b_headp) {
-                               if (!(f & FFRAND))
-                                       ewprintf("Beginning of buffer");
-                               return (FALSE);
-                       }
-                       curwp->w_dotp = lp;
-                       curwp->w_doto = llength(lp);
-                       curwp->w_rflag |= WFMOVE;
-                       curwp->w_dotline--;
-               } else
-                       curwp->w_doto--;
-       }
-       return (TRUE);
-}
-
-/*
- * Go to end of line.
- */
-/* ARGSUSED */
-int
-gotoeol(int f, int n)
-{
-       curwp->w_doto = llength(curwp->w_dotp);
-       return (TRUE);
-}
-
-/*
- * Move cursor forwards. Do the
- * right thing if the count is less than
- * 0. Error if you try to move forward
- * from the end of the buffer.
- */
-/* ARGSUSED */
-int
-forwchar(int f, int n)
-{
-       if (n < 0)
-               return (backchar(f, -n));
-       while (n--) {
-               if (curwp->w_doto == llength(curwp->w_dotp)) {
-                       curwp->w_dotp = lforw(curwp->w_dotp);
-                       if (curwp->w_dotp == curbp->b_headp) {
-                               curwp->w_dotp = lback(curwp->w_dotp);
-                               if (!(f & FFRAND))
-                                       ewprintf("End of buffer");
-                               return (FALSE);
-                       }
-                       curwp->w_doto = 0;
-                       curwp->w_dotline++;
-                       curwp->w_rflag |= WFMOVE;
-               } else
-                       curwp->w_doto++;
-       }
-       return (TRUE);
-}
-
-/*
- * Go to the beginning of the
- * buffer. Setting WFFULL is conservative,
- * but almost always the case.
- */
-int
-gotobob(int f, int n)
-{
-       (void) setmark(f, n);
-       curwp->w_dotp = bfirstlp(curbp);
-       curwp->w_doto = 0;
-       curwp->w_rflag |= WFFULL;
-       curwp->w_dotline = 1;
-       return (TRUE);
-}
-
-/*
- * Go to the end of the buffer. Leave dot 3 lines from the bottom of the
- * window if buffer length is longer than window length; same as emacs.
- * Setting WFFULL is conservative, but almost always the case.
- */
-int
-gotoeob(int f, int n)
-{
-       struct line     *lp;
-       
-       (void) setmark(f, n);
-       curwp->w_dotp = blastlp(curbp);
-       curwp->w_doto = llength(curwp->w_dotp);
-       curwp->w_dotline = curwp->w_bufp->b_lines;
-
-       lp = curwp->w_dotp;
-       n = curwp->w_ntrows - 3;
-
-       if (n < curwp->w_bufp->b_lines && n >= 3) {
-               while (n--)
-                       curwp->w_dotp = lback(curwp->w_dotp);
-
-               curwp->w_linep = curwp->w_dotp;
-               curwp->w_dotp = lp;
-       }
-       curwp->w_rflag |= WFFULL;
-       return (TRUE);
-}
-
-/*
- * Move forward by full lines.
- * If the number of lines to move is less
- * than zero, call the backward line function to
- * actually do it. The last command controls how
- * the goal column is set.
- */
-/* ARGSUSED */
-int
-forwline(int f, int n)
-{
-       struct line  *dlp;
-
-       if (n < 0)
-               return (backline(f | FFRAND, -n));
-       if ((dlp = curwp->w_dotp) == curbp->b_headp)
-               return(TRUE);
-       if ((lastflag & CFCPCN) == 0)   /* Fix goal. */
-               setgoal();
-       thisflag |= CFCPCN;
-       if (n == 0)
-               return (TRUE);
-       while (n--) {
-               dlp = lforw(dlp);
-               if (dlp == curbp->b_headp) {
-                       curwp->w_dotp = lback(dlp);
-                       curwp->w_doto = llength(curwp->w_dotp);
-                       curwp->w_rflag |= WFMOVE;
-                       return (TRUE);
-               }
-               curwp->w_dotline++;
-       }
-       curwp->w_rflag |= WFMOVE;
-       curwp->w_dotp = dlp;
-       curwp->w_doto = getgoal(dlp);
-
-       return (TRUE);
-}
-
-/*
- * This function is like "forwline", but
- * goes backwards. The scheme is exactly the same.
- * Check for arguments that are less than zero and
- * call your alternate. Figure out the new line and
- * call "movedot" to perform the motion.
- */
-/* ARGSUSED */
-int
-backline(int f, int n)
-{
-       struct line   *dlp;
-
-       if (n < 0)
-               return (forwline(f | FFRAND, -n));
-       if ((lastflag & CFCPCN) == 0)   /* Fix goal. */
-               setgoal();
-       thisflag |= CFCPCN;
-       dlp = curwp->w_dotp;
-       while (n-- && lback(dlp) != curbp->b_headp) {
-               dlp = lback(dlp);
-               curwp->w_dotline--;
-       }
-       curwp->w_dotp = dlp;
-       curwp->w_doto = getgoal(dlp);
-       curwp->w_rflag |= WFMOVE;
-       return (TRUE);
-}
-
-/*
- * Set the current goal column, which is saved in the external variable
- * "curgoal", to the current cursor column. The column is never off
- * the edge of the screen; it's more like display then show position.
- */
-void
-setgoal(void)
-{
-       curgoal = getcolpos();          /* Get the position. */
-       /* we can now display past end of display, don't chop! */
-}
-
-/*
- * This routine looks at a line (pointed
- * to by the LINE pointer "dlp") and the current
- * vertical motion goal column (set by the "setgoal"
- * routine above) and returns the best offset to use
- * when a vertical motion is made into the line.
- */
-int
-getgoal(struct line *dlp)
-{
-       int c, i, col = 0;
-       char tmp[5];
-
-
-       for (i = 0; i < llength(dlp); i++) {
-               c = lgetc(dlp, i);
-               if (c == '\t'
-#ifdef NOTAB
-                   && !(curbp->b_flag & BFNOTAB)
-#endif
-                       ) {
-                       col |= 0x07;
-                       col++;
-               } else if (ISCTRL(c) != FALSE) {
-                       col += 2;
-               } else if (isprint(c))
-                       col++;
-               else {
-                       col += snprintf(tmp, sizeof(tmp), "\\%o", c);
-               }
-               if (col > curgoal)
-                       break;
-       }
-       return (i);
-}
-
-/*
- * Scroll forward by a specified number
- * of lines, or by a full page if no argument.
- * The "2" is the window overlap (this is the default
- * value from ITS EMACS). Because the top line in
- * the window is zapped, we have to do a hard
- * update and get it back.
- */
-/* ARGSUSED */
-int
-forwpage(int f, int n)
-{
-       struct line  *lp;
-
-       if (!(f & FFARG)) {
-               n = curwp->w_ntrows - 2;        /* Default scroll.       */
-               if (n <= 0)                     /* Forget the overlap    */
-                       n = 1;                  /* if tiny window.       */
-       } else if (n < 0)
-               return (backpage(f | FFRAND, -n));
-
-       lp = curwp->w_linep;
-       while (n--)
-               if ((lp = lforw(lp)) == curbp->b_headp) {
-                       ttbeep();
-                       ewprintf("End of buffer");
-                       return(TRUE);
-               }
-
-       curwp->w_linep = lp;
-       curwp->w_rflag |= WFFULL;
-
-       /* if in current window, don't move dot */
-       for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp))
-               if (lp == curwp->w_dotp)
-                       return (TRUE);
-
-       /* Advance the dot the slow way, for line nos */
-       while (curwp->w_dotp != curwp->w_linep) {
-               curwp->w_dotp = lforw(curwp->w_dotp);
-               curwp->w_dotline++;
-       }
-       curwp->w_doto = 0;
-       return (TRUE);
-}
-
-/*
- * This command is like "forwpage",
- * but it goes backwards. The "2", like above,
- * is the overlap between the two windows. The
- * value is from the ITS EMACS manual. The
- * hard update is done because the top line in
- * the window is zapped.
- */
-/* ARGSUSED */
-int
-backpage(int f, int n)
-{
-       struct line  *lp, *lp2;
-
-       if (!(f & FFARG)) {
-               n = curwp->w_ntrows - 2;        /* Default scroll.       */
-               if (n <= 0)                     /* Don't blow up if the  */
-                       return (backline(f, 1));/* window is tiny.       */
-       } else if (n < 0)
-               return (forwpage(f | FFRAND, -n));
-
-       lp = lp2 = curwp->w_linep;
-
-       while (n-- && lback(lp) != curbp->b_headp) {
-               lp = lback(lp);
-       }
-       if (lp == curwp->w_linep) {
-               ttbeep();
-               ewprintf("Beginning of buffer");
-       }
-       curwp->w_linep = lp;
-       curwp->w_rflag |= WFFULL;
-
-       /* if in current window, don't move dot */
-       for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp))
-               if (lp == curwp->w_dotp)
-                       return (TRUE);
-
-        lp2 = lforw(lp2);
-
-       /* Move the dot the slow way, for line nos */
-       while (curwp->w_dotp != lp2) {
-                if (curwp->w_dotline <= curwp->w_ntrows)
-                        return (TRUE);
-               curwp->w_dotp = lback(curwp->w_dotp);
-               curwp->w_dotline--;
-       }
-       curwp->w_doto = 0;
-       return (TRUE);
-}
-
-/*
- * These functions are provided for compatibility with Gosling's Emacs. They
- * are used to scroll the display up (or down) one line at a time.
- */
-int
-forw1page(int f, int n)
-{
-       if (!(f & FFARG)) {
-               n = 1;
-               f = FFUNIV;
-       }
-       forwpage(f | FFRAND, n);
-       return (TRUE);
-}
-
-int
-back1page(int f, int n)
-{
-       if (!(f & FFARG)) {
-               n = 1;
-               f = FFUNIV;
-       }
-       backpage(f | FFRAND, n);
-       return (TRUE);
-}
-
-/*
- * Page the other window. Check to make sure it exists, then
- * nextwind, forwpage and restore window pointers.
- */
-int
-pagenext(int f, int n)
-{
-       struct mgwin *wp;
-
-       if (wheadp->w_wndp == NULL) {
-               ewprintf("No other window");
-               return (FALSE);
-       }
-       wp = curwp;
-       (void) nextwind(f, n);
-       (void) forwpage(f, n);
-       curwp = wp;
-       curbp = wp->w_bufp;
-       return (TRUE);
-}
-
-/*
- * Internal set mark routine, used by other functions (daveb).
- */
-void
-isetmark(void)
-{
-       curwp->w_markp = curwp->w_dotp;
-       curwp->w_marko = curwp->w_doto;
-       curwp->w_markline = curwp->w_dotline;
-}
-
-/*
- * Set the mark in the current window
- * to the value of dot. A message is written to
- * the echo line.  (ewprintf knows about macros)
- */
-/* ARGSUSED */
-int
-setmark(int f, int n)
-{
-       isetmark();
-       ewprintf("Mark set");
-       return (TRUE);
-}
-
-/* Clear the mark, if set. */
-/* ARGSUSED */
-int
-clearmark(int f, int n)
-{
-       if (!curwp->w_markp)
-               return (FALSE);
-
-       curwp->w_markp = NULL;
-       curwp->w_marko = 0;
-       curwp->w_markline = 0;
-
-       return (TRUE);
-}
-
-/*
- * Swap the values of "dot" and "mark" in
- * the current window. This is pretty easy, because
- * all of the hard work gets done by the standard routine
- * that moves the mark about. The only possible
- * error is "no mark".
- */
-/* ARGSUSED */
-int
-swapmark(int f, int n)
-{
-       struct line  *odotp;
-       int odoto, odotline;
-
-       if (curwp->w_markp == NULL) {
-               ewprintf("No mark in this window");
-               return (FALSE);
-       }
-       odotp = curwp->w_dotp;
-       odoto = curwp->w_doto;
-       odotline = curwp->w_dotline;
-       curwp->w_dotp = curwp->w_markp;
-       curwp->w_doto = curwp->w_marko;
-       curwp->w_dotline = curwp->w_markline;
-       curwp->w_markp = odotp;
-       curwp->w_marko = odoto;
-       curwp->w_markline = odotline;
-       curwp->w_rflag |= WFMOVE;
-       return (TRUE);
-}
-
-/*
- * Go to a specific line, mostly for
- * looking up errors in C programs, which give the
- * error a line number. If an argument is present, then
- * it is the line number, else prompt for a line number
- * to use.
- */
-/* ARGSUSED */
-int
-gotoline(int f, int n)
-{
-       struct line  *clp;
-       char   buf[32], *bufp;
-       const char *err;
-
-       if (!(f & FFARG)) {
-               if ((bufp = eread("Goto line: ", buf, sizeof(buf),
-                   EFNUL | EFNEW | EFCR)) == NULL)
-                       return (ABORT);
-               if (bufp[0] == '\0')
-                       return (ABORT);
-               n = (int)strtonum(buf, INT_MIN, INT_MAX, &err);
-               if (err) {
-                       ewprintf("Line number %s", err);
-                       return (FALSE);
-               }
-       }
-       if (n >= 0) {
-               if (n == 0)
-                       n++;
-               curwp->w_dotline = n;
-               clp = lforw(curbp->b_headp);    /* "clp" is first line */
-               while (--n > 0) {
-                       if (lforw(clp) == curbp->b_headp) {
-                               curwp->w_dotline = curwp->w_bufp->b_lines;
-                               break;
-                       }
-                       clp = lforw(clp);
-               }
-       } else {
-               curwp->w_dotline = curwp->w_bufp->b_lines + n;
-               clp = lback(curbp->b_headp);    /* "clp" is last line */
-               while (n < 0) {
-                       if (lback(clp) == curbp->b_headp) {
-                               curwp->w_dotline = 1;
-                               break;
-                       }
-                       clp = lback(clp);
-                       n++;
-               }
-       }
-       curwp->w_dotp = clp;
-       curwp->w_doto = 0;
-       curwp->w_rflag |= WFMOVE;
-       return (TRUE);
-}