[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs clang.c
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs clang.c |
Date: |
Sat, 15 Mar 2014 23:00:07 +0000 |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 14/03/15 23:00:07
Modified files:
. : clang.c
Log message:
fix some c-mode problems
* fix indentation change, was broken if extra spaces needed removal
* remove remove_indent, no longer needed
* handle || and && test continuation lines according to lisp-like style
* fix erratic indentation on ':'
* unindent labels and case/default clauses
* allow tab override if pressed more than once
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/clang.c?cvsroot=qemacs&r1=1.48&r2=1.49
Patches:
Index: clang.c
===================================================================
RCS file: /sources/qemacs/qemacs/clang.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -b -r1.48 -r1.49
--- clang.c 1 Mar 2014 19:21:40 -0000 1.48
+++ clang.c 15 Mar 2014 23:00:07 -0000 1.49
@@ -57,26 +57,27 @@
"cal" /* GNU Calc */
;
-#if 0
+/* grab a C identifier from a uchar buf, stripping color.
+ * return char count.
+ */
static int get_c_identifier(char *buf, int buf_size, unsigned int *p)
{
unsigned int c;
- char *q;
+ int i, j;
- c = *p;
- q = buf;
- if (qe_isalpha_(c)) {
+ i = j = 0;
+ c = p[i];
+ if (qe_isalpha_(c & CHAR_MASK)) {
do {
- if ((q - buf) < buf_size - 1)
- *q++ = c;
- p++;
- c = *p;
- } while (qe_isalnum_(c));
+ if (j < buf_size - 1)
+ buf[j++] = c;
+ i++;
+ c = p[i];
+ } while (qe_isalnum_(c & CHAR_MASK));
}
- *q = '\0';
- return q - buf;
+ buf[j] = '\0';
+ return i;
}
-#endif
/* c-mode colorization states */
enum {
@@ -315,11 +316,13 @@
pos = 0;
for (i = 0; i < size; i++) {
c = buf[i] & CHAR_MASK;
- if (c == '\t')
+ if (c == '\t') {
pos += s->b->tab_width - (pos % s->b->tab_width);
- else
+ } else {
+ /* simplistic case: assume single width characters */
pos++;
}
+ }
return pos;
}
@@ -331,78 +334,66 @@
/* Check if indentation is already what it should be */
static int check_indent(EditState *s, int offset, int i, int *offset_ptr)
{
+ int tw, col, ntabs, nspaces, bad;
int offset1;
- /* check tabs */
- if (s->indent_tabs_mode) {
- while (i >= s->b->tab_width) {
- if (eb_nextc(s->b, offset, &offset) != '\t')
- return 0;
- i -= s->b->tab_width;
- }
- }
+ tw = s->b->tab_width > 0 ? s->b->tab_width : 8;
+ col = ntabs = nspaces = bad = 0;
- /* check needed spaces */
- while (i > 0) {
- if (eb_nextc(s->b, offset, &offset) != ' ')
- return 0;
- i--;
+ for (;;) {
+ int c = eb_nextc(s->b, offset1 = offset, &offset);
+ if (c == '\t') {
+ col += tw - col % tw;
+ bad |= nspaces;
+ ntabs += 1;
+ } else
+ if (c == ' ') {
+ col += 1;
+ nspaces += 1;
+ } else {
+ break;
}
- if (!qe_isblank(eb_nextc(s->b, offset, &offset1))) {
- *offset_ptr = offset;
}
- return 1;
-}
-static void remove_indent(EditState *s, int offset)
-{
- int offset1 = offset, offset2;
+ *offset_ptr = offset1;
- /* suppress leading spaces */
- for (;;) {
- int c = eb_nextc(s->b, offset1, &offset2);
- if (c != ' ' && c != '\t')
- break;
- offset1 = offset2;
+ if (col != i || bad)
+ return 0;
+
+ /* check tabs */
+ if (s->indent_tabs_mode) {
+ return (nspaces >= tw) ? 0 : 1;
+ } else {
+ return (ntabs > 0) ? 0 : 1;
}
- if (offset1 > offset)
- eb_delete_range(s->b, offset, offset1);
}
/* Insert n spaces at beginning of line at <offset>.
- * Stop new offset after indentation to <*offset_ptr>.
- * Tabs are inserted if s->indent_tabs_mode is true. */
+ * Store new offset after indentation to <*offset_ptr>.
+ * Tabs are inserted if s->indent_tabs_mode is true.
+ */
static void insert_indent(EditState *s, int offset, int i, int *offset_ptr)
{
/* insert tabs */
if (s->indent_tabs_mode) {
- while (i >= s->b->tab_width) {
+ int tw = s->b->tab_width > 0 ? s->b->tab_width : 8;
+ while (i >= tw) {
offset += eb_insert_uchar(s->b, offset, '\t');
- i -= s->b->tab_width;
+ i -= tw;
}
}
/* insert needed spaces */
- while (i > 0) {
- char buf[64];
- int size = i;
-
- if (size > ssizeof(buf))
- size = ssizeof(buf);
- memset(buf, ' ', size);
- offset += eb_insert_utf8_buf(s->b, offset, buf, size);
- i -= size;
- }
+ offset += eb_insert_spaces(s->b, offset, i);
+
*offset_ptr = offset;
}
-/* indent a line of C code starting at <offset>,
- * store indentation in <*offset_ptr>
- */
+/* indent a line of C code starting at <offset> */
static void c_indent_line(EditState *s, int offset0)
{
int offset, offset1, offsetl, c, pos, line_num, col_num;
- int i, eoi_found, len, pos1, lpos, style, line_num1, state;
+ int i, j, eoi_found, len, pos1, lpos, style, line_num1, state;
unsigned int buf[MAX_BUF_SIZE], *p;
unsigned char stack[MAX_STACK_SIZE];
char buf1[64], *q;
@@ -434,10 +425,11 @@
c = *p;
/* skip strings or comments */
style = c >> STYLE_SHIFT;
- if (style == QE_STYLE_COMMENT ||
- style == QE_STYLE_STRING ||
- style == QE_STYLE_PREPROCESS)
+ if (style == QE_STYLE_COMMENT
+ || style == QE_STYLE_STRING
+ || style == QE_STYLE_PREPROCESS) {
continue;
+ }
c = c & CHAR_MASK;
if (state == INDENT_FIND_EQ) {
/* special case to search '=' or ; before { to know if
@@ -513,10 +505,12 @@
case ':':
/* a label line is ignored */
/* XXX: incorrect */
+ if (style == QE_STYLE_DEFAULT)
goto prev_line;
+ break;
default:
if (stack_ptr == 0) {
- if ((c >> STYLE_SHIFT) == QE_STYLE_KEYWORD) {
+ if (style == QE_STYLE_KEYWORD) {
unsigned int *p1, *p2;
/* special case for if/for/while */
p1 = p;
@@ -560,13 +554,31 @@
for (i = 0; i < len; i++) {
c = buf[i];
style = c >> STYLE_SHIFT;
+ if (qe_isblank(c & CHAR_MASK))
+ continue;
/* if preprocess, no indent */
if (style == QE_STYLE_PREPROCESS) {
pos = 0;
break;
}
+ if (qe_isalpha_(c & CHAR_MASK)) {
+ j = get_c_identifier(buf1, countof(buf1), buf + i);
+
+ if (style == QE_STYLE_KEYWORD) {
+ if (strfind(buf1, "case|default"))
+ goto unindent;
+ }
+ for (j += i; qe_isblank(buf[j] & CHAR_MASK); j++)
+ continue;
+ if (buf[j] == ':')
+ goto unindent;
+ }
/* NOTE: strings & comments are correctly ignored there */
- if (c == '}' || c == ':') {
+ if ((c == '&' || c == '|') && buf[i + 1] == c)
+ goto unindent;
+
+ if (c == '}') {
+ unindent:
pos -= s->indent_size;
if (pos < 0)
pos = 0;
@@ -576,29 +588,34 @@
pos = 0;
break;
}
+ break;
}
- /* the number of needed spaces is in 'pos' */
+ /* the computed indent is in 'pos' */
/* if on a blank line, reset indent to 0 unless point is on it */
if (eb_is_blank_line(s->b, offset, &offset1)
- && (s->offset < offset || s->offset >= offset1)) {
+ && !(s->offset >= offset && s->offset < offset1)) {
pos = 0;
}
/* Do not modify buffer if indentation in correct */
if (!check_indent(s, offset, pos, &offset1)) {
/* simple approach to normalization of indentation */
- remove_indent(s, offset);
+ eb_delete_range(s->b, offset, offset1);
insert_indent(s, offset, pos, &offset1);
}
- if (s->offset >= offset && s->offset < offset1) {
/* move to the indentation if point was in indent space */
+ if (s->offset >= offset && s->offset < offset1) {
s->offset = offset1;
}
}
static void do_c_indent(EditState *s)
{
+ if (s->qe_state->last_cmd_func == (CmdFunc)do_c_indent) {
+ do_tab(s, 1);
+ } else {
c_indent_line(s, s->offset);
+ }
}
static void do_c_indent_region(EditState *s)