[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs util.c qe.h extra-modes.c
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs util.c qe.h extra-modes.c |
Date: |
Fri, 07 Mar 2014 10:26:00 +0000 |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 14/03/07 10:26:00
Modified files:
. : util.c qe.h extra-modes.c
Log message:
add haskell-mode
* detect haskell files on extension: *.hs
* fix small things
* add qe_findchar(str, c) to search code point in ascii string
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/util.c?cvsroot=qemacs&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.145&r2=1.146
http://cvs.savannah.gnu.org/viewcvs/qemacs/extra-modes.c?cvsroot=qemacs&r1=1.2&r2=1.3
Patches:
Index: util.c
===================================================================
RCS file: /sources/qemacs/qemacs/util.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- util.c 7 Feb 2014 07:38:31 -0000 1.62
+++ util.c 7 Mar 2014 10:25:59 -0000 1.63
@@ -207,8 +207,10 @@
void canonicalize_path(char *buf, int buf_size, const char *path)
{
const char *p;
+
/* check for URL protocol or windows drive */
/* CG: should not skip '/' */
+ /* XXX: bogus if filename contains ':' */
p = strchr(path, ':');
if (p) {
if ((p - path) == 1) {
@@ -232,6 +234,7 @@
{
const char *p;
+ /* XXX: should only accept 'drive:' and 'proto:' */
p = strchr(path, ':');
if (p)
p++;
Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.145
retrieving revision 1.146
diff -u -b -r1.145 -r1.146
--- qe.h 6 Mar 2014 20:36:50 -0000 1.145
+++ qe.h 7 Mar 2014 10:25:59 -0000 1.146
@@ -276,6 +276,10 @@
return (qe_inrange(c, 'A', 'Z') ? c + 'a' - 'A' : c);
}
+static int inline qe_findchar(const char *str, int c) {
+ return qe_inrange(c, 1, 255) && strchr(str, c);
+}
+
int qe_strcollate(const char *s1, const char *s2);
void qe_strtolower(char *buf, int buf_size, const char *str);
void skip_spaces(const char **pp);
@@ -1918,6 +1922,13 @@
ModeSavedData *saved_data,
int is_html, const char *default_stylesheet);
+/* extra-modes.c */
+
+void lua_colorize_line(unsigned int *buf, int len,
+ int *colorize_state_ptr, int state_only);
+void haskell_colorize_line(unsigned int *buf, int len,
+ int *colorize_state_ptr, int state_only);
+
/* image.c */
void fill_border(EditState *s, int x, int y, int w, int h, int color);
Index: extra-modes.c
===================================================================
RCS file: /sources/qemacs/qemacs/extra-modes.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- extra-modes.c 7 Mar 2014 02:24:14 -0000 1.2
+++ extra-modes.c 7 Mar 2014 10:26:00 -0000 1.3
@@ -290,7 +290,7 @@
if (qe_isalpha_(str[i])) {
for (j = i + 1; j < n; j++) {
if (!qe_isalnum_(str[j])) {
- if (strchr("$&address@hidden", str[j]))
+ if (qe_findchar("$&address@hidden", str[j]))
j++;
break;
}
@@ -693,7 +693,7 @@
PS_IDENTIFIER = QE_STYLE_FUNCTION,
};
-#define ispssep(c) (strchr(" \t\r\n,()<>[]{}/", (c)) != NULL)
+#define ispssep(c) (qe_findchar(" \t\r\n,()<>[]{}/", c))
#define wrap 0
static void ps_colorize_line(unsigned int *str, int n, int *statep,
@@ -965,7 +965,7 @@
}
}
-static void lua_colorize_line(unsigned int *str, int n, int *statep,
+void lua_colorize_line(unsigned int *str, int n, int *statep,
__unused__ int state_only)
{
int i = 0, j = i, c, sep = 0, level = 0, level1, klen, style;
@@ -1052,6 +1052,7 @@
continue;
default:
if (qe_isdigit(c)) {
+ /* XXX: should parse actual number syntax */
for (j = i + 1; j < n; j++) {
if (!qe_isalnum(str[j] && str[j] != '.'))
break;
@@ -1125,6 +1126,245 @@
return 0;
}
+/*---------------- Haskell coloring ----------------*/
+
+static char const haskell_keywords[] = {
+ "|_|case|class|data|default|deriving|do|else|foreign"
+ "|if|import|in|infix|infixl|infixr|instance|let"
+ "|module|newtype|of|then|type|where"
+ "|"
+};
+
+#define IN_COMMENT 0x10
+#define IN_STRING 0x20
+#define IN_LEVEL 0x0F
+
+enum {
+ HASKELL_TEXT = QE_STYLE_DEFAULT,
+ HASKELL_COMMENT = QE_STYLE_COMMENT,
+ HASKELL_STRING = QE_STYLE_STRING,
+ HASKELL_LONGLIT = QE_STYLE_STRING,
+ HASKELL_NUMBER = QE_STYLE_NUMBER,
+ HASKELL_KEYWORD = QE_STYLE_KEYWORD,
+ HASKELL_FUNCTION = QE_STYLE_FUNCTION,
+ HASKELL_SYMBOL = QE_STYLE_NUMBER,
+};
+
+static inline int haskell_is_symbol(int c)
+{
+ return qe_findchar("!#$%&+./<=>address@hidden|-~:", c);
+}
+
+void haskell_colorize_line(unsigned int *str, int n, int *statep,
+ __unused__ int state_only)
+{
+ int i = 0, j = i, c, sep = 0, level = 0, klen;
+ int state = *statep;
+ char kbuf[32];
+
+ if (state & IN_COMMENT)
+ goto parse_comment;
+
+ if (state & IN_STRING) {
+ sep = '\"';
+ state = 0;
+ while (qe_isspace(str[j]))
+ j++;
+ if (str[j] == '\\')
+ j++;
+ goto parse_string;
+ }
+
+ while (i < n) {
+ switch (c = str[i]) {
+ case '-':
+ if (str[i + 1] == '-' && !haskell_is_symbol(str[i + 2])) {
+ SET_COLOR(str, i, n, HASKELL_COMMENT);
+ i = n;
+ continue;
+ }
+ goto parse_symbol;
+ case '{':
+ if (str[i + 1] == '-') {
+ state |= IN_COMMENT;
+ goto parse_comment;
+ }
+ /* FALL THRU */
+ case '}':
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ case ',':
+ case ';':
+ case '`':
+ /* special */
+ break;
+
+ parse_comment:
+ level = state & IN_LEVEL;
+ for (j = i; j < n; j++) {
+ if (str[i] == '{' && str[i + 1] == '-') {
+ level++;
+ j++;
+ continue;
+ }
+ if (str[i] == '-' && str[i + 1] == '}') {
+ j++;
+ level--;
+ if (level == 0) {
+ j++;
+ state &= ~IN_COMMENT;
+ break;
+ }
+ }
+ }
+ state &= ~IN_COMMENT;
+ state |= level & IN_COMMENT;
+ SET_COLOR(str, i, j, HASKELL_COMMENT);
+ i = j;
+ continue;
+
+ case '\'':
+ case '"':
+ /* parse string const */
+ sep = str[i];
+ j = i + 1;
+ parse_string:
+ for (; j < n;) {
+ c = str[j++];
+ if (c == '\\') {
+ if (j == n) {
+ if (sep == '\"') {
+ /* XXX: should ignore whitespace */
+ state = IN_STRING;
+ }
+ } else
+ if (str[j] == '^' && j + 1 < n && str[j + 1] != sep) {
+ j += 2;
+ } else {
+ j += 1;
+ }
+ } else
+ if (c == sep) {
+ break;
+ }
+ }
+ SET_COLOR(str, i, j, HASKELL_STRING);
+ i = j;
+ continue;
+
+ default:
+ if (qe_isdigit(c)) {
+ j = i + 1;
+ if (c == '0' && qe_tolower(str[j]) == 'o') {
+ /* octal numbers */
+ for (j += 1; str[j] >= '0' && str[j] < '8'; j++)
+ continue;
+ } else
+ if (c == '0' && qe_tolower(str[j]) == 'x') {
+ /* hexadecimal numbers */
+ for (j += 1; qe_isxdigit(str[j]); j++)
+ continue;
+ } else {
+ /* decimal numbers */
+ for (j = i + 1; qe_isdigit(str[j]); j++)
+ continue;
+ if (str[j] == '.' && qe_isdigit(str[j + 1])) {
+ /* decimal floats require a digit after the '.' */
+ for (j = i + 2; qe_isdigit(str[j]); j++)
+ continue;
+ if (qe_tolower(str[j]) == 'e') {
+ int k = j + 1;
+ if (str[k] == '+' || str[k] == '-')
+ k++;
+ if (qe_isdigit(str[k])) {
+ for (j = k + 1; qe_isdigit(str[j]); j++)
+ continue;
+ }
+ }
+ }
+ }
+ /* XXX: should detect malformed number constants */
+ SET_COLOR(str, i, j, HASKELL_NUMBER);
+ i = j;
+ continue;
+ }
+ if (qe_isalpha_(c)) {
+ for (klen = 0, j = i + 1;
+ qe_isalnum_(str[j]) || str[j] == '\'';
+ j++) {
+ if (klen < countof(kbuf) - 1)
+ kbuf[klen++] = str[j];
+ }
+ kbuf[klen] = '\0';
+
+ if (strfind(haskell_keywords, kbuf)) {
+ SET_COLOR(str, i, j, HASKELL_KEYWORD);
+ i = j;
+ continue;
+ }
+ while (qe_isblank(str[j]))
+ j++;
+ if (str[j] == '(') {
+ SET_COLOR(str, i, j, HASKELL_FUNCTION);
+ i = j;
+ continue;
+ }
+ i = j;
+ continue;
+ }
+ parse_symbol:
+ if (haskell_is_symbol(c)) {
+ for (j = i + 1; haskell_is_symbol(str[j]); j++)
+ continue;
+ SET_COLOR(str, i, j, HASKELL_SYMBOL);
+ i = j;
+ continue;
+ }
+ break;
+ }
+ i++;
+ continue;
+ }
+ *statep = state;
+}
+
+#undef IN_COMMENT
+#undef IN_STRING
+#undef IN_STRING2
+#undef IN_LONGLIT
+#undef IN_LEVEL
+
+static int haskell_mode_probe(ModeDef *mode, ModeProbeData *p)
+{
+ if (match_extension(p->filename, mode->extensions))
+ return 80;
+
+ return 1;
+}
+
+static CmdDef haskell_commands[] = {
+ CMD_DEF_END,
+};
+
+static ModeDef haskell_mode;
+
+static int haskell_init(void)
+{
+ /* haskell mode is almost like the text mode, so we copy and patch it */
+ memcpy(&haskell_mode, &text_mode, sizeof(ModeDef));
+ haskell_mode.name = "Haskell";
+ haskell_mode.extensions = "hs|haskell";
+ haskell_mode.mode_probe = haskell_mode_probe;
+ haskell_mode.colorize_func = haskell_colorize_line;
+
+ qe_register_mode(&haskell_mode);
+ qe_register_cmd_table(haskell_commands, &haskell_mode);
+
+ return 0;
+}
+
/*----------------*/
static int extra_modes_init(void)
@@ -1136,6 +1376,7 @@
ps_init();
sql_init();
lua_init();
+ haskell_init();
return 0;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemacs-commit] qemacs util.c qe.h extra-modes.c,
Charlie Gordon <=