[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-devel] Changes to qemacs/qe.c
From: |
Charlie Gordon |
Subject: |
[Qemacs-devel] Changes to qemacs/qe.c |
Date: |
Mon, 09 May 2005 05:10:43 -0400 |
Index: qemacs/qe.c
diff -u qemacs/qe.c:1.19 qemacs/qe.c:1.20
--- qemacs/qe.c:1.19 Mon May 9 06:21:49 2005
+++ qemacs/qe.c Mon May 9 09:10:37 2005
@@ -65,6 +65,8 @@
static int screen_width = 0;
static int screen_height = 0;
EditBuffer *trace_buffer;
+int no_init_file;
+const char *user_option;
/* mode handling */
@@ -1263,14 +1265,17 @@
}
/* XXX: may be better to move it into qe_key_process() */
-static void quote_grab_key(void *opaque, int key)
+static void quote_key(void *opaque, int key)
{
+ /* CG: should pass s as opaque */
QEmacsState *qs = &qe_state;
EditState *s;
s = qs->active_window;
if (!s)
return;
+
+ /* CG: why not insert special keys as well? */
if (!KEY_SPECIAL(key) ||
(key >= 0 && key <= 31)) {
do_char(s, key);
@@ -1282,7 +1287,7 @@
void do_quote(EditState *s)
{
- qe_grab_keys(quote_grab_key, NULL);
+ qe_grab_keys(quote_key, NULL);
put_status(s, "Quote: ");
}
@@ -1326,6 +1331,12 @@
put_status(s, "Mark set");
}
+void do_mark_whole_buffer(EditState *s)
+{
+ s->b->mark = 0;
+ s->offset = s->b->total_size;
+}
+
EditBuffer *new_yank_buffer(void)
{
QEmacsState *qs = &qe_state;
@@ -1672,6 +1683,48 @@
s->offset = eb_goto_char(s->b, pos);
}
+void do_count_lines(EditState *s)
+{
+ int total_lines, line_num, mark_line, col_num;
+
+ eb_get_pos(s->b, &total_lines, &col_num, s->b->total_size);
+ eb_get_pos(s->b, &mark_line, &col_num, s->b->mark);
+ eb_get_pos(s->b, &line_num, &col_num, s->offset);
+
+ put_status(s, "%d lines, point on line %d, %d lines in block",
+ total_lines, line_num + 1, abs(line_num - mark_line));
+}
+
+void do_what_cursor_position(EditState *s)
+{
+ char buf[128];
+ int line_num, col_num;
+ int c, pos, offset1;
+
+ buf[0] = '\0';
+ if (s->offset < s->b->total_size) {
+ c = eb_nextc(s->b, s->offset, &offset1);
+ pos = snprintf(buf, sizeof(buf), "char: ");
+ if (c < 32 || c == 127) {
+ pos += snprintf(buf + pos, sizeof(buf) - pos, "^%c ",
+ (c + '@') & 127);
+ } else
+ if (c < 127 || c >= 160) {
+ buf[pos++] = '\'';
+ pos = utf8_encode(buf + pos, c) - buf;
+ buf[pos++] = '\'';
+ buf[pos++] = ' ';
+ }
+ pos += snprintf(buf + pos, sizeof(buf) - pos, "(%#3o %d 0x%2x) ",
+ c, c, c);
+ /* CG: should display buffer bytes if non ascii */
+ }
+ eb_get_pos(s->b, &line_num, &col_num, s->offset);
+ put_status(s, "%spoint=%d column=%d mark=%d size=%d region=%d",
+ buf, s->offset, col_num, s->b->mark, s->b->total_size,
+ abs(s->offset - s->b->mark));
+}
+
void do_set_tab_width(EditState *s, int tab_width)
{
if (tab_width > 1)
@@ -3175,6 +3228,16 @@
void exec_command(EditState *s, CmdDef *d, int argval)
{
ExecCmdState *es;
+ const char *argdesc;
+
+ argdesc = d->name + strlen(d->name) + 1;
+ if (*argdesc == '*') {
+ argdesc++;
+ if (s->b->flags & BF_READONLY) {
+ put_status(s, "Buffer is read only");
+ return;
+ }
+ }
es = malloc(sizeof(ExecCmdState));
if (!es)
@@ -3189,7 +3252,7 @@
es->args[es->nb_args] = (void *)s;
es->args_type[es->nb_args] = CMD_ARG_WINDOW;
es->nb_args++;
- es->ptype = d->name + strlen(d->name) + 1;
+ es->ptype = argdesc;
parse_args(es);
}
@@ -3293,6 +3356,7 @@
qs->ec.function = d->name;
call_func(d->action.func, es->nb_args, es->args, es->args_type);
/* CG: Should test for abort condition */
+ /* CG: Should follow qs->active_window ? */
} while (--rep_count > 0);
qs->last_cmd_func = d->action.func;
@@ -3635,16 +3699,23 @@
macro_add_key(key);
}
+again:
if (c->grab_key_cb) {
c->grab_key_cb(c->grab_key_opaque, key);
- return;
+ /* allow key_grabber to quit and unget last key */
+ if (c->grab_key_cb || qs->ungot_key == -1)
+ return;
+ key = qs->ungot_key;
+ qs->ungot_key = -1;
}
+ /* safety check */
if (c->nb_keys >= MAX_KEYS) {
qe_key_init();
c->describe_key = 0;
return;
}
+
c->keys[c->nb_keys++] = key;
s = qs->active_window;
if (!s->minibuf) {
@@ -3700,6 +3771,8 @@
}
}
if (kd) {
+ /* horrible kludge to pass key as intrinsic argument */
+ /* CG: should have an argument type for key */
kd->cmd->val = (void *)key;
goto exec_cmd;
}
@@ -3742,6 +3815,12 @@
qe_key_init();
edit_display(qs);
dpy_flush(&global_screen);
+ /* CG: should move ungot key handling to generic event dispatch */
+ if (qs->ungot_key != -1) {
+ key = qs->ungot_key;
+ qs->ungot_key = -1;
+ goto again;
+ }
return;
}
}
@@ -4020,19 +4099,17 @@
char path[MAX_FILENAME_SIZE];
char file[MAX_FILENAME_SIZE];
char filename[MAX_FILENAME_SIZE];
- char *base;
+ const char *base, *ext;
int len;
- pstrcpy(path, sizeof(path), input);
- base = path + (basename(path) - path);
- pstrcpy(file, sizeof(file), base);
+ splitpath(path, sizeof(path), file, sizeof(file), input);
pstrcat(file, sizeof(file), "*");
- *base = '\0';
+
ffs = find_file_open(*path ? path : ".", file);
while (find_file_next(ffs, filename, sizeof(filename)) == 0) {
struct stat sb;
- base = filename + (basename(filename) - filename);
+ base = basename(filename);
/* ignore . and .. to force direct match if
* single entry in directory */
if (!strcmp(base, ".") || !strcmp(base, ".."))
@@ -4042,18 +4119,16 @@
if (!len || base[len - 1] == '~')
continue;
/* ignore known output file extensions */
- if (strfind(file_completion_ignore_extensions,
- extension(filename), 1)) {
+ ext = extension(base);
+ if (*ext && strfind(file_completion_ignore_extensions, ext + 1, 1))
continue;
- }
- makepath(file, sizeof(file), path, base);
+
/* stat the file to find out if it's a directory.
* In that case add a slash to speed up typing long paths
*/
- stat(file, &sb);
- if (S_ISDIR(sb.st_mode))
- pstrcat(path, sizeof(path), "/");
- add_string(cs, file);
+ if (!stat(filename, &sb) && S_ISDIR(sb.st_mode))
+ pstrcat(filename, sizeof(filename), "/");
+ add_string(cs, filename);
}
find_file_close(ffs);
@@ -4581,6 +4656,11 @@
s->b->flags ^= BF_READONLY;
}
+void do_not_modified(EditState *s)
+{
+ s->b->modified = 0;
+}
+
static void kill_buffer_confirm_cb(void *opaque, char *reply);
static void kill_buffer_noconfirm(EditBuffer *b);
@@ -4695,7 +4775,8 @@
return selected_mode;
}
-static void do_load1(EditState *s, const char *filename1, int kill_buffer)
+static void do_load1(EditState *s, const char *filename1,
+ int kill_buffer, int load_resource)
{
char buf[1025];
char filename[MAX_FILENAME_SIZE];
@@ -4706,15 +4787,20 @@
FILE *f;
struct stat st;
+ if (load_resource) {
+ if (find_resource_file(filename, sizeof(filename), filename1))
+ return;
+ } else {
+ /* compute full name */
+ canonize_absolute_path(filename, sizeof(filename), filename1);
+ }
+
if (kill_buffer) {
/* CG: this behaviour is not correct */
/* CG: should have a direct primitive */
do_kill_buffer(s, s->b->name);
}
- /* compute full name */
- canonize_absolute_path(filename, sizeof(filename), filename1);
-
/* see if file is already edited */
b = eb_find_file(filename);
if (b) {
@@ -4818,12 +4904,17 @@
void do_load(EditState *s, const char *filename)
{
- do_load1(s, filename, 0);
+ do_load1(s, filename, 0, 0);
}
void do_find_alternate_file(EditState *s, const char *filename)
{
- do_load1(s, filename, 1);
+ do_load1(s, filename, 1, 0);
+}
+
+void do_load_file_from_path(EditState *s, const char *filename)
+{
+ do_load1(s, filename, 0, 1);
}
void do_insert_file(EditState *s, const char *filename)
@@ -6414,6 +6505,7 @@
/* search for command */
d = qe_find_cmd(cmd);
if (!d) {
+ /* CG: should handle variables */
err = -1;
put_status(s, "Unknown command '%s'", cmd);
continue;
@@ -6425,6 +6517,14 @@
/* construct argument type list */
r = d->name + strlen(d->name) + 1;
+ if (*r == '*') {
+ r++;
+ if (s->b->flags & BF_READONLY) {
+ put_status(s, "Buffer is read only");
+ continue;
+ }
+ }
+
for (;;) {
unsigned char arg_type;
int ret;
@@ -6526,6 +6626,8 @@
qs->ec.function = d->name;
call_func(d->action.func, nb_args, args, args_type);
+ if (qs->active_window)
+ s = qs->active_window;
continue;
fail:
@@ -6551,9 +6653,7 @@
ffs = find_file_open(qs->res_path, "config");
if (!ffs)
return;
- for (;;) {
- if (find_file_next(ffs, filename, sizeof(filename)) != 0)
- break;
+ while (find_file_next(ffs, filename, sizeof(filename)) == 0) {
parse_config_file(e, filename);
}
find_file_close(ffs);
@@ -6586,6 +6686,8 @@
void qe_register_cmd_line_options(CmdOptionDef *table)
{
CmdOptionDef **pp, *p;
+
+ /* link command line options table at end of list */
pp = &first_cmd_options;
while (*pp != NULL) {
p = *pp;
@@ -6598,44 +6700,146 @@
/******************************************************/
-static void show_help(void)
+static void show_version(void)
+{
+ printf("QEmacs version " QE_VERSION "\n"
+ "Copyright (c) 2000-2003 Fabrice Bellard\n"
+ "QEmacs comes with ABSOLUTELY NO WARRANTY.\n"
+ "You may redistribute copies of QEmacs\n"
+ "under the terms of the GNU Lesser General Public License.\n");
+ exit(1);
+}
+
+static void show_usage(void)
{
CmdOptionDef *p;
- printf("QEmacs version " QE_VERSION ", Copyright (c) 2000-2003 Fabrice
Bellard\n");
+ int pos;
+
+ printf("Usage: qe [OPTIONS] [filename ...]\n"
+ "\n"
+ "Options:\n"
+ "\n");
- /* generate usage */
- printf("usage: qe");
+ /* print all registered command line options */
p = first_cmd_options;
while (p != NULL) {
while (p->name != NULL) {
- printf(" [-%s", p->name);
+ pos = printf("--%s", p->name);
+ if (p->shortname)
+ pos += printf(", -%s", p->shortname);
if (p->flags & CMD_OPT_ARG)
- printf(" %s", p->argname);
- printf("]");
+ pos += printf(" %s", p->argname);
+ if (pos < 24)
+ printf("%*s", pos - 24, "");
+ printf("%s\n", p->help);
p++;
}
p = p->u.next;
}
- printf(" [filename...]\n\n");
+ printf("\n"
+ "Report bugs to address@hidden First, please see the Bugs\n"
+ "section of the QEmacs manual or the file BUGS.\n");
+ exit(1);
+}
- /* generate help */
- p = first_cmd_options;
- while (p != NULL) {
- while (p->name != NULL) {
- printf("-%s", p->name);
- if (p->flags & CMD_OPT_ARG)
- printf(" %s", p->argname);
- printf(": %s\n", p->help);
- p++;
+int parse_command_line(int argc, char **argv)
+{
+ int optind;
+
+ optind = 1;
+ for (;;) {
+ const char *r, *r1, *r2, *optarg;
+ CmdOptionDef *p;
+
+ if (optind >= argc)
+ break;
+ r = argv[optind];
+ /* stop before first non option */
+ if (r[0] != '-')
+ break;
+ optind++;
+
+ r2 = r1 = r + 1;
+ if (r2[0] == '-') {
+ r2++;
+ /* stop after `--' marker */
+ if (r2[0] == '\0')
+ break;
}
- p = p->u.next;
+
+ p = first_cmd_options;
+ while (p != NULL) {
+ while (p->name != NULL) {
+ if (!strcmp(p->name, r2) ||
+ (p->shortname && !strcmp(p->shortname, r1))) {
+ if (p->flags & CMD_OPT_ARG) {
+ if (optind >= argc) {
+ put_status(NULL,
+ "cmdline argument expected -- %s", r);
+ goto next_cmd;
+ }
+ optarg = argv[optind++];
+ } else {
+ optarg = NULL;
+ }
+ if (p->flags & CMD_OPT_BOOL) {
+ *p->u.int_ptr = 1;
+ } else if (p->flags & CMD_OPT_STRING) {
+ *p->u.string_ptr = optarg;
+ } else if (p->flags & CMD_OPT_INT) {
+ *p->u.int_ptr = strtol(optarg, NULL, 0);
+ } else if (p->flags & CMD_OPT_ARG) {
+ p->u.func_arg(optarg);
+ } else {
+ p->u.func_noarg();
+ }
+ goto next_cmd;
+ }
+ p++;
+ }
+ p = p->u.next;
+ }
+ put_status(NULL, "unknown cmdline option '%s'", r);
+ next_cmd: ;
+ }
+ return optind;
+}
+
+void set_user_option(const char *user)
+{
+ QEmacsState *qs = &qe_state;
+ char path[1024];
+ const char *home_path;
+
+ user_option = user;
+ /* compute resources path */
+ pstrcpy(qs->res_path, sizeof(qs->res_path),
+ CONFIG_QE_PREFIX "/share/qe:" CONFIG_QE_PREFIX "/lib/qe:"
+ "/usr/share/qe:/usr/lib/qe");
+ if (user) {
+ /* use ~USER/.qe instead of ~/.qe */
+ /* CG: should get user homedir */
+ snprintf(path, sizeof(path), "/home/%s", user);
+ home_path = path;
+ } else {
+ home_path = getenv("HOME");
+ }
+ if (home_path) {
+ pstrcat(qs->res_path, sizeof(qs->res_path), ":");
+ pstrcat(qs->res_path, sizeof(qs->res_path), home_path);
+ pstrcat(qs->res_path, sizeof(qs->res_path), "/.qe");
}
- exit(1);
}
static CmdOptionDef cmd_options[] = {
- { "h", NULL, 0, "show help",
- {func_noarg: show_help}},
+ { "help", "h", NULL, 0, "display this help message and exit",
+ {func_noarg: show_usage}},
+ { "no-init-file", "q", NULL, CMD_OPT_BOOL, "do not load config files",
+ {int_ptr: &no_init_file}},
+ { "user", "u", "USER", CMD_OPT_ARG, "load ~USER/.qe/config instead of your
own",
+ {func_arg: set_user_option}},
+ { "version", "V", NULL, 0, "display version information and exit",
+ {func_noarg: show_version}},
{ NULL },
};
@@ -6801,6 +7005,7 @@
module_hex_init(); /* hex.c(351) */
module_list_init(); /* list.c(102) */
module_tty_init(); /* tty.c(567) */
+#ifndef CONFIG_TINY
module_charset_more_init(); /* charsetmore.c(324) */
module_unihex_init(); /* unihex.c(184) */
module_c_init(); /* clang.c(567) */
@@ -6809,16 +7014,19 @@
module_bufed_init(); /* bufed.c(197) */
module_shell_init(); /* shell.c(922) */
module_dired_init(); /* dired.c(369) */
+#endif
#ifdef CONFIG_WIN32
module_win32_init(); /* win32.c(504) */
#endif
#ifdef CONFIG_X11
module_x11_init(); /* x11.c(1704) */
#endif
+#ifndef CONFIG_TINY
#ifdef CONFIG_HTML
module_html_init(); /* html.c(894) */
module_docbook_init(); /* docbook.c(53) */
#endif
+#endif
#ifdef CONFIG_FFMPEG
module_video_init(); /* video.c(979) */
module_image_init(); /* image.c(844) */
@@ -6885,22 +7093,14 @@
EditBuffer *b;
QEDisplay *dpy;
int i, optind, is_player;
- char *home_path;
- /* compute resources path */
- strcpy(qs->res_path,
- CONFIG_QE_PREFIX "/share/qe:" CONFIG_QE_PREFIX "/lib/qe:"
- "/usr/share/qe:/usr/lib/qe");
- home_path = getenv("HOME");
- if (home_path) {
- pstrcat(qs->res_path, sizeof(qs->res_path), ":");
- pstrcat(qs->res_path, sizeof(qs->res_path), home_path);
- pstrcat(qs->res_path, sizeof(qs->res_path), "/.qe");
- }
+ qs->ec.function = "qe-init";
qs->macro_key_index = -1; /* no macro executing */
qs->ungot_key = -1; /* no unget key */
- qs->ec.function = "qe-init";
+ /* setup resource path */
+ set_user_option(NULL);
+
eb_init();
charset_init();
init_input_methods();
@@ -6909,6 +7109,7 @@
/* init basic modules */
qe_register_mode(&text_mode);
qe_register_cmd_table(basic_commands, NULL);
+ qe_register_cmd_line_options(cmd_options);
register_completion("command", command_completion);
register_completion("charset", charset_completion);
@@ -6919,8 +7120,6 @@
minibuffer_init();
less_mode_init();
-
- qe_register_cmd_line_options(cmd_options);
/* init all external modules in link order */
init_all_modules();
@@ -6962,54 +7161,11 @@
dummy_dpy.dpy_init(&global_screen, screen_width, screen_height);
/* handle options */
- optind = 1;
- for (;;) {
- const char *r, *optarg;
- CmdOptionDef *p;
-
- if (optind >= argc)
- break;
- r = argv[optind];
- if (r[0] != '-')
- break;
- optind++;
-
- p = first_cmd_options;
- while (p != NULL) {
- while (p->name != NULL) {
- if (!strcmp(p->name, r + 1)) {
- if (p->flags & CMD_OPT_ARG) {
- if (optind >= argc) {
- put_status(NULL,
- "cmdline argument expected -- %s", r);
- goto next_cmd;
- }
- optarg = argv[optind++];
- } else {
- optarg = NULL;
- }
- if (p->flags & CMD_OPT_BOOL) {
- *p->u.int_ptr = 1;
- } else if (p->flags & CMD_OPT_STRING) {
- *p->u.string_ptr = optarg;
- } else if (p->flags & CMD_OPT_INT) {
- *p->u.int_ptr = atoi(optarg);
- } else if (p->flags & CMD_OPT_ARG) {
- p->u.func_arg(optarg);
- } else {
- p->u.func_noarg();
- }
- goto next_cmd;
- }
- p++;
- }
- p = p->u.next;
- }
- put_status(NULL, "unknown cmdline option -- %s", r);
- next_cmd: ;
- }
+ optind = parse_command_line(argc, argv);
- parse_config(s, NULL);
+ /* load config file unless command line option given */
+ if (!no_init_file)
+ parse_config(s, NULL);
qe_key_init();
@@ -7033,12 +7189,15 @@
/* load file(s) */
for (i = optind; i < argc; i++) {
do_load(s, argv[i]);
+ /* CG: handle +linenumber */
}
+#ifndef CONFIG_TINY
if (is_player && optind >= argc) {
/* if player, go to directory mode by default if no file selected */
do_dired(s);
}
+#endif
put_status(s, "QEmacs %s - Press F1 for help", QE_VERSION);
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/08
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/08
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/08
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/08
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/08
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/08
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/09
- [Qemacs-devel] Changes to qemacs/qe.c,
Charlie Gordon <=
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/10
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/11
- [Qemacs-devel] Changes to qemacs/qe.c, Charlie Gordon, 2005/05/13