1 /* $OpenBSD: match.c,v 1.16 2009/06/04 02:23:37 kjell Exp $ */
3 /* This file is in the public domain. */
6 * Limited parenthesis matching routines
8 * The hacks in this file implement automatic matching * of (), [], {}, and
9 * other characters. It would be better to have a full-blown syntax table,
10 * but there's enough overhead in the editor as it is.
16 static int balance(void);
17 static void displaymatch(struct line *, int);
20 * Balance table. When balance() encounters a character that is to be
21 * matched, it first searches this table for a balancing left-side character.
22 * If the character is not in the table, the character is balanced by itself.
24 static struct balance {
35 * Hack to show matching paren. Self-insert character, then show matching
36 * character, if any. Bound to "blink-and-insert".
39 showmatch(int f, int n)
43 for (i = 0; i < n; i++) {
44 if ((s = selfinsert(FFRAND, 1)) != TRUE)
46 /* unbalanced -- warn user */
47 if (balance() != TRUE)
54 * Search for and display a matching character.
56 * This routine does the real work of searching backward
57 * for a balancing character. If such a balancing character
58 * is found, it uses displaymatch() to display the match.
68 rbal = key.k_chars[key.k_count - 1];
70 /* See if there is a matching character -- default to the same */
72 for (i = 0; bal[i].right != '\0'; i++)
73 if (bal[i].right == rbal) {
79 * Move behind the inserted character. We are always guaranteed
80 * that there is at least one character on the line, since one was
81 * just self-inserted by blinkparen.
84 cbo = curwp->w_doto - 1;
86 /* init nesting depth */
91 clp = lback(clp); /* beginning of line */
92 if (clp == curbp->b_headp)
94 cbo = llength(clp) + 1;
96 if (--cbo == llength(clp))
97 c = '\n'; /* end of line */
99 c = lgetc(clp, cbo); /* somewhere in middle */
102 * Check for a matching character. If still in a nested
103 * level, pop out of it and continue search. This check
104 * is done before the nesting check so single-character
105 * matches will work too.
109 displaymatch(clp, cbo);
114 /* Check for another level of nesting. */
122 * Display matching character. Matching characters that are not in the
123 * current window are displayed in the echo line. If in the current window,
124 * move dot to the matching character, sit there a while, then move back.
127 displaymatch(struct line *clp, int cbo)
138 * Figure out if matching char is in current window by
139 * searching from the top of the window to dot.
142 for (tlp = curwp->w_linep; tlp != lforw(curwp->w_dotp);
147 if (inwindow == TRUE) {
148 tlp = curwp->w_dotp; /* save current position */
151 curwp->w_dotp = clp; /* move to new position */
153 curwp->w_rflag |= WFMOVE;
155 update(); /* show match */
156 ttwait(1000); /* wait for key or 1 second */
158 curwp->w_dotp = tlp; /* return to old position */
160 curwp->w_rflag |= WFMOVE;
163 /* match is not in this window, so display line in echo area */
165 for (cp = 0; cp < llength(clp); cp++) {
169 || (curbp->b_flag & BFNOTAB)
174 buf[bufo++] = CCHR(c);
183 ewprintf("Matches %s", buf);