From 7868f2b05cce00c6fc8fb4d25fadddc5b8c8f727 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Mon, 31 Mar 2008 20:35:31 +0000 Subject: [PATCH] added command find-file-other-window added module extra.c for commands in full version added command compare_windows added command delete_horizontal_space added command show_date_and_time moved block navigation and kill commands from clang.c to extras.c --- Makefile | 2 + clang.c | 156 --------------------------- extras.c | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++ qe.c | 11 ++ qe.h | 7 ++ qeconfig.h | 3 + 6 files changed, 333 insertions(+), 156 deletions(-) create mode 100644 extras.c diff --git a/Makefile b/Makefile index 0a041e3..3ca418e 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,8 @@ TARGETS+= qe$(EXE) tqe$(EXE) kmaps ligatures OBJS=qe.o charset.o buffer.o input.o display.o util.o hex.o list.o cutils.o TOBJS=tqe.o charset.o buffer.o input.o display.o util.o hex.o list.o cutils.o +OBJS+= extras.o + ifdef CONFIG_PNG_OUTPUT HTMLTOPPM_LIBS+= -lpng endif diff --git a/clang.c b/clang.c index e6b5abb..fec0ba6 100644 --- a/clang.c +++ b/clang.c @@ -592,147 +592,6 @@ static void do_c_forward_preprocessor(EditState *s, int dir) { } -/* forward / backward block */ -#define MAX_LEVEL 20 - -/* CG: move this to generic command */ -static void do_c_forward_block(EditState *s, int dir) -{ - unsigned int buf[MAX_BUF_SIZE]; - char balance[MAX_LEVEL]; - int line_num, col_num, offset, offset1, len, pos, style, c, c1, level; - - eb_get_pos(s->b, &line_num, &col_num, s->offset); - offset = eb_goto_bol2(s->b, s->offset, &pos); - offset1 = offset; - len = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num); - style = buf[pos] >> STYLE_SHIFT; - level = 0; - - if (dir < 0) { - for (;;) { - if (pos == 0) { - if (offset <= 0) - break; - line_num--; - offset = eb_prev_line(s->b, offset); - offset1 = offset; - pos = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num); - continue; - } - c = buf[--pos]; - if (style != c >> STYLE_SHIFT) { - if (style == 0) - continue; - style = 0; - if ((c >> STYLE_SHIFT) != 0) - continue; - } - switch (c &= CHAR_MASK) { - case ')': - c1 = '('; - goto push; - case ']': - c1 = '['; - goto push; - case '}': - c1 = '{'; - push: - if (level < MAX_LEVEL) { - balance[level] = c1; - } - level++; - break; - case '(': - case '[': - case '{': - if (level > 0) { - --level; - if (balance[level] != c) { - put_status(s, "Unmatched delimiter"); - return; - } - if (level <= 0) - goto the_end; - } - break; - } - } - } else { - for (;;) { - if (pos >= len) { - /* Should simplify with get_colorized_line updating - * offset - */ - line_num++; - pos = 0; - offset = eb_next_line(s->b, offset); - if (offset >= s->b->total_size) - break; - offset1 = offset; - len = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num); - continue; - } - c = buf[pos]; - pos++; - if (style != c >> STYLE_SHIFT) { - if (style == 0) - continue; - style = 0; - if ((c >> STYLE_SHIFT) != 0) - continue; - } - switch (c &= CHAR_MASK) { - case '(': - c1 = ')'; - goto push1; - case '[': - c1 = ']'; - goto push1; - case '{': - c1 = '}'; - push1: - if (level < MAX_LEVEL) { - balance[level] = c1; - } - level++; - break; - case ')': - case ']': - case '}': - if (level > 0) { - --level; - if (balance[level] != c) { - put_status(s, "Unmatched delimiter"); - return; - } - if (level <= 0) - goto the_end; - } - break; - } - } - } -the_end: - while (pos > 0) { - eb_nextc(s->b, offset, &offset); - pos--; - } - s->offset = offset; -} - -/* CG: move this to generic command */ -static void do_c_kill_block(EditState *s, int dir) -{ - int start = s->offset; - - if (s->b->flags & BF_READONLY) - return; - - do_c_forward_block(s, dir); - do_kill(s, start, s->offset, dir); -} - static int c_mode_probe(ModeProbeData *p) { /* currently, only use the file extension */ @@ -784,20 +643,6 @@ static CmdDef c_commands[] = { CMD_DEF_END, }; -/* Non C mode specific commands */ -static CmdDef c_global_commands[] = { - CMDV( KEY_META(KEY_CTRL('b')), KEY_NONE, - "c-backward-block", do_c_forward_block, ESi, -1, "*v") - /* should map to KEY_META + KEY_CTRL_RIGHT */ - CMDV( KEY_META(KEY_CTRL('f')), KEY_NONE, - "c-forward-block", do_c_forward_block, ESi, 1, "*v") - CMDV( KEY_META(KEY_CTRL('k')), KEY_NONE, - "c-kill-block", do_c_kill_block, ESi, 1, "*v") - CMDV( KEY_ESC, KEY_DELETE, - "c-backward-kill-block", do_c_kill_block, ESi, -1, "*v") - CMD_DEF_END, -}; - static ModeDef c_mode; static int c_init(void) @@ -810,7 +655,6 @@ static int c_init(void) qe_register_mode(&c_mode); qe_register_cmd_table(c_commands, &c_mode); - qe_register_cmd_table(c_global_commands, NULL); return 0; } diff --git a/extras.c b/extras.c new file mode 100644 index 0000000..0445d82 --- /dev/null +++ b/extras.c @@ -0,0 +1,310 @@ +/* + * QEmacs, extra commands non full version + * + * Copyright (c) 2000-2008 Charlie Gordon. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "qe.h" +#include "qfribidi.h" + +void do_compare_windows(EditState *s, int argval) +{ + QEmacsState *qs = s->qe_state; + EditState *s1; + EditState *s2; + int offset1, offset2, size1, size2, ch1, ch2; + int tries; + + s1 = s; + /* Should use same internal function as for next_window */ + if (s1->next_window) + s2 = s1->next_window; + else + s2 = qs->first_window; + + if (argval) + qs->ignore_spaces ^= 1; + + if (s1 == s2) + return; + + size1 = s1->b->total_size; + size2 = s2->b->total_size; + + if (qs->last_cmd_func == do_compare_windows + && (eb_nextc(s1->b, s1->offset, &offset1) != + eb_nextc(s2->b, s2->offset, &offset2))) { + /* Try to resync: just skip in parallel */ + s1->offset = offset1; + s2->offset = offset2; + } + + for (tries = 0;;) { + + if (++tries >= 100000) { + tries = 0; + //if (check_input()) + // return; + } + + if (s1->offset >= size1) { + offset1 = s1->offset; + ch1 = EOF; + } else { + ch1 = eb_nextc(s1->b, s1->offset, &offset1); + } + if (s2->offset >= size2) { + offset2 = s2->offset; + ch2 = EOF; + } else { + ch2 = eb_nextc(s2->b, s2->offset, &offset2); + } + if (ch1 != ch2) { + if (qs->ignore_spaces) { + /* UTF-8 issue */ + if (qe_isspace(ch1)) { + s1->offset = offset1; + continue; + } + if (qe_isspace(ch2)) { + s2->offset = offset2; + continue; + } + } + if (ch1 == EOF || ch2 == EOF) + put_status(s, "Extra characters"); + else + put_status(s, "Difference: %c <-> %c", ch1, ch2); + break; + } + if (ch1 != EOF) { + s1->offset = offset1; + s2->offset = offset2; + continue; + } + put_status(s, "No difference"); + break; + } +} + +void do_delete_horizontal_space(EditState *s) +{ + int from, to, offset, ch; + + from = to = s->offset; + while (from > 0) { + ch = eb_prevc(s->b, from, &offset); + if (!qe_isblank(ch)) + break; + from = offset; + } + while (to < s->b->total_size) { + ch = eb_nextc(s->b, to, &offset); + if (!qe_isblank(ch)) + break; + to = offset; + } + s->offset = eb_delete_range(s->b, from, to); +} + +void do_show_date_and_time(EditState *s, int argval) +{ + time_t t = argval; + + if (t == 0) + time(&t); + + put_status(s, "%.24s", ctime(&t)); +} + +/* forward / backward block */ +#define MAX_BUF_SIZE 512 +#define MAX_LEVEL 20 + +/* CG: move this to generic command */ +static void do_forward_block(EditState *s, int dir) +{ + unsigned int buf[MAX_BUF_SIZE]; + char balance[MAX_LEVEL]; + int line_num, col_num, offset, offset1, len, pos, style, c, c1, level; + + eb_get_pos(s->b, &line_num, &col_num, s->offset); + offset = eb_goto_bol2(s->b, s->offset, &pos); + offset1 = offset; + len = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num); + style = buf[pos] >> STYLE_SHIFT; + level = 0; + + if (dir < 0) { + for (;;) { + if (pos == 0) { + if (offset <= 0) + break; + line_num--; + offset = eb_prev_line(s->b, offset); + offset1 = offset; + pos = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num); + continue; + } + c = buf[--pos]; + if (style != c >> STYLE_SHIFT) { + if (style == 0) + continue; + style = 0; + if ((c >> STYLE_SHIFT) != 0) + continue; + } + switch (c &= CHAR_MASK) { + case ')': + c1 = '('; + goto push; + case ']': + c1 = '['; + goto push; + case '}': + c1 = '{'; + push: + if (level < MAX_LEVEL) { + balance[level] = c1; + } + level++; + break; + case '(': + case '[': + case '{': + if (level > 0) { + --level; + if (balance[level] != c) { + put_status(s, "Unmatched delimiter"); + return; + } + if (level <= 0) + goto the_end; + } + break; + } + } + } else { + for (;;) { + if (pos >= len) { + /* Should simplify with get_colorized_line updating + * offset + */ + line_num++; + pos = 0; + offset = eb_next_line(s->b, offset); + if (offset >= s->b->total_size) + break; + offset1 = offset; + len = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num); + continue; + } + c = buf[pos]; + pos++; + if (style != c >> STYLE_SHIFT) { + if (style == 0) + continue; + style = 0; + if ((c >> STYLE_SHIFT) != 0) + continue; + } + switch (c &= CHAR_MASK) { + case '(': + c1 = ')'; + goto push1; + case '[': + c1 = ']'; + goto push1; + case '{': + c1 = '}'; + push1: + if (level < MAX_LEVEL) { + balance[level] = c1; + } + level++; + break; + case ')': + case ']': + case '}': + if (level > 0) { + --level; + if (balance[level] != c) { + put_status(s, "Unmatched delimiter"); + return; + } + if (level <= 0) + goto the_end; + } + break; + } + } + } +the_end: + while (pos > 0) { + eb_nextc(s->b, offset, &offset); + pos--; + } + s->offset = offset; +} + +/* CG: move this to generic command */ +static void do_kill_block(EditState *s, int dir) +{ + int start = s->offset; + + if (s->b->flags & BF_READONLY) + return; + + do_forward_block(s, dir); + do_kill(s, start, s->offset, dir); +} + +static CmdDef extra_commands[] = { + CMD_( KEY_META('='), KEY_NONE, + "compare-windows", do_compare_windows, ESi, "ui" ) + CMD_( KEY_META('\\'), KEY_NONE, + "delete-horizontal-space", do_delete_horizontal_space, ES, "*") + CMD_( KEY_CTRLX('t'), KEY_NONE, + "show-date-and-time", do_show_date_and_time, ESi, "ui") + + /* Should map to KEY_META + KEY_CTRL_LEFT */ + CMDV( KEY_META(KEY_CTRL('b')), KEY_NONE, + "backward-block", do_forward_block, ESi, -1, "*v") + /* Should map to KEY_META + KEY_CTRL_RIGHT */ + CMDV( KEY_META(KEY_CTRL('f')), KEY_NONE, + "forward-block", do_forward_block, ESi, 1, "*v") + CMDV( KEY_ESC, KEY_DELETE, + "backward-kill-block", do_kill_block, ESi, -1, "*v") + CMDV( KEY_META(KEY_CTRL('k')), KEY_NONE, + "kill-block", do_kill_block, ESi, 1, "*v") + + CMD_DEF_END, +}; + +static int extras_init(void) +{ + int key; + + qe_register_cmd_table(extra_commands, NULL); + for (key = KEY_META('0'); key <= KEY_META('9'); key++) + qe_register_binding(key, "universal-argument", NULL); + return 0; +} + +qe_module_init(extras_init); diff --git a/qe.c b/qe.c index 2be7658..2347431 100644 --- a/qe.c +++ b/qe.c @@ -5279,6 +5279,7 @@ static ModeDef *probe_mode(EditState *s, int mode, const uint8_t *buf, return selected_mode; } +/* Should take bits from enumeration instead of booleans */ static void do_load1(EditState *s, const char *filename1, int kill_buffer, int load_resource) { @@ -5433,6 +5434,14 @@ void do_find_file(EditState *s, const char *filename) do_load1(s, filename, 0, 0); } +void do_find_file_other_window(EditState *s, const char *filename) +{ + QEmacsState *qs = s->qe_state; + + do_split_window(s, 0); + do_load1(qs->active_window, filename, 0, 0); +} + void do_find_alternate_file(EditState *s, const char *filename) { do_load1(s, filename, 1, 0); @@ -7069,6 +7078,8 @@ int parse_config_file(EditState *s, const char *filename) skip = 0; err = 0; line_num = 0; + /* Should parse whole config file in a single read, or load it via + * a buffer */ for (;;) { if (fgets(line, sizeof(line), f) == NULL) break; diff --git a/qe.h b/qe.h index af50f6a..8ec28f8 100644 --- a/qe.h +++ b/qe.h @@ -1517,6 +1517,7 @@ void edit_set_mode(EditState *s, ModeDef *m, ModeSavedData *saved_data); /* loading files */ void do_exit_qemacs(EditState *s, int argval); void do_find_file(EditState *s, const char *filename); +void do_find_file_other_window(EditState *s, const char *filename); void do_load_from_path(EditState *s, const char *filename); void do_switch_to_buffer(EditState *s, const char *bufname); void do_break(EditState *s); @@ -1685,6 +1686,12 @@ int parse_command_line(int argc, char **argv); void set_user_option(const char *user); void set_tty_charset(const char *name); +/* extras.c */ + +void do_compare_windows(EditState *s, int argval); +void do_delete_horizontal_space(EditState *s); +void do_show_date_and_time(EditState *s, int argval); + /* hex.c */ void hex_write_char(EditState *s, int key); diff --git a/qeconfig.h b/qeconfig.h index a5d0dad..2e1d7b0 100644 --- a/qeconfig.h +++ b/qeconfig.h @@ -111,6 +111,9 @@ static CmdDef basic_commands[] = { CMD_( KEY_CTRLX(KEY_CTRL('f')), KEY_NONE, "find-file", do_find_file, ESs, "s{Find file: }[file]|file|") /* u? */ + CMD_( KEY_CTRL('x'), KEY_META('f'), + "find-file-other-window", do_find_file_other_window, ESs, + "s{Find file: }[file]|file|") /* u? */ CMD_( KEY_CTRLX(KEY_CTRL('v')), KEY_NONE, "find-alternate-file", do_find_alternate_file, ESs, "s{Find alternate file: }[file]|file|") /* u? */