+++ /dev/null
-/* $OpenBSD: match.c,v 1.16 2009/06/04 02:23:37 kjell Exp $ */
-
-/* This file is in the public domain. */
-
-/*
- * Limited parenthesis matching routines
- *
- * The hacks in this file implement automatic matching * of (), [], {}, and
- * other characters. It would be better to have a full-blown syntax table,
- * but there's enough overhead in the editor as it is.
- */
-
-#include "def.h"
-#include "key.h"
-
-static int balance(void);
-static void displaymatch(struct line *, int);
-
-/*
- * Balance table. When balance() encounters a character that is to be
- * matched, it first searches this table for a balancing left-side character.
- * If the character is not in the table, the character is balanced by itself.
- */
-static struct balance {
- char left, right;
-} bal[] = {
- { '(', ')' },
- { '[', ']' },
- { '{', '}' },
- { '<', '>' },
- { '\0', '\0' }
-};
-
-/*
- * Hack to show matching paren. Self-insert character, then show matching
- * character, if any. Bound to "blink-and-insert".
- */
-int
-showmatch(int f, int n)
-{
- int i, s;
-
- for (i = 0; i < n; i++) {
- if ((s = selfinsert(FFRAND, 1)) != TRUE)
- return (s);
- /* unbalanced -- warn user */
- if (balance() != TRUE)
- ttbeep();
- }
- return (TRUE);
-}
-
-/*
- * Search for and display a matching character.
- *
- * This routine does the real work of searching backward
- * for a balancing character. If such a balancing character
- * is found, it uses displaymatch() to display the match.
- */
-static int
-balance(void)
-{
- struct line *clp;
- int cbo;
- int c, i, depth;
- int rbal, lbal;
-
- rbal = key.k_chars[key.k_count - 1];
-
- /* See if there is a matching character -- default to the same */
- lbal = rbal;
- for (i = 0; bal[i].right != '\0'; i++)
- if (bal[i].right == rbal) {
- lbal = bal[i].left;
- break;
- }
-
- /*
- * Move behind the inserted character. We are always guaranteed
- * that there is at least one character on the line, since one was
- * just self-inserted by blinkparen.
- */
- clp = curwp->w_dotp;
- cbo = curwp->w_doto - 1;
-
- /* init nesting depth */
- depth = 0;
-
- for (;;) {
- if (cbo == 0) {
- clp = lback(clp); /* beginning of line */
- if (clp == curbp->b_headp)
- return (FALSE);
- cbo = llength(clp) + 1;
- }
- if (--cbo == llength(clp))
- c = '\n'; /* end of line */
- else
- c = lgetc(clp, cbo); /* somewhere in middle */
-
- /*
- * Check for a matching character. If still in a nested
- * level, pop out of it and continue search. This check
- * is done before the nesting check so single-character
- * matches will work too.
- */
- if (c == lbal) {
- if (depth == 0) {
- displaymatch(clp, cbo);
- return (TRUE);
- } else
- depth--;
- }
- /* Check for another level of nesting. */
- if (c == rbal)
- depth++;
- }
- /* NOTREACHED */
-}
-
-/*
- * Display matching character. Matching characters that are not in the
- * current window are displayed in the echo line. If in the current window,
- * move dot to the matching character, sit there a while, then move back.
- */
-static void
-displaymatch(struct line *clp, int cbo)
-{
- struct line *tlp;
- int tbo;
- int cp;
- int bufo;
- int c;
- int inwindow;
- char buf[NLINE];
-
- /*
- * Figure out if matching char is in current window by
- * searching from the top of the window to dot.
- */
- inwindow = FALSE;
- for (tlp = curwp->w_linep; tlp != lforw(curwp->w_dotp);
- tlp = lforw(tlp))
- if (tlp == clp)
- inwindow = TRUE;
-
- if (inwindow == TRUE) {
- tlp = curwp->w_dotp; /* save current position */
- tbo = curwp->w_doto;
-
- curwp->w_dotp = clp; /* move to new position */
- curwp->w_doto = cbo;
- curwp->w_rflag |= WFMOVE;
-
- update(); /* show match */
- ttwait(1000); /* wait for key or 1 second */
-
- curwp->w_dotp = tlp; /* return to old position */
- curwp->w_doto = tbo;
- curwp->w_rflag |= WFMOVE;
- update();
- } else {
- /* match is not in this window, so display line in echo area */
- bufo = 0;
- for (cp = 0; cp < llength(clp); cp++) {
- c = lgetc(clp, cp);
- if (c != '\t'
-#ifdef NOTAB
- || (curbp->b_flag & BFNOTAB)
-#endif
- )
- if (ISCTRL(c)) {
- buf[bufo++] = '^';
- buf[bufo++] = CCHR(c);
- } else
- buf[bufo++] = c;
- else
- do {
- buf[bufo++] = ' ';
- } while (bufo & 7);
- }
- buf[bufo++] = '\0';
- ewprintf("Matches %s", buf);
- }
-}