Commit 9b2625fe authored by Ryan Kavanagh's avatar Ryan Kavanagh

Imported Upstream version 1.6

parent dca062dd
11-10 1.6 release
10-27 pmk: automatic detection of tabbing and tab stop
10-26 pmk: fix off-by-one error in macro repetition
08-17 pmk: fix cursor position after xterm REGSCREEN
05-04 pmk: fix window destruction display error
04-11 pmk: fix line insert/delete bug
03-25 pmk: Haskell support
03-17 pmk: feature requests, line numbers
03-16 pmk: AOEUI_OVERLAP and comment highlighting
03-15 pmk: fix display issues on non-Apple Xterms, Linux console
03-11 pmk: optimize screen erasure again
02-01 pmk: fix raw hex character insertion (encode to UTF-8 unless -U)
2011
10-14 1.5 release
10-14 pmk: display debugging output, fix display errors
04-21 pmk: tweak colors, code cleanup, add display test
......
VERSION = 1.5
VERSION = 1.6
PACKAGE = aoeui-$(VERSION)
SRCS = main.c mem.c die.c display.c text.c file.c locus.c buffer.c \
undo.c utf8.c window.c util.c clip.c mode.c search.c \
child.c bookmark.c help.c find.c tags.c tab.c fold.c macro.c \
keyword.c
HDRS = all.h buffer.h child.h mode.h text.h locus.h utf8.h display.h \
window.h util.h clip.h macro.h mem.h die.h types.h
window.h util.h clip.h macro.h mem.h die.h types.h rgba.h
RELS = $(SRCS:.c=.o)
LIBS = -lutil
INST_DIR = $(DESTDIR)/usr
CFLAGS = -Wall -Wno-parentheses \
-Wpointer-arith -Wcast-align -Wwrite-strings -Wstrict-prototypes \
......@@ -21,19 +22,17 @@ STRINGIFY = sed 's/\\/\\\\/g;s/"/\\"/g;s/^/"/;s/$$/\\n"/'
default: optimized display-test aoeui.1 asdfg.1
aoeui: $(RELS) libs
$(CC) $(CFLAGS) -o $@ $(RELS) `cat libs`
aoeui: $(RELS)
$(CC) $(CFLAGS) -o $@ $(RELS) $(LIBS)
$(RELS): $(HDRS)
help.o: aoeui.help asdfg.help
aoeui.help: help.m4
m4 help.m4 | $(STRINGIFY) >$@
asdfg.help: help.m4
m4 -D ASDFG help.m4 | $(STRINGIFY) >$@
libs:
if [ .`uname -s` = .Linux ]; then echo -lutil; fi >$@
display-test: display-test.o display.o mem.o utf8.o libs
$(CC) $(CFLAGS) -o $@ display-test.o display.o mem.o utf8.o `cat libs`
display-test: display-test.o display.o mem.o utf8.o
$(CC) $(CFLAGS) -o $@ display-test.o display.o mem.o utf8.o
display-test.o: types.h utf8.h display.h
aoeui.1.gz: aoeui.1
......@@ -56,7 +55,7 @@ static:
debug: clean
$(MAKE) CFLAGS="-g -O0 -DDEBUG $(CFLAGS)" aoeui
profile: clean
$(MAKE) CFLAGS="-pg $(CFLAGS)" LIBS="$(LIBS) -pg" aoeui
$(MAKE) CFLAGS="-pg $(CFLAGS)" aoeui
TAGS: $(SRCS) $(HDRS)
$(CTAGS) -x $(SRCS) $(HDRS) >$@
......@@ -70,7 +69,7 @@ install: aoeui aoeui.1.gz asdfg.1.gz
install *.txt $(INST_DIR)/share/aoeui
install *.1.gz $(INST_DIR)/share/man/man1
clean:
rm -f *.o *.help libs core gmon.out screenlog.*
rm -f *.o *.help core gmon.out screenlog.*
clobber: clean
rm -f aoeui display-test unicode TAGS *.1 *.1.gz *.1.html
spotless: clobber
......
......@@ -23,7 +23,7 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#ifdef __APPLE__
#if defined __APPLE__ || defined BSD
# include <util.h>
#else
# include <pty.h>
......
......@@ -45,9 +45,9 @@ When run with no file name arguments,
displays a short command introduction and summary.
.P
.B AOEUI
can browse very large read-only files with quick start-up,
since original texts are memory-mapped from files and not
duplicated in memory until they are about to be modified.
can browse very large read-only files with quick start-up time,
since the original texts are memory-mapped from files and not
duplicated in memory unless they are about to be modified.
.SH OPTIONS
.TP
.B -k
......@@ -393,6 +393,8 @@ character code 0x01 inserted.)
.B ^Space^^
with a numeric argument, probably in hexadecimal, inserts the
specified Unicode character into the text in UTF-8 format.
If the text is not UTF-8, the character code is inserted directly
as a big-endian literal.
.TP
.B Tab
(or
......@@ -418,9 +420,6 @@ with a single TAB character.
(or
.BR ^Space^I )
will align the current line to the indentation of the previous one.
This is equivalent to
.B ^Space^cmd(D,X)
.BR Enter .
With a numeric argument of 1, it toggles the text's use of tab characters
for indentation.
With a numeric argument between 2 and 20, it will set the tab stop pitch.
......@@ -637,6 +636,19 @@ moves to another window, closing the old one.
.B ;
is not a control character)
creates a new anonymous text.
.TP
.B ^Space #
(note that the number sign
.B `
is not a contral character)
displays the current position's path name and line number.
.TP
.B ^Space ?
(note that the question mark
.B ?
is not a control character)
displays a new window with the built-in help summary of
commands.
.SH MACROS
.TP
.B ^Space^cmd(O,B)
......@@ -805,6 +817,9 @@ or
.B ^cmd(L,P)
and then
.BR ^cmd(Z,N) .
(Or set the environment variable
.B AOEUI_OVERLAP
to 50.)
.TP
.B *
To insert characters with a repeat count, type the characters into a new
......@@ -837,11 +852,25 @@ cause
use the title bar of the terminal emulator as a status indicator
that displays the path name of the active view and whether or not it has
been saved since last modified.
Unless the file is large, it also displays the line number of the cursor.
.TP
.B TERM_PROGRAM
will, if set to Apple_Terminal, make
.B AOEUI
work around Apple's Terminal emulator's behavioral differences from
standard Xterm.
.TP
.B AOEUI_WRITABLE
Default command used in the absence of the
.B -w
option.
.TP
.B AOEUI_OVERLAP
The percentage of overlap when scrolling a window up with
.B ^cmd(R,O)
or down with
.BR ^cmd(L,P) .
The default is 1, for minimal overlap.
.SH FILES
.TP
.IB file ~
......
......@@ -6,17 +6,12 @@
#include "types.h"
#include "utf8.h"
#include "display.h"
#define RED 0xff000000
#define GREEN 0x00ff0000
#define BLUE 0x0000ff00
#define WHITE 0xffffff00
#define BLACK 0
void die(const char *, ...);
Boolean_t multiplexor(Boolean_t);
static struct display *D;
static unsigned rows, columns;
static int rows, columns;
static void dfill(int row, int rows, int col, int cols,
int ch, rgba_t fgrgba, rgba_t bgrgba)
......@@ -42,8 +37,8 @@ static void dprint(int row, int col, rgba_t fgrgba, rgba_t bgrgba,
static void dpause(void)
{
int ch;
dfill(rows-1, 1, 0, columns, ' ', RED, WHITE);
dprint(rows-1, 0, RED, WHITE, "Hit Q to quit, or any other key to continue...");
dfill(rows-1, 1, 0, columns, ' ', RED_RGBA, WHITE_RGBA);
dprint(rows-1, 0, RED_RGBA, WHITE_RGBA, "Hit Q to quit, or any other key to continue...");
while ((ch = display_getch(D, 1)) == ERROR_CHANGED)
display_get_geometry(D, &rows, &columns);
if (ch == 'q' || ch == 'Q') {
......@@ -74,45 +69,58 @@ int main(void)
D = display_init();
display_get_geometry(D, &rows, &columns);
display_title(D, "display-test");
dprint(0, 0, BLACK, WHITE, "geometry: %d rows, %d columns", rows, columns);
dprint(0, 0, BLACK_RGBA, WHITE_RGBA, "geometry: %d rows, %d columns", rows, columns);
dprint(1, 0, DEFAULT_FGRGBA, DEFAULT_BGRGBA, "default foreground and background");
dprint(2, 0, WHITE, BLACK, "white foreground on black background");
dprint(2, 0, WHITE_RGBA, BLACK_RGBA, "white foreground on black background");
dprint(3, 0, BLACK_RGBA, WHITE_RGBA, "black foreground on white background");
dprint(4, 0, RED_RGBA, BLUE_RGBA, "red foreground on blue background");
dprint(5, 0, BLUE_RGBA, RED_RGBA, "blue foreground on red background");
dpause();
dfill(0, rows, 0, columns, '.', WHITE, BLACK);
dprint(0, 0, WHITE, BLACK, "filled with white dots on black");
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
dprint(0, 0, BLUE_RGBA, RED_RGBA, "filled with red dots on green");
dpause();
display_erase(D, 1, 0, rows-1, columns);
dfill(0, 1, 0, columns, ' ', WHITE, BLACK);
dprint(0, 0, WHITE, BLACK, "after display_erase()");
display_erase(D, 0, 0, rows, columns);
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after ERASEALL display_erase()");
dpause();
dfill(0, rows, 0, columns, '.', WHITE, BLACK);
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
display_erase(D, rows/2, 0, rows - rows/2, columns);
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after ERASETOEND display_erase()");
dpause();
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
display_erase(D, 1, columns/2, 1, columns);
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after ERASELINE display_erase()");
dpause();
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
display_erase(D, 1, 0, 1, columns/2);
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after ERASECOLS display_erase()");
dpause();
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
display_insert_lines(D, 2, 0, rows/2, rows-2, columns);
dfill(0, 1, 0, columns, ' ', WHITE, BLACK);
dprint(0, 0, WHITE, BLACK, "after display_insert_lines()");
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after display_insert_lines()");
dpause();
dfill(0, rows, 0, columns, '.', WHITE, BLACK);
dfill(rows-1, 1, 0, columns, '*', WHITE, BLACK);
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
dfill(rows-1, 1, 0, columns, '*', RED_RGBA, GREEN_RGBA);
display_delete_lines(D, 2, 0, rows/2, rows-2, columns);
dfill(0, 1, 0, columns, ' ', WHITE, BLACK);
dprint(0, 0, WHITE, BLACK, "after display_delete_lines()");
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after display_delete_lines()");
dpause();
dfill(0, rows, 0, columns, '.', WHITE, BLACK);
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
display_insert_spaces(D, 2, 0, columns/2, columns);
display_insert_spaces(D, 3, columns/2, columns - (columns/2), columns);
dfill(0, 1, 0, columns, ' ', WHITE, BLACK);
dprint(0, 0, WHITE, BLACK, "after display_insert_spaces()");
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after display_insert_spaces()");
dpause();
dfill(0, rows, 0, columns, '.', WHITE, BLACK);
dfill(0, rows, 0, columns, '.', RED_RGBA, GREEN_RGBA);
display_delete_chars(D, 2, 0, columns/2, columns);
display_delete_chars(D, 3, columns/2, columns - (columns/2), columns);
dfill(0, 1, 0, columns, ' ', WHITE, BLACK);
dprint(0, 0, WHITE, BLACK, "after display_delete_chars()");
dprint(0, 0, BLUE_RGBA, RED_RGBA, "after display_delete_chars()");
dpause();
display_end(D);
......
This diff is collapsed.
......@@ -2,21 +2,20 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include "rgba.h"
extern struct termios original_termios;
struct display;
typedef unsigned rgba_t;
#define DEFAULT_FGRGBA 0xff
#define DEFAULT_BGRGBA (~0)
struct display *display_init(void);
void display_reset(struct display *);
void display_end(struct display *);
void display_get_geometry(struct display *, unsigned *rows, unsigned *columns);
void display_title(struct display *, const char *);
void display_cursor(struct display *, unsigned row, unsigned column);
void display_put(struct display *, unsigned row, unsigned column,
void display_get_geometry(struct display *, int *rows, int *columns);
Boolean_t display_title(struct display *, const char *);
void display_cursor(struct display *, int row, int column);
Boolean_t display_cursor_color(struct display *, rgba_t rgba);
void display_put(struct display *, int row, int column,
Unicode_t unicode, rgba_t fgRGBA, rgba_t bgRGBA);
void display_beep(struct display *);
void display_sync(struct display *);
......@@ -29,15 +28,15 @@ void display_sync(struct display *);
Unicode_t display_getch(struct display *, Boolean_t block);
/* hints */
void display_erase(struct display *, unsigned row, unsigned column,
unsigned rows, unsigned columns);
void display_insert_spaces(struct display *, unsigned row, unsigned column,
unsigned spaces, unsigned columns);
void display_delete_chars(struct display *, unsigned row, unsigned column,
unsigned chars, unsigned columns);
void display_insert_lines(struct display *, unsigned row, unsigned column,
unsigned lines, unsigned rows, unsigned columns);
void display_delete_lines(struct display *, unsigned row, unsigned column,
unsigned lines, unsigned rows, unsigned columns);
void display_erase(struct display *, int row, int column,
int rows, int columns);
void display_insert_spaces(struct display *, int row, int column,
int spaces, int columns);
void display_delete_chars(struct display *, int row, int column,
int chars, int columns);
void display_insert_lines(struct display *, int row, int column,
int lines, int rows, int columns);
void display_delete_lines(struct display *, int row, int column,
int lines, int rows, int columns);
#endif
......@@ -5,6 +5,8 @@ enum utf8_mode utf8_mode = UTF8_AUTO;
const char *make_writable;
Boolean_t no_save_originals;
Boolean_t read_only;
unsigned default_tab_stop = 8; /* the only correct value :-) */
Boolean_t default_no_tabs;
const char *path_format(const char *path)
{
......@@ -131,6 +133,12 @@ static void scan(struct view *view)
size_t chlen, check;
Unicode_t ch, lastch = 0;
int crnl = 0, nl = 0;
Boolean_t any_tab = FALSE;
int tabstop = default_tab_stop;
/* Reset state */
view->text->flags &= ~(TEXT_NO_UTF8 | TEXT_CRNL | TEXT_NO_TABS);
view->text->tabstop = default_tab_stop;
if (utf8_mode == UTF8_NO)
view->text->flags |= TEXT_NO_UTF8;
......@@ -152,6 +160,20 @@ static void scan(struct view *view)
}
if (nl && crnl == nl)
view->text->flags |= TEXT_CRNL;
for (at = 0; at + chop < bytes; at = find_line_end(view, at) + 1) {
int spaces = 0;
while ((ch = view_unicode(view, at, &at)) == ' ')
spaces++;
if (ch == '\t')
any_tab = TRUE;
if (spaces > 1 && spaces < tabstop)
tabstop = spaces;
}
if (default_no_tabs || !any_tab) {
view->text->flags |= TEXT_NO_TABS;
view->text->tabstop = tabstop;
}
}
struct view *view_open(const char *path0)
......@@ -270,7 +292,7 @@ struct view *text_new(void)
sprintf(dir, "/tmp/aoeui-%s", me);
fd = try_dir(path, dir, gmt);
}
#ifndef __APPLE__
#if !defined __APPLE__ && !defined BSD
if (fd < 0 && (me = cuserid(NULL))) {
sprintf(dir, "/tmp/aoeui-%s", me);
fd = try_dir(path, dir, gmt);
......@@ -399,7 +421,7 @@ void text_preserve(struct text *text)
text->fd < 0 ||
!text->buffer)
return;
text->preserved = text->dirties;
text->preserved = ++text->dirties;
if (read_only)
return;
text_unfold_all(text);
......@@ -419,7 +441,7 @@ void text_preserve(struct text *text)
message("%s: modified since read into the "
"editor, changes may have been overwritten.",
path_format(text->path));
text->preserved = text->dirties;
text->preserved = ++text->dirties;
if (text->flags & TEXT_RDONLY && text->path && make_writable) {
char cmd[128];
int newfd;
......
......@@ -312,14 +312,47 @@ sposition_t find_corresponding_bracket(struct view *view, position_t offset)
position_t find_line_number(struct view *view, unsigned line)
{
position_t offset;
position_t offset, next, next2;
sposition_t fold_start = -1, fold_end = -1;
for (offset = 0;
offset < view->bytes;
offset = find_line_end(view, offset) + 1)
if (!--line)
if (line-- <= 1)
return 0;
for (offset = 0; offset < view->bytes; offset = next) {
Unicode_t ch = view_unicode(view, offset, &next);
if (offset >= fold_end)
fold_end = -1;
if (ch == '\n' && !--line)
break;
return offset;
if (fold_end < 0 && IS_FOLDED(ch)) {
size_t fbytes = FOLDED_BYTES(ch);
if (view_unicode(view, next + fbytes, &next2) ==
FOLD_END + fbytes) {
fold_start = offset;
fold_end = next2;
}
}
}
if (fold_end >= 0)
return fold_start;
return offset + 1;
}
unsigned current_line_number(struct view *view, position_t offset)
{
int line = 1;
position_t at;
unsigned last = '\n';
if (offset >= view->bytes)
offset = view->bytes;
for (at = 0; at < offset; at++) {
last = view_byte(view, at);
if (last == '\n')
line++;
}
if (at == view->bytes && last == '\n')
line--;
return line;
}
position_t find_row_bytes(struct view *view, position_t offset0,
......
......@@ -10,8 +10,8 @@ static const char *help[2] = {
struct view *view_help(void)
{
struct view *view = text_create("* Help *", TEXT_EDITOR);
view->text->flags &= ~TEXT_RDONLY;
view_insert(view, help[is_asdfg], 0, strlen(help[is_asdfg]));
locus_set(view, CURSOR, 0);
view->text->flags |= TEXT_RDONLY;
return view;
}
ifdef(`ASDFG',`define(`AOEUI',`asdfg')define(`cmd',`$2')',`define(`AOEUI',`aoeui')define(`cmd',`$1')')dnl
Welcome to AOEUI 1.5! Here are some clues to help you use the editor.
Welcome to AOEUI 1.6! Here are some clues to help you use the editor.
- The up/down/left/right "arrow" keys, page up/down keys, and Delete key
all work fine. You can use AOEUI as a simple notepad if you like.
......@@ -12,6 +12,7 @@ Welcome to AOEUI 1.5! Here are some clues to help you use the editor.
Command summary:
^Sp? display this help again
^Q pause the editor and return to the shell; return with "fg"
^Sp^Q save all files and quit
^Sp^\ quit immediately without saving
......@@ -49,7 +50,7 @@ Command summary:
^Sp^_ incremental regular expression search mode with POSIX regexps.
In search mode, use ^cmd(H,G) and ^cmd(T,H) to move from one
instance of the search target to another and any other command,
or Return, to resume editing.
or Return, to resume editing.
^cmd(X,E) open file named by selection in new window
insert current path as selection if none
......
......@@ -28,6 +28,143 @@ static const char *Cpp_keyword_list[] = {
"wchar_t", "while"
};
static const char *Haskell_keyword_list[] = {
"_", "case", "class", "data", "default", "deriving", "do", "else",
"foreign", "if", "import", "in", "infix", "infixl", "infixr",
"instance", "let", "module", "newtype", "of", "then", "type",
"where"
};
static sposition_t C_comment_start(struct view *view, position_t offset)
{
Unicode_t ch, nch = 0;
int newlines = 0;
while (IS_UNICODE((ch = view_char_prior(view, offset, &offset)))) {
if (ch == '\n') {
if (newlines++ == 100)
break;
} else if (ch == '/') {
if (nch == '*')
return offset;
if (!newlines && nch == '/')
return offset;
} else if (ch == '*' && nch == '/')
break;
nch = ch;
}
return -1;
}
static sposition_t C_comment_end(struct view *view, position_t offset)
{
Unicode_t ch, lch = 0;
position_t next;
if (view_char(view, offset, &offset) != '/')
return -1;
ch = view_char(view, offset, &offset);
if (ch == '/')
return find_line_end(view, offset);
if (ch != '*')
return -1;
while (IS_UNICODE((ch = view_char(view, offset, &next)))) {
if (lch == '*' && ch == '/')
return offset;
lch = ch;
offset = next;
}
return -1;
}
static sposition_t C_string_end(struct view *view, position_t offset)
{
Unicode_t ch, lch = 0, ch0 = view_char(view, offset, &offset);
position_t next;
if (ch0 != '\'' && ch0 != '"')
return -1;
while (IS_UNICODE((ch = view_char(view, offset, &next)))) {
if (ch == ch0 && lch != '\\')
return offset;
if (ch == '\n')
break;
if (ch == '\\' && lch == '\\')
lch = 0;
else
lch = ch;
offset = next;
}
return -1;
}
static sposition_t Haskell_comment_start(struct view *view, position_t offset)
{
Unicode_t ch, nch = 0;
int newlines = 0;
while (IS_UNICODE((ch = view_char_prior(view, offset, &offset)))) {
if (ch == '\n') {
if (newlines++ == 100)
break;
} else if (ch == '{' && nch == '-')
return offset;
else if (ch == '-') {
if (!newlines && nch == '-')
return offset;
if (nch == '}')
break;
}
nch = ch;
}
return -1;
}
static sposition_t Haskell_comment_end(struct view *view, position_t offset)
{
Unicode_t ch, lch = 0;
position_t next;
ch = view_char(view, offset, &offset);
if (ch != '-' && ch != '{')
return -1;
if (view_char(view, offset, &offset) != '-')
return -1;
if (ch == '-')
return find_line_end(view, offset);
while (IS_UNICODE((ch = view_char(view, offset, &next)))) {
if (lch == '-' && ch == '}')
return offset;
lch = ch;
offset = next;
}
return -1;
}
static sposition_t Haskell_string_end(struct view *view, position_t offset)
{
position_t next;
Unicode_t ch, lch = 0, ch0 = view_char(view, offset, &next);
if (ch0 == '\'') {
ch = view_char_prior(view, offset, NULL);
if (isalnum(ch) || ch == '_' || ch == '\'')
return -1;
} else if (ch0 != '"')
return -1;
while (IS_UNICODE((ch = view_char(view, offset = next, &next)))) {
if (ch == ch0 && lch != '\\')
return offset;
if (ch == '\n')
break;
if (ch == '\\' && lch == '\\')
lch = 0;
else
lch = ch;
}
return -1;
}
#define KW(lang) { sizeof lang##_keyword_list / sizeof *lang##_keyword_list, \
lang##_keyword_list }
......@@ -35,13 +172,18 @@ static struct file_keywords {
const char *suffix;
struct keywords keywords;
const char *brackets;
sposition_t (*comment_start)(struct view *, position_t);
sposition_t (*comment_end)(struct view *, position_t);
sposition_t (*string_end)(struct view *, position_t);
} kwmap [] = {
{ ".c", KW(C), "()[]{}" },
{ ".C", KW(C), "()[]{}" },
{ ".cc", KW(Cpp), "()[]{}" },
{ ".cpp", KW(Cpp), "()[]{}" },
{ ".cxx", KW(Cpp), "()[]{}" },
{ ".h", KW(Cpp), "()[]{}" },
{ ".c", KW(C), "()[]{}", C_comment_start, C_comment_end, C_string_end },
{ ".C", KW(C), "()[]{}", C_comment_start, C_comment_end, C_string_end },
{ ".cc", KW(Cpp), "()[]{}", C_comment_start, C_comment_end, C_string_end },
{ ".cpp", KW(Cpp), "()[]{}", C_comment_start, C_comment_end, C_string_end },
{ ".cxx", KW(Cpp), "()[]{}", C_comment_start, C_comment_end, C_string_end },
{ ".h", KW(Cpp), "()[]{}", C_comment_start, C_comment_end, C_string_end },
{ ".hs", KW(Haskell), "()[]{}", Haskell_comment_start, Haskell_comment_end,
Haskell_string_end },
{ ".html", { 0, NULL }, "<>" },
{ }
};
......@@ -57,8 +199,12 @@ void keyword_init(struct text *text)
!strcmp(text->path + pathlen - suffixlen,
kwmap[j].suffix)) {
text->brackets = kwmap[j].brackets;
if (!no_keywords)
if (!no_keywords) {
text->keywords = &kwmap[j].keywords;
text->comment_start = kwmap[j].comment_start;
text->comment_end = kwmap[j].comment_end;
text->string_end = kwmap[j].string_end;
}
return;
}
}
......@@ -76,7 +222,7 @@ Boolean_t is_keyword(struct view *view, position_t offset)
if (!view->text->keywords)
return FALSE;
bytes = find_id_end(view, offset + 1) - offset;
bytes = find_id_end(view, offset) - offset;
if (view_raw(view, &word, offset, bytes) < bytes)
return FALSE;
for (n = view->text->keywords->count,
......
......@@ -102,7 +102,7 @@ Unicode_t macro_getch(void)
playing->bytes - playing->at);
ch = utf8_unicode(p, n = utf8_length(p, n));
if ((playing->at += n) == playing->bytes)
if (playing->repeat-- > 0)
if (playing->repeat-- > 1)
playing->at = 0;
else
playing = playing->suspended;
......
/* Copyright 2007, 2008 Peter Klausler. See COPYING for license. */
#include "all.h"
static void sighandler(int signo)
......
......@@ -145,33 +145,32 @@ static Boolean_t funckey(struct view *view, int Fk)
}
static position_t self_insert(struct view *view, Unicode_t ch,
position_t mark, position_t old_cursor,
Boolean_t literal_unicode)
position_t mark, position_t old_cursor)
{
char cbuf[8];
char cbuf[16], *p = cbuf;
position_t cursor = old_cursor;
size_t len = 0;
if (mark != UNSET && mark > cursor) {
cursor = cut(view, 1);
mark = UNSET;
}
if (ch == '\n' && view->text->flags & TEXT_CRNL) {
view_insert(view, "\r\n", cursor, 2);
cursor += 2;
} else if (ch <= 0x100 &&
(!literal_unicode ||
view->text->flags & TEXT_NO_UTF8)) {
cbuf[0] = ch;
view_insert(view, cbuf, cursor++, 1);
memcpy(p, "\r\n", len = 2);
} else if (view->text->flags & TEXT_NO_UTF8) {
for (p = cbuf + sizeof cbuf; ch; ch >>= 8)
*--p = ch, len++;
if (!len)
*--p = 0, len++;
} else {
size_t len = unicode_utf8(cbuf, ch);
view_insert(view, cbuf, cursor, len);
cursor += len;
len = unicode_utf8(p, ch);
}
<