[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs bufed.c dired.c extras.c list.c makemode...
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs bufed.c dired.c extras.c list.c makemode... |
Date: |
Mon, 10 Feb 2014 21:21:41 +0000 |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 14/02/10 21:21:40
Modified files:
. : bufed.c dired.c extras.c list.c makemode.c qe.c
qe.h qeconfig.h shell.c
Log message:
Improve mode selection and mode specific command safety
* add set-auto-mode() to (re)select best mode for buffer
* add set-next-mode() on M-m to cycle appropriate buffer modes
* add set-previous-mode()
* add default_mode and saved_mode in buffers to improve mode switching
* add dired mode probing and store st_mode in buffer to detect
directories
* add charset, eol_type and buffer in ModeProbeData
* clean mode selection and window buffer attachment (needs more work)
* compute sorted list of appropriate modes in probe_mode
* convert charset and eol_type in mode_probe
* add signatures in buffer priv_data to perform save casts
* move BufedState to b->priv_data, protect mode specific functions
add bufed_mode_probe function, cycling through modes comes back to
bufed mode
* move DiredState to b->priv_data, protect mode specific functions
add dired_mode_probe function, cycling through modes comes back to
dired mode
* add heading line in dired buffer with directory spec
* protect shell-mode specific functions.
* restart shell in shell() command if exited
* some cosmetics changes (remove useless __unused__, missing messages
...)
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/bufed.c?cvsroot=qemacs&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/qemacs/dired.c?cvsroot=qemacs&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/qemacs/list.c?cvsroot=qemacs&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/qemacs/makemode.c?cvsroot=qemacs&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.149&r2=1.150
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.140&r2=1.141
http://cvs.savannah.gnu.org/viewcvs/qemacs/qeconfig.h?cvsroot=qemacs&r1=1.46&r2=1.47
http://cvs.savannah.gnu.org/viewcvs/qemacs/shell.c?cvsroot=qemacs&r1=1.84&r2=1.85
Patches:
Index: bufed.c
===================================================================
RCS file: /sources/qemacs/qemacs/bufed.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- bufed.c 15 Jan 2014 19:44:24 -0000 1.24
+++ bufed.c 10 Feb 2014 21:21:39 -0000 1.25
@@ -25,7 +25,10 @@
BUFED_ALL_VISIBLE = 1
};
+static int bufed_signature;
+
typedef struct BufedState {
+ void *signature;
StringArray items;
int flags;
int last_index;
@@ -33,32 +36,47 @@
static ModeDef bufed_mode;
+static BufedState *bufed_get_state(EditState *s)
+{
+ BufedState *bs = s->b->priv_data;
+
+ if (bs && bs->signature == &bufed_signature)
+ return bs;
+
+ put_status(s, "Not a bufed buffer");
+ return NULL;
+}
+
static void build_bufed_list(EditState *s)
{
QEmacsState *qs = s->qe_state;
EditBuffer *b;
- BufedState *hs;
+ BufedState *bs;
int last_index = list_get_pos(s);
- int i, flags;
+ int i;
- hs = s->mode_data;
+ if (!(bs = bufed_get_state(s)))
+ return;
- free_strings(&hs->items);
+ free_strings(&bs->items);
for (b = qs->first_buffer; b != NULL; b = b->next) {
- if (!(b->flags & BF_SYSTEM) || (hs->flags & BUFED_ALL_VISIBLE))
- add_string(&hs->items, b->name);
+ if (!(b->flags & BF_SYSTEM) || (bs->flags & BUFED_ALL_VISIBLE))
+ add_string(&bs->items, b->name);
}
/* build buffer */
b = s->b;
- flags = b->flags;
b->flags &= ~BF_READONLY;
eb_delete(b, 0, b->total_size);
- for (i = 0; i < hs->items.nb_items; i++) {
- EditBuffer *b1 = eb_find(hs->items.items[i]->str);
+
+ for (i = 0; i < bs->items.nb_items; i++) {
+ EditBuffer *b1 = eb_find(bs->items.items[i]->str);
char flags[4];
char *flagp = flags;
+ if (i == last_index) {
+ s->offset = b->total_size;
+ }
if (b1) {
if (b1->modified)
*flagp++ = '*';
@@ -66,14 +84,20 @@
*flagp++ = '%';
}
*flagp = '\0';
- eb_printf(b, " %-2s%-16s", flags, hs->items.items[i]->str);
+ eb_printf(b, " %-2s%-16s", flags, bs->items.items[i]->str);
if (b1) {
char path[MAX_FILENAME_SIZE];
const char *mode_name;
EditState *e;
+ if (b1->saved_mode) {
+ mode_name = b1->saved_mode->name;
+ } else
if (b1->saved_data) {
mode_name = b1->saved_data->mode->name;
+ } else
+ if (b1->default_mode) {
+ mode_name = b1->default_mode->name;
} else {
mode_name = "none";
for (e = qs->first_window; e != NULL; e = e->next_window) {
@@ -93,15 +117,18 @@
}
eb_printf(b, "\n");
}
- b->flags = flags;
- s->offset = eb_goto_pos(s->b, last_index, 0);
+ b->modified = 0;
+ b->flags |= BF_READONLY;
}
static EditBuffer *bufed_get_buffer(EditState *s)
{
- BufedState *bs = s->mode_data;
+ BufedState *bs;
int index;
+ if (!(bs = bufed_get_state(s)))
+ return NULL;
+
index = list_get_pos(s);
if (index < 0 || index >= bs->items.nb_items)
return NULL;
@@ -111,12 +138,15 @@
static void bufed_select(EditState *s, int temp)
{
- BufedState *bs = s->mode_data;
+ BufedState *bs;
StringItem *item;
EditBuffer *b;
EditState *e;
int index;
+ if (!(bs = bufed_get_state(s)))
+ return;
+
index = list_get_pos(s);
if (index < 0 || index >= bs->items.nb_items)
return;
@@ -137,7 +167,7 @@
return;
}
if (e) {
- /* delete dired window */
+ /* delete bufed window */
do_delete_window(s, 1);
switch_to_buffer(e, b);
} else {
@@ -175,13 +205,20 @@
static void bufed_kill_item(void *opaque, StringItem *item)
{
EditState *s = opaque;
+
+ /* XXX: avoid killing buffer list by mistake */
+ if (strcmp(s->b->name, item->str))
do_kill_buffer(s, item->str);
}
static void bufed_kill_buffer(EditState *s)
{
- BufedState *hs = s->mode_data;
- string_selection_iterate(&hs->items, list_get_pos(s),
+ BufedState *bs;
+
+ if (!(bs = bufed_get_state(s)))
+ return;
+
+ string_selection_iterate(&bs->items, list_get_pos(s),
bufed_kill_item, s);
build_bufed_list(s);
}
@@ -209,7 +246,9 @@
e = insert_window_left(b, width, WF_MODELINE);
edit_set_mode(e, &bufed_mode);
- bs = e->mode_data;
+ if (!(bs = bufed_get_state(e)))
+ return;
+
if (argval != NO_ARG) {
bs->flags |= BUFED_ALL_VISIBLE;
build_bufed_list(e);
@@ -257,7 +296,10 @@
static void bufed_refresh(EditState *s, int toggle)
{
- BufedState *bs = s->mode_data;
+ BufedState *bs;
+
+ if (!(bs = bufed_get_state(s)))
+ return;
if (toggle)
bs->flags ^= BUFED_ALL_VISIBLE;
@@ -274,21 +316,57 @@
bufed_select(s, 1);
}
+static int bufed_mode_probe(ModeDef *mode, ModeProbeData *p)
+{
+ if (p->b->priv_data) {
+ BufedState *bs = p->b->priv_data;
+ if (bs->signature == &bufed_signature)
+ return 95;
+ else
+ return 0;
+ }
+ return 0;
+}
+
+static void bufed_close(EditBuffer *b)
+{
+ BufedState *bs = b->priv_data;
+
+ if (bs) {
+ free_strings(&bs->items);
+ }
+
+ qe_free(&b->priv_data);
+}
+
static int bufed_mode_init(EditState *s, ModeSavedData *saved_data)
{
+ BufedState *bs;
+
list_mode.mode_init(s, saved_data);
- build_bufed_list(s);
+ if (s->b->priv_data) {
+ bs = s->b->priv_data;
+ if (bs->signature != &bufed_signature)
+ return -1;
+ } else {
+ /* XXX: should be allocated by buffer_load API */
+ bs = qe_mallocz(BufedState);
+ if (!bs)
+ return -1;
+
+ bs->signature = &bufed_signature;
+ s->b->priv_data = bs;
+ s->b->close = bufed_close;
+ /* XXX: should be built by buffer_load API */
+ build_bufed_list(s);
+ }
return 0;
}
static void bufed_mode_close(EditState *s)
{
- BufedState *bs = s->mode_data;
-
- free_strings(&bs->items);
-
list_mode.mode_close(s);
}
@@ -315,7 +393,7 @@
"previous-line", do_up_down, -1)
CMD1( 'r', 'g',
"bufed-refresh", bufed_refresh, 0)
- CMD0( 'k', KEY_F8,
+ CMD0( 'k', 'd',
"bufed-kill-buffer", bufed_kill_buffer)
CMD_DEF_END,
};
@@ -332,7 +410,7 @@
/* CG: assuming list_mode already initialized ? */
memcpy(&bufed_mode, &list_mode, sizeof(ModeDef));
bufed_mode.name = "bufed";
- bufed_mode.instance_size = sizeof(BufedState);
+ bufed_mode.mode_probe = bufed_mode_probe;
bufed_mode.mode_init = bufed_mode_init;
bufed_mode.mode_close = bufed_mode_close;
/* CG: not a good idea, display hook has side effect on layout */
Index: dired.c
===================================================================
RCS file: /sources/qemacs/qemacs/dired.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- dired.c 5 Feb 2014 00:56:49 -0000 1.36
+++ dired.c 10 Feb 2014 21:21:39 -0000 1.37
@@ -21,7 +21,7 @@
#include "qe.h"
-enum { DIRED_HEADER = 0 };
+enum { DIRED_HEADER = 1 };
enum {
DIRED_SORT_NAME = 1,
@@ -33,7 +33,10 @@
DIRED_SORT_DESCENDING = 32,
};
+static int dired_signature;
+
typedef struct DiredState {
+ void *signature;
StringArray items;
int sort_mode; /* DIRED_SORT_GROUP | DIRED_SORT_NAME */
int last_index;
@@ -55,12 +58,11 @@
return list_get_pos(s) - DIRED_HEADER;
}
-static void dired_free(EditState *s)
+static void dired_free(DiredState *ds)
{
- DiredState *ds = s->mode_data;
+ if (ds) {
int i;
- /* free opaques */
for (i = 0; i < ds->items.nb_items; i++) {
qe_free(&ds->items.items[i]->opaque);
}
@@ -68,44 +70,58 @@
free_strings(&ds->items);
ds->last_index = -1;
+ }
+}
- /* reset cursor position */
- s->offset_top = 0;
- s->offset = 0;
+static DiredState *dired_get_state(EditState *s)
+{
+ DiredState *ds = s->b->priv_data;
+
+ if (ds && ds->signature == &dired_signature)
+ return ds;
+
+ put_status(s, "Not a dired buffer");
+ return NULL;
}
static char *dired_get_filename(EditState *s,
char *buf, int buf_size, int index)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
const StringItem *item;
const DiredItem *dip;
+ if (!(ds = dired_get_state(s)))
+ return NULL;
+
/* CG: assuming buf_size > 0 */
buf[0] = '\0';
if (index < 0)
index = dired_get_index(s);
- if (index < 0 || index >= hs->items.nb_items)
+ if (index < 0 || index >= ds->items.nb_items)
return NULL;
- item = hs->items.items[index];
+ item = ds->items.items[index];
dip = item->opaque;
/* build filename */
/* CG: Should canonicalize path */
- return makepath(buf, buf_size, hs->path, dip->name);
+ return makepath(buf, buf_size, ds->path, dip->name);
}
static int dired_find_target(EditState *s, const char *target)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
char filename[MAX_FILENAME_SIZE];
int i;
if (target) {
- for (i = 0; i < hs->items.nb_items; i++) {
+ if (!(ds = dired_get_state(s)))
+ return -1;
+
+ for (i = 0; i < ds->items.nb_items; i++) {
if (dired_get_filename(s, filename, sizeof(filename), i)
&& strequal(filename, target)) {
return i;
@@ -159,34 +175,38 @@
/* select current item */
static void dired_sort_list(EditState *s)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
StringItem *item, *cur_item;
DiredItem *dip;
EditBuffer *b;
int index, i;
+ if (!(ds = dired_get_state(s)))
+ return;
+
index = dired_get_index(s);
cur_item = NULL;
- if (index >= 0 && index < hs->items.nb_items)
- cur_item = hs->items.items[index];
+ if (index >= 0 && index < ds->items.nb_items)
+ cur_item = ds->items.items[index];
- qsort(hs->items.items, hs->items.nb_items,
+ qsort(ds->items.items, ds->items.nb_items,
sizeof(StringItem *), dired_sort_func);
/* construct list buffer */
b = s->b;
b->flags &= ~BF_READONLY;
eb_delete(b, 0, b->total_size);
- s->offset_top = 0;
- s->offset = 0;
- if (DIRED_HEADER)
- eb_printf(b, " %s:\n", hs->path);
- for (i = 0; i < hs->items.nb_items; i++) {
- item = hs->items.items[i];
+
+ if (DIRED_HEADER) {
+ eb_printf(b, " Directory of %s:\n", ds->path);
+ }
+
+ for (i = 0; i < ds->items.nb_items; i++) {
+ item = ds->items.items[i];
dip = item->opaque;
dip->offset = b->total_size;
if (item == cur_item) {
- hs->last_index = i;
+ ds->last_index = i;
s->offset = b->total_size;
}
eb_printf(b, "%c %s\n", dip->mark, item->str);
@@ -197,17 +217,19 @@
static void dired_mark(EditState *s, int mark)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
const StringItem *item;
DiredItem *dip;
unsigned char ch;
int index;
- index = dired_get_index(s);
+ if (!(ds = dired_get_state(s)))
+ return;
- if (index < 0 || index >= hs->items.nb_items)
+ index = dired_get_index(s);
+ if (index < 0 || index >= ds->items.nb_items)
return;
- item = hs->items.items[index];
+ item = ds->items.items[index];
dip = item->opaque;
ch = dip->mark = mark;
@@ -221,41 +243,44 @@
static void dired_sort(EditState *s, const char *sort_order)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
const char *p;
+ if (!(ds = dired_get_state(s)))
+ return;
+
for (p = sort_order; *p; p++) {
switch (qe_tolower((unsigned char)*p)) {
case 'n': /* name */
- hs->sort_mode &= ~DIRED_SORT_MASK;
- hs->sort_mode |= DIRED_SORT_NAME;
+ ds->sort_mode &= ~DIRED_SORT_MASK;
+ ds->sort_mode |= DIRED_SORT_NAME;
break;
case 'e': /* extension */
- hs->sort_mode &= ~DIRED_SORT_MASK;
- hs->sort_mode |= DIRED_SORT_EXTENSION;
+ ds->sort_mode &= ~DIRED_SORT_MASK;
+ ds->sort_mode |= DIRED_SORT_EXTENSION;
break;
case 's': /* size */
- hs->sort_mode &= ~DIRED_SORT_MASK;
- hs->sort_mode |= DIRED_SORT_SIZE;
+ ds->sort_mode &= ~DIRED_SORT_MASK;
+ ds->sort_mode |= DIRED_SORT_SIZE;
break;
case 'd': /* direct */
- hs->sort_mode &= ~DIRED_SORT_MASK;
- hs->sort_mode |= DIRED_SORT_DATE;
+ ds->sort_mode &= ~DIRED_SORT_MASK;
+ ds->sort_mode |= DIRED_SORT_DATE;
break;
case 'u': /* ungroup */
- hs->sort_mode &= ~DIRED_SORT_GROUP;
+ ds->sort_mode &= ~DIRED_SORT_GROUP;
break;
case 'g': /* group */
- hs->sort_mode |= DIRED_SORT_GROUP;
+ ds->sort_mode |= DIRED_SORT_GROUP;
break;
case '+': /* ascending */
- hs->sort_mode &= ~DIRED_SORT_DESCENDING;
+ ds->sort_mode &= ~DIRED_SORT_DESCENDING;
break;
case '-': /* descending */
- hs->sort_mode |= DIRED_SORT_DESCENDING;
+ ds->sort_mode |= DIRED_SORT_DESCENDING;
break;
case 'r': /* reverse */
- hs->sort_mode ^= DIRED_SORT_DESCENDING;
+ ds->sort_mode ^= DIRED_SORT_DESCENDING;
break;
}
}
@@ -267,7 +292,7 @@
static void dired_build_list(EditState *s, const char *path,
const char *target)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
FindFileState *ffst;
char filename[MAX_FILENAME_SIZE];
char line[1024], buf[1024];
@@ -276,15 +301,18 @@
int ct, len, index;
StringItem *item;
+ if (!(ds = dired_get_state(s)))
+ return;
+
/* free previous list, if any */
- dired_free(s);
+ dired_free(ds);
/* CG: should make absolute ? */
- canonicalize_path(hs->path, sizeof(hs->path), path);
- eb_set_filename(s->b, hs->path);
+ canonicalize_path(ds->path, sizeof(ds->path), path);
+ eb_set_filename(s->b, ds->path);
s->b->flags |= BF_DIRED;
- ffst = find_file_open(hs->path, "*");
+ ffst = find_file_open(ds->path, "*");
/* Should scan directory/filespec before computing lines to adjust
* filename gutter width
*/
@@ -351,13 +379,13 @@
}
pstrcat(line, sizeof(line), buf);
- item = add_string(&hs->items, line);
+ item = add_string(&ds->items, line);
if (item) {
DiredItem *dip;
int plen = strlen(p);
dip = qe_malloc_hack(DiredItem, plen);
- dip->state = hs;
+ dip->state = ds;
dip->st_mode = st.st_mode;
dip->size = st.st_size;
dip->mtime = st.st_mtime;
@@ -371,7 +399,7 @@
dired_sort_list(s);
index = dired_find_target(s, target);
- s->offset = eb_goto_pos(s->b, index + DIRED_HEADER, 0);
+ s->offset = eb_goto_pos(s->b, max(index, 0) + DIRED_HEADER, 0);
}
/* select current item */
@@ -443,31 +471,40 @@
static void dired_parent(EditState *s)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
char target[MAX_FILENAME_SIZE];
char filename[MAX_FILENAME_SIZE];
- pstrcpy(target, sizeof(target), hs->path);
- makepath(filename, sizeof(filename), hs->path, "..");
+ if (!(ds = dired_get_state(s)))
+ return;
+
+ pstrcpy(target, sizeof(target), ds->path);
+ makepath(filename, sizeof(filename), ds->path, "..");
dired_build_list(s, filename, target);
}
static void dired_refresh(EditState *s)
{
- DiredState *hs = s->mode_data;
+ DiredState *ds;
char target[MAX_FILENAME_SIZE];
+ if (!(ds = dired_get_state(s)))
+ return;
+
dired_get_filename(s, target, sizeof(target), -1);
- dired_build_list(s, hs->path, target);
+ dired_build_list(s, ds->path, target);
}
static void dired_display_hook(EditState *s)
{
- DiredState *ds = s->mode_data;
+ DiredState *ds;
char filename[MAX_FILENAME_SIZE];
int index;
+ if (!(ds = dired_get_state(s)))
+ return;
+
/* Prevent point from going beyond list */
if (s->offset && s->offset == s->b->total_size)
do_up_down(s, -1);
@@ -486,34 +523,67 @@
}
}
+static void dired_close(EditBuffer *b)
+{
+ DiredState *ds = b->priv_data;
+
+ dired_free(ds);
+ qe_free(&b->priv_data);
+}
+
static int dired_mode_init(EditState *s, ModeSavedData *saved_data)
{
- DiredState *hs;
+ DiredState *ds;
list_mode.mode_init(s, saved_data);
- /* XXX: File system charset should be detected automatically */
- eb_set_charset(s->b, &charset_utf8, s->b->eol_type);
+ if (s->b->priv_data) {
+ ds = s->b->priv_data;
+ if (ds->signature != &dired_signature)
+ return -1;
+ } else {
+ /* XXX: should be allocated by buffer_load API */
+ ds = qe_mallocz(DiredState);
+ if (!ds)
+ return -1;
- hs = s->mode_data;
- hs->sort_mode = DIRED_SORT_GROUP | DIRED_SORT_NAME;
+ ds->signature = &dired_signature;
+ ds->sort_mode = DIRED_SORT_GROUP | DIRED_SORT_NAME;
+ s->b->priv_data = ds;
+ s->b->close = dired_close;
+
+ /* XXX: should be built by buffer_load API */
dired_build_list(s, s->b->filename, NULL);
+ }
+
+ /* XXX: File system charset should be detected automatically */
+ /* XXX: If file system charset is not utf8, eb_printf will fail */
+ eb_set_charset(s->b, &charset_utf8, s->b->eol_type);
return 0;
}
static void dired_mode_close(EditState *s)
{
- dired_free(s);
list_mode.mode_close(s);
}
/* can only apply dired mode on directories */
static int dired_mode_probe(ModeDef *mode, ModeProbeData *p)
{
- if (S_ISDIR(p->st_mode))
+ if (p->b->priv_data) {
+ DiredState *ds = p->b->priv_data;
+ if (ds->signature != &dired_signature)
+ return 0;
+ else
return 100;
+ }
+ if (S_ISDIR(p->st_mode))
+ return 95;
+ else
+ if (strchr(p->real_filename, '*') || strchr(p->real_filename, '?'))
+ return 90;
else
return 0;
}
@@ -557,7 +627,7 @@
edit_set_mode(e, &dired_mode);
index = dired_find_target(e, target);
- e->offset = eb_goto_pos(e->b, index + DIRED_HEADER, 0);
+ e->offset = eb_goto_pos(e->b, max(index, 0) + DIRED_HEADER, 0);
/* modify active window */
qs->active_window = e;
@@ -621,7 +691,6 @@
/* CG: assuming list_mode already initialized ? */
memcpy(&dired_mode, &list_mode, sizeof(ModeDef));
dired_mode.name = "dired";
- dired_mode.instance_size = sizeof(DiredState);
dired_mode.mode_probe = dired_mode_probe;
dired_mode.mode_init = dired_mode_init;
dired_mode.mode_close = dired_mode_close;
Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- extras.c 10 Feb 2014 20:33:01 -0000 1.20
+++ extras.c 10 Feb 2014 21:21:40 -0000 1.21
@@ -764,6 +764,9 @@
eb_printf(b1, " eol_type: %d %s\n", b->eol_type, buf);
eb_printf(b1, " charset: %s (bytes=%d, shift=%d)\n",
b->charset->name, b->char_bytes, b->char_shift);
+ eb_printf(b1, "default_mode: %s, saved_mode: %s\n",
+ b->default_mode ? b->default_mode->name : "",
+ b->saved_mode ? b->saved_mode->name : "");
desc = buf_init(&descbuf, buf, countof(buf));
if (b->flags & BF_SAVELOG)
Index: list.c
===================================================================
RCS file: /sources/qemacs/qemacs/list.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- list.c 15 Jan 2014 15:54:27 -0000 1.11
+++ list.c 10 Feb 2014 21:21:40 -0000 1.12
@@ -79,7 +79,7 @@
text_move_up_down(s, 1);
}
-static int list_mode_init(EditState *s, __unused__ ModeSavedData *saved_data)
+static int list_mode_init(EditState *s, ModeSavedData *saved_data)
{
text_mode_init(s, saved_data);
Index: makemode.c
===================================================================
RCS file: /sources/qemacs/qemacs/makemode.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- makemode.c 6 Feb 2014 00:22:18 -0000 1.9
+++ makemode.c 10 Feb 2014 21:21:40 -0000 1.10
@@ -161,7 +161,7 @@
static ModeDef makefile_mode;
-static int makefile_mode_init(EditState *s, __unused__ ModeSavedData
*saved_data)
+static int makefile_mode_init(EditState *s, ModeSavedData *saved_data)
{
text_mode_init(s, saved_data);
s->b->tab_width = 8;
Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.149
retrieving revision 1.150
diff -u -b -r1.149 -r1.150
--- qe.c 10 Feb 2014 20:29:26 -0000 1.149
+++ qe.c 10 Feb 2014 21:21:40 -0000 1.150
@@ -1543,6 +1543,8 @@
eb_delete(s->b, p1, len);
s->offset = p1;
qs->this_cmd_func = (CmdFunc)do_append_next_kill;
+ } else {
+ put_status(s, "Region copied");
}
selection_activate(qs->screen);
}
@@ -1729,6 +1731,8 @@
b->data_type->buffer_close(b);
b->data = NULL;
b->data_type = &raw_data_type;
+ eb_delete(b, 0, b->total_size);
+ b->modified = 0;
}
}
}
@@ -1790,6 +1794,7 @@
{
ModeDef *m;
+ /* XXX: should check if mode is appropriate */
m = find_mode(name);
if (m)
edit_set_mode(s, m);
@@ -1797,51 +1802,6 @@
put_status(s, "No mode %s", name);
}
-/* CG: should have commands to cycle modes and charsets */
-#if 0
-/* cycle modes appropriate for buffer */
-void do_next_mode(EditState *s)
-{
- QEmacsState *qs = s->qe_state;
- char fname[MAX_FILENAME_SIZE];
- u8 buf[1024];
- ModeProbeData probe_data;
- int size;
- ModeDef *m, *m0;
-
- size = eb_read(s->b, 0, buf, sizeof(buf));
- probe_data.buf = buf;
- probe_data.buf_size = size;
- probe_data.real_filename = s->b->filename;
- probe_data.total_size = s->b->total_size;
- probe_data.st_mode = 0644;
- probe_data.filename = reduce_filename(fname, sizeof(fname),
- get_basename(s->b->filename));
- /* CG: should pass EditState? QEmacsState ? */
-
- /* Should cycle modes in order of decreasing scores */
- m = m0 = s->mode;
- for (;;) {
- m = m->next;
- if (!m)
- m = qs->first_mode;
- if (m == m0)
- break;
- if (!m->mode_probe
- || m->mode_probe(m, &probe_data) > 0) {
- edit_set_mode(s, m);
- break;
- }
- }
-}
-
-void do_cycle_charset(EditState *s)
-{
- if (++s->b->charset == CHARSET_NB)
- s->b->charset = 0;
-}
-#endif
-
QECharset *read_charset(EditState *s, const char *charset_str,
EOLType *eol_typep)
{
@@ -4669,13 +4629,16 @@
QEmacsState *qs = s->qe_state;
EditBuffer *b1;
EditState *e;
- ModeSavedData *saved_data, **psaved_data;
+ ModeSavedData *saved_data;
int saved_data_allocated = 0;
ModeDef *mode;
/* remove region hilite */
s->region_style = 0;
+ if (s->b == b)
+ return;
+
b1 = s->b;
if (b1) {
/* save mode data if no other window uses the buffer */
@@ -4692,10 +4655,10 @@
/* if no more window uses the buffer:
* - if transient contents, free the buffer
* - otherwise, save the mode data in the buffer.
- * CG: Should free previous such data ?
*/
if (!(b1->flags & BF_TRANSIENT)) {
qe_free(&b1->saved_data);
+ b1->saved_mode = s->mode;
b1->saved_data = s->mode->mode_save_data(s);
}
}
@@ -4717,18 +4680,18 @@
break;
}
if (e) {
- psaved_data = NULL;
+ mode = e->mode;
saved_data = e->mode->mode_save_data(e);
saved_data_allocated = 1;
} else {
- psaved_data = &b->saved_data;
- saved_data = *psaved_data;
+ mode = b->saved_mode;
+ saved_data = b->saved_data;
}
/* find the mode */
- if (saved_data)
- mode = saved_data->mode;
- else
+ if (!mode)
+ mode = b->default_mode;
+ if (!mode)
mode = &text_mode; /* default mode */
/* open it ! */
@@ -5070,13 +5033,12 @@
buffer */
if (!completion_popup_window) {
b = eb_new("*completion*", BF_SYSTEM | BF_UTF8 | BF_TRANSIENT);
+ b->default_mode = &list_mode;
w1 = qs->screen->width;
h1 = qs->screen->height - qs->status_height;
w = (w1 * 3) / 4;
h = (h1 * 3) / 4;
e = edit_new(b, (w1 - w) / 2, (h1 - h) / 2, w, h, WF_POPUP);
- /* set list mode */
- edit_set_mode(e, &list_mode);
do_refresh(e);
completion_popup_window = e;
}
@@ -5307,11 +5269,11 @@
minibuffer_opaque = opaque;
b = eb_new("*minibuf*", BF_SYSTEM | BF_SAVELOG | BF_UTF8);
+ b->default_mode = &minibuffer_mode;
s = edit_new(b, 0, qs->screen->height - qs->status_height,
qs->screen->width, qs->status_height, 0);
/* Should insert at end of window list */
- edit_set_mode(s, &minibuffer_mode);
s->prompt = qe_strdup(prompt);
s->minibuf = 1;
s->bidir = 0;
@@ -5343,6 +5305,7 @@
/* minibuf mode inherits from text mode */
memcpy(&minibuffer_mode, &text_mode, sizeof(ModeDef));
minibuffer_mode.name = "minibuffer";
+ minibuffer_mode.mode_probe = NULL;
minibuffer_mode.scroll_up_down = minibuf_complete_scroll_up_down;
qe_register_mode(&minibuffer_mode);
qe_register_cmd_table(minibuffer_commands, &minibuffer_mode);
@@ -5416,6 +5379,7 @@
/* less mode inherits from text mode */
memcpy(&less_mode, &text_mode, sizeof(ModeDef));
less_mode.name = "less";
+ less_mode.mode_probe = NULL;
qe_register_mode(&less_mode);
qe_register_cmd_table(less_commands, &less_mode);
}
@@ -5621,24 +5585,31 @@
splitpath(buf, buf_size, NULL, 0, buf1);
}
-static ModeDef *probe_mode(EditState *s,
+static int probe_mode(EditState *s, EditBuffer *b,
+ ModeDef **modes, int nb_modes,
+ int *scores, int min_score,
const char *filename, int st_mode, long total_size,
- const uint8_t *buf, int len)
+ const uint8_t *rawbuf, int len,
+ QECharset *charset, EOLType eol_type)
{
+ u8 buf[4097];
QEmacsState *qs = s->qe_state;
char fname[MAX_FILENAME_SIZE];
- ModeDef *m, *selected_mode;
+ ModeDef *m;
ModeProbeData probe_data;
- int best_probe_score, score;
+ int found_modes;
const uint8_t *p;
- selected_mode = NULL;
- best_probe_score = 0;
+ if (!modes || !scores || nb_modes < 1)
+ return 0;
+
+ found_modes = 0;
+ *modes = NULL;
+ *scores = 0;
+ probe_data.b = b;
probe_data.buf = buf;
probe_data.buf_size = len;
- p = memchr(buf, '\n', len);
- probe_data.line_len = p ? p - buf : len;
probe_data.real_filename = filename;
probe_data.st_mode = st_mode;
probe_data.total_size = total_size;
@@ -5646,18 +5617,101 @@
get_basename(filename));
/* CG: should pass EditState? QEmacsState ? */
- m = qs->first_mode;
- while (m != NULL) {
+ /* XXX: Should use eb_get_range_contents to deal with charset and
+ * eol_type instead of hand coding this conversion */
+ probe_data.eol_type = eol_type;
+ probe_data.charset = charset;
+ charset_decode_init(&probe_data.charset_state, charset, eol_type);
+
+ if (charset == &charset_utf8
+ || charset == &charset_raw
+ || charset == &charset_8859_1) {
+ probe_data.buf = rawbuf;
+ probe_data.buf_size = len;
+ } else {
+ int offset = 0;
+ u8 *bufp = buf;
+
+ while (offset < len) {
+ int ch = probe_data.charset_state.table[rawbuf[offset]];
+ offset++;
+ if (ch == ESCAPE_CHAR) {
+ probe_data.charset_state.p = rawbuf + offset - 1;
+ ch =
probe_data.charset_state.decode_func(&probe_data.charset_state);
+ offset = probe_data.charset_state.p - rawbuf;
+ }
+ bufp += utf8_encode((char *)bufp, ch);
+ if (bufp > buf + sizeof(buf) - MAX_CHAR_BYTES - 1)
+ break;
+ probe_data.buf = buf;
+ probe_data.buf_size = bufp - buf;
+ }
+ }
+ charset_decode_close(&probe_data.charset_state);
+
+ p = memchr(probe_data.buf, '\n', probe_data.buf_size);
+ probe_data.line_len = p ? p - probe_data.buf : probe_data.buf_size;
+
+ for (m = qs->first_mode; m != NULL; m = m->next) {
if (m->mode_probe) {
- score = m->mode_probe(m, &probe_data);
- if (score > best_probe_score) {
- selected_mode = m;
- best_probe_score = score;
+ int score = m->mode_probe(m, &probe_data);
+ if (score > min_score) {
+ int i;
+ /* sort appropriate modes by insertion in modes array */
+ for (i = 0; i < found_modes; i++) {
+ if (scores[i] < score)
+ break;
+ }
+ if (i < nb_modes) {
+ if (found_modes >= nb_modes)
+ found_modes = nb_modes - 1;
+ if (i < found_modes) {
+ memmove(modes + i + 1, modes + i,
+ (found_modes - i) * sizeof(*modes));
+ memmove(scores + i + 1, scores + i,
+ (found_modes - i) * sizeof(*scores));
+ }
+ modes[i] = m;
+ scores[i] = score;
+ found_modes++;
+ }
+ }
+ }
+ }
+ return found_modes;
+}
+
+/* Select appropriate mode for buffer:
+ * iff dir == 0, select best mode
+ * iff dir > 0, select next mode
+ * iff dir < 0, select previous mode
+ */
+void do_set_next_mode(EditState *s, int dir)
+{
+ u8 buf[4097];
+ int size;
+ ModeDef *modes[32];
+ int scores[32];
+ int i, nb, found;
+ EditBuffer *b = s->b;
+
+ size = eb_read(b, 0, buf, sizeof(buf));
+
+ nb = probe_mode(s, b, modes, countof(modes), scores, 2,
+ b->filename, b->st_mode, b->total_size,
+ buf, size, b->charset, b->eol_type);
+ found = 0;
+ if (dir && nb > 0) {
+ for (i = 0; i < nb; i++) {
+ if (s->mode == modes[i]) {
+ found = (i + nb + dir) % nb;
+ break;
}
}
- m = m->next;
}
- return selected_mode;
+ edit_set_mode(s, modes[found]);
+ put_status(s, "Mode is now %s, score=%d",
+ modes[found]->name, scores[found]);
}
/* Should take bits from enumeration instead of booleans */
@@ -5668,10 +5722,13 @@
char filename[MAX_FILENAME_SIZE];
int st_mode, buf_size;
ModeDef *selected_mode;
+ int mode_score;
EditBuffer *b;
EditBufferDataType *bdt;
FILE *f;
struct stat st;
+ EOLType eol_type = EOL_UNIX;
+ QECharset *charset = &charset_utf8;
if (load_resource) {
if (find_resource_file(filename, sizeof(filename), filename1)) {
@@ -5713,31 +5770,34 @@
b = eb_new("", BF_SAVELOG);
eb_set_filename(b, filename);
- /* Switch to the newly created buffer */
- switch_to_buffer(s, b);
-
s->offset = 0;
- /* CG: need a default setting for this */
- s->wrap = WRAP_LINE;
+ /* XXX: Should test for full width and WRAP_TRUNCATE if not */
+ s->wrap = WRAP_LINE; /* default mode may override this */
/* First we try to read the first block to determine the data type */
if (stat(filename, &st) < 0) {
/* XXX: default charset should be selectable. Use utf8 for now */
eb_set_charset(b, &charset_utf8, b->eol_type);
- /* CG: should check for wildcards and do dired */
- //if (strchr(filename, '*') || strchr(filename, '?'))
- // goto dired;
+ /* XXX: dired_mode_probe will check for wildcards in real_filename */
put_status(s, "(New file)");
/* Try to determine the desired mode based on the filename.
* This avoids having to set c-mode for each new .c or .h file. */
+ b->st_mode = st_mode = S_IFREG;
buf[0] = '\0';
- selected_mode = probe_mode(s, filename, S_IFREG, 0, buf, 0);
- /* XXX: avoid loading file */
- if (selected_mode)
- edit_set_mode(s, selected_mode);
+ buf_size = 0;
+ probe_mode(s, b, &selected_mode, 1, &mode_score, 2,
+ b->filename, b->st_mode, b->total_size,
+ buf, buf_size, b->charset, b->eol_type);
+
+ /* Attach buffer to window, will set default_mode
+ * XXX: this will also load the file, incorrect for non raw modes
+ */
+ b->default_mode = selected_mode;
+ switch_to_buffer(s, b);
+ do_load_qerc(s, s->b->filename);
return;
} else {
- st_mode = st.st_mode;
+ b->st_mode = st_mode = st.st_mode;
buf_size = 0;
f = NULL;
@@ -5748,47 +5808,51 @@
goto fail;
buf_size = fread(buf, 1, sizeof(buf) - 1, f);
if (buf_size <= 0 && ferror(f)) {
- fail1:
fclose(f);
f = NULL;
goto fail;
}
- }
+ /* autodetect buffer charset */
+ charset = detect_charset(buf, buf_size, &eol_type);
}
buf[buf_size] = '\0';
- selected_mode = probe_mode(s, filename, st_mode, st.st_size, buf,
buf_size);
- if (!selected_mode)
- goto fail1;
+ if (!probe_mode(s, b, &selected_mode, 1, &mode_score, 2,
+ filename, b->st_mode, st.st_size,
+ buf, buf_size, charset, eol_type)) {
+ fclose(f);
+ f = NULL;
+ goto fail;
+ }
bdt = selected_mode->data_type;
-
- /* autodetect buffer charset (could move it to raw buffer loader) */
- if (bdt == &raw_data_type) {
- QECharset *charset;
- EOLType eol_type;
-
- charset = detect_charset(buf, buf_size, &eol_type);
+ if (bdt == &raw_data_type)
eb_set_charset(b, charset, eol_type);
- }
- /* now we can set the mode */
- edit_set_mode_full(s, selected_mode, NULL, f);
- do_load_qerc(s, s->b->filename);
+ if (f) {
+ /* XXX: should use f to load buffer if raw_data_type */
+ fclose(f);
+ f = NULL;
+ }
+ /* Attach buffer to window, will set default_mode
+ * XXX: this will also load the file, incorrect for non raw modes
+ */
+ b->default_mode = selected_mode;
+ switch_to_buffer(s, b);
if (access(b->filename, W_OK)) {
b->flags |= BF_READONLY;
}
-
- if (f) {
- fclose(f);
- }
+ do_load_qerc(s, s->b->filename);
/* XXX: invalid place */
edit_invalidate(s);
return;
+ }
fail:
- put_status(s, "Could not open '%s'", filename);
+ eb_free(&b);
+
+ put_status(s, "Could not open '%s': %m", filename);
}
#if 0
@@ -5796,26 +5860,29 @@
{
EditState *s = opaque;
EditBuffer *b = s->b;
- if (size >= 1024 && !b->probed)
- edit_set_mode(s, probe_mode(s, b->filename, S_IFREG, b->total_size,
buf, size));
+
+ if (size >= 1024 && !b->probed) {
+ do_set_next_mode(s, 0);
+ }
}
static void load_completion_cb(void *opaque, int err)
{
EditState *s = opaque;
- int st_mode;
- st_mode = S_IFREG;
/* CG: potential problem: EXXX may be negative, as in Haiku */
if (err == -ENOENT || err == -ENOTDIR) {
put_status(s, "(New file)");
- } else if (err == -EISDIR) {
- st_mode = S_IFDIR;
- } else if (err < 0) {
+ } else
+ if (err == -EISDIR) {
+ s->b->st_mode = S_IFDIR;
+ } else
+ if (err < 0) {
put_status(s, "Could not read file");
}
- if (!s->b->probed)
- edit_set_mode(s, probe_mode(s, b->filename, st_mode, b->total_size,
buf, size));
+ if (!s->b->probed) {
+ do_set_next_mode(s, 0);
+ }
edit_display(s->qe_state);
dpy_flush(&global_screen);
}
@@ -7284,14 +7351,14 @@
{
eb_add_callback(s->b, eb_offset_callback, &s->offset, 0);
eb_add_callback(s->b, eb_offset_callback, &s->offset_top, 0);
- if (!saved_data) {
+ if (saved_data) {
+ memcpy(s, saved_data->generic_data, SAVED_DATA_SIZE);
+ } else {
memset(s, 0, SAVED_DATA_SIZE);
s->insert = 1;
s->indent_size = 4;
s->default_style = QE_STYLE_DEFAULT;
s->wrap = WRAP_LINE;
- } else {
- memcpy(s, saved_data->generic_data, SAVED_DATA_SIZE);
}
s->hex_mode = 0;
s->insert = 1;
Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.140
retrieving revision 1.141
diff -u -b -r1.140 -r1.141
--- qe.h 10 Feb 2014 20:29:26 -0000 1.140
+++ qe.h 10 Feb 2014 21:21:40 -0000 1.141
@@ -822,6 +822,8 @@
/* CG: should instead keep a pointer to last window using this
* buffer, even if no longer on screen
*/
+ struct ModeDef *default_mode;
+ struct ModeDef *saved_mode;
struct ModeSavedData *saved_data;
/* default mode stuff when buffer is detached from window */
@@ -833,6 +835,7 @@
EditBuffer *next; /* next editbuffer in qe_state buffer list */
+ int st_mode; /* unix file mode */
char name[MAX_BUFFERNAME_SIZE]; /* buffer name */
char filename[MAX_FILENAME_SIZE]; /* file name */
@@ -1136,6 +1139,10 @@
int line_len;
int st_mode; /* unix file mode */
long total_size;
+ EOLType eol_type;
+ CharsetDecodeState charset_state;
+ QECharset *charset;
+ EditBuffer *b;
};
/* private data saved by a mode so that it can be restored when the
Index: qeconfig.h
===================================================================
RCS file: /sources/qemacs/qemacs/qeconfig.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -b -r1.46 -r1.47
--- qeconfig.h 10 Feb 2014 20:29:26 -0000 1.46
+++ qeconfig.h 10 Feb 2014 21:21:40 -0000 1.47
@@ -383,6 +383,12 @@
"s{Set mode: }[mode]")
CMD1( KEY_NONE, KEY_NONE,
"set-auto-coding", do_set_auto_coding, 1)
+ CMD1( KEY_NONE, KEY_NONE,
+ "set-auto-mode", do_set_next_mode, 0)
+ CMD1( KEY_META('m'), KEY_NONE,
+ "set-next-mode", do_set_next_mode, 1)
+ CMD1( KEY_NONE, KEY_NONE,
+ "set-previous-mode", do_set_next_mode, -1)
/* tab & indent */
CMD2( KEY_NONE, KEY_NONE,
Index: shell.c
===================================================================
RCS file: /sources/qemacs/qemacs/shell.c,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -b -r1.84 -r1.85
--- shell.c 5 Feb 2014 00:56:49 -0000 1.84
+++ shell.c 10 Feb 2014 21:21:40 -0000 1.85
@@ -52,7 +52,10 @@
TTY_STATE_STRING,
};
+static int shell_signature;
+
typedef struct ShellState {
+ void *signature;
/* buffer state */
int pty_fd;
int pid; /* -1 if not launched */
@@ -256,7 +259,6 @@
char *term;
s->state = TTY_STATE_NORM;
- s->cur_offset = 0;
/* Should compute def_color from shell default style at display
* time and force full redisplay upon style change.
*/
@@ -655,11 +657,25 @@
#endif
}
+static ShellState *shell_get_state(EditState *e)
+{
+ ShellState *s = e->b->priv_data;
+
+ if (s && s->signature == &shell_signature)
+ return s;
+
+ put_status(e, "Not a shell buffer");
+ return NULL;
+}
+
/* CG: much cleaner way! */
/* would need a kill hook as well ? */
static void shell_display_hook(EditState *e)
{
- ShellState *s = e->b->priv_data;
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
if (e->interactive)
e->offset = s->cur_offset;
@@ -672,6 +688,9 @@
const char *p;
int len;
+ if (!s || s->signature != &shell_signature)
+ return;
+
if (key == KEY_CTRL('o')) {
qe_ungrab_keys();
unget_key(key);
@@ -1222,10 +1241,14 @@
static void shell_read_cb(void *opaque)
{
ShellState *s = opaque;
- QEmacsState *qs = s->qe_state;
+ QEmacsState *qs;
unsigned char buf[16 * 1024];
int len, i;
+ if (!s || s->signature != &shell_signature)
+ return;
+
+ qs = s->qe_state;
len = read(s->pty_fd, buf, sizeof(buf));
if (len <= 0)
return;
@@ -1252,11 +1275,17 @@
static void shell_pid_cb(void *opaque, int status)
{
ShellState *s = opaque;
- EditBuffer *b = s->b;
- QEmacsState *qs = s->qe_state;
+ EditBuffer *b;
+ QEmacsState *qs;
EditState *e;
char buf[1024];
+ if (!s || s->signature != &shell_signature)
+ return;
+
+ b = s->b;
+ qs = s->qe_state;
+
*buf = 0;
if (s->caption) {
time_t ti;
@@ -1348,7 +1377,11 @@
int rows, cols;
b = b0;
- if (!b) {
+ if (b) {
+ s = b->priv_data;
+ if (s && s->signature != &shell_signature)
+ return NULL;
+ } else {
int bf_flags = BF_SAVELOG;
if (shell_flags & SF_COLOR)
bf_flags |= BF_STYLE2;
@@ -1367,22 +1400,27 @@
eb_set_charset(b, &charset_vt100, b->eol_type);
}
+ s = b->priv_data;
+ if (!s) {
s = qe_mallocz(ShellState);
if (!s) {
if (!b0)
eb_free(&b);
return NULL;
}
+ s->signature = &shell_signature;
b->priv_data = s;
b->close = shell_close;
/* Track cursor with edge effect */
eb_add_callback(b, eb_offset_callback, &s->cur_offset, 1);
+ }
s->b = b;
s->pty_fd = -1;
s->pid = -1;
s->qe_state = qs;
s->caption = caption;
s->shell_flags = shell_flags;
+ s->cur_offset = b->total_size;
tty_init(s);
/* launch shell */
@@ -1421,25 +1459,52 @@
static void do_shell(EditState *s, int force)
{
- EditBuffer *b;
+ ShellState *shs;
+ EditBuffer *b = NULL;
/* CG: Should prompt for buffer name if arg:
* find a syntax for optional string argument w/ prompt
*/
/* find shell buffer if any */
if (!force || force == NO_ARG) {
- if (try_show_buffer(s, "*shell*"))
+ /* XXX: if current buffer is a shell buffer without a process,
+ * restart shell process.
+ */
+ b = s->b;
+ shs = b->priv_data;
+ if (strstart(b->name, "*shell*", NULL)
+ && shs && shs->signature == &shell_signature) {
+ if (shs->pid >= 0)
return;
+ } else {
+ b = try_show_buffer(s, "*shell*");
+ if (b) {
+ shs = b->priv_data;
+ if (shs) {
+ if (shs->signature != &shell_signature) {
+ b = NULL;
+ } else
+ if (shs->pid >= 0)
+ return;
+ }
+ }
+ }
+ if (b) {
+ /* restart shell in *shell* buffer */
+ s->offset = b->total_size;
+ }
}
/* create new buffer */
- b = new_shell_buffer(NULL, "*shell*", "Shell process", NULL,
+ b = new_shell_buffer(b, "*shell*", "Shell process", NULL,
SF_COLOR | SF_INTERACTIVE);
if (!b)
return;
+ b->default_mode = &shell_mode;
switch_to_buffer(s, b);
- edit_set_mode(s, &shell_mode);
+ s->interactive = 1;
+ //edit_set_mode(s, &shell_mode);
put_status(s, "Press C-o to toggle between shell/edit mode");
}
@@ -1483,16 +1548,21 @@
if (!b)
return;
+ b->default_mode = &shell_mode;
switch_to_buffer(s, b);
- edit_set_mode(s, &shell_mode);
+ //edit_set_mode(s, &shell_mode);
put_status(s, "Press C-o to toggle between shell/edit mode");
}
static void shell_move_left_right(EditState *e, int dir)
{
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
+
if (e->interactive) {
- ShellState *s = e->b->priv_data;
tty_write(s, dir > 0 ? s->kcuf1 : s->kcub1, -1);
} else {
text_move_left_right_visual(e, dir);
@@ -1501,8 +1571,12 @@
static void shell_move_word_left_right(EditState *e, int dir)
{
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
+
if (e->interactive) {
- ShellState *s = e->b->priv_data;
tty_write(s, dir > 0 ? "\033f" : "\033b", -1);
} else {
text_move_word_left_right(e, dir);
@@ -1511,8 +1585,12 @@
static void shell_move_up_down(EditState *e, int dir)
{
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
+
if (e->interactive) {
- ShellState *s = e->b->priv_data;
tty_write(s, dir > 0 ? s->kcud1 : s->kcuu1, -1);
} else {
text_move_up_down(e, dir);
@@ -1521,7 +1599,10 @@
static void shell_scroll_up_down(EditState *e, int dir)
{
- ShellState *s = e->b->priv_data;
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
e->interactive = 0;
text_scroll_up_down(e, dir);
@@ -1530,11 +1611,15 @@
static void shell_move_bol(EditState *e)
{
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
+
/* XXX: exit shell interactive mode on home / ^A */
e->interactive = 0;
if (e->interactive) {
- ShellState *s = e->b->priv_data;
tty_write(s, "\001", 1); /* Control-A */
} else {
text_move_bol(e);
@@ -1543,7 +1628,10 @@
static void shell_move_eol(EditState *e)
{
- ShellState *s = e->b->priv_data;
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
if (e->interactive) {
tty_write(s, "\005", 1); /* Control-E */
@@ -1558,10 +1646,12 @@
{
char buf[10];
int len;
+ ShellState *s;
- if (e->interactive) {
- ShellState *s = e->b->priv_data;
+ if (!(s = shell_get_state(e)))
+ return;
+ if (e->interactive) {
if (c >= KEY_META(0) && c <= KEY_META(0xff)) {
buf[0] = '\033';
buf[1] = c - KEY_META(0);
@@ -1613,15 +1703,18 @@
static void do_shell_toggle_input(EditState *e)
{
+ ShellState *s;
+
+ if (!(s = shell_get_state(e)))
+ return;
+
e->interactive = !e->interactive;
if (e->interactive) {
- ShellState *s = e->b->priv_data;
if (s->grab_keys)
qe_grab_keys(shell_key, s);
}
#if 0
if (e->interactive) {
- ShellState *s = e->b->priv_data;
tty_update_cursor(s);
}
#endif
@@ -1650,7 +1743,6 @@
/* XXX: try to split window if necessary */
switch_to_buffer(e, b);
- /* XXX: pager_mode for colorized output, text mode should support color
buffer */
edit_set_mode(e, &pager_mode);
set_error_offset(b, 0);
}
@@ -1815,7 +1907,17 @@
CMD_DEF_END,
};
-static int shell_mode_init(EditState *s, __unused__ ModeSavedData *saved_data)
+static int shell_mode_probe(ModeDef *mode, ModeProbeData *p)
+{
+ if (p->b && p->b->priv_data) {
+ ShellState *s = p->b->priv_data;
+ if (s->signature == &shell_signature)
+ return 100;
+ }
+ return 0;
+}
+
+static int shell_mode_init(EditState *s, ModeSavedData *saved_data)
{
text_mode_init(s, saved_data);
s->b->tab_width = 8;
@@ -1824,7 +1926,7 @@
return 0;
}
-static int pager_mode_init(EditState *s, __unused__ ModeSavedData *saved_data)
+static int pager_mode_init(EditState *s, ModeSavedData *saved_data)
{
text_mode_init(s, saved_data);
s->b->tab_width = 8;
@@ -1837,7 +1939,7 @@
/* populate and register shell mode and commands */
memcpy(&shell_mode, &text_mode, sizeof(ModeDef));
shell_mode.name = "shell";
- shell_mode.mode_probe = NULL;
+ shell_mode.mode_probe = shell_mode_probe;
shell_mode.mode_init = shell_mode_init;
shell_mode.display_hook = shell_display_hook;
shell_mode.move_left_right = shell_move_left_right;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemacs-commit] qemacs bufed.c dired.c extras.c list.c makemode...,
Charlie Gordon <=