Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
230f2ba
Fix several problems in signal handler autoconf check (#96)
hhoffstaette Apr 11, 2026
bca792e
Only ASCII is safe to use in OSC 8 link text, so use `->` instead of …
dsalt Apr 11, 2026
fd85065
fix GLO_OPT_INT issue (#100)
pcm1k Apr 15, 2026
922708e
Fix an off-by-one in m4.jsf.
dsalt Apr 9, 2026
0057eef
Fix an off-by-one in sh keyword colouring.
dsalt Mar 31, 2026
2f2a9af
Construct a message when setting certain boolean options. (Fixes a se…
dsalt Mar 31, 2026
e082df1
debian/jsf indented line colouring: add <…>, fix after line ends
dsalt Apr 4, 2026
2c97c05
Fix tags file security vulnerability (#105)
jhallen Apr 20, 2026
f8e792f
Syntax fixes (#104)
dsalt Apr 20, 2026
ac085f5
save filthist to state (#102)
pcm1k Apr 20, 2026
a7b2993
allow notmod in PW (#103)
pcm1k Apr 20, 2026
273f44e
Fix: file does not work if JOE is reading from stdin pipe
jhallen Apr 20, 2026
153d31c
Update NEWS, bump version to 4.8
jhallen Apr 20, 2026
ef1ca8a
rtree_opt: don't try to malloc 0 bytes
dsalt Apr 12, 2026
72590ac
Fix selection bugs, make ^Z / ^X consistent (#106)
jhallen Apr 20, 2026
07dc8d5
Update NEWS and copyright date
jhallen Apr 20, 2026
98fda77
Fix parsing of compiler messages and handle absolute pathnames (#95)
dsalt Apr 20, 2026
db733e3
Some fixes for 98fda77c0f06c07a1f98df48a2462bc357162ec9
jhallen Apr 21, 2026
d52b474
Update NEWS.
jhallen Apr 21, 2026
719da5b
Fix assign to stdin issue
jhallen May 6, 2026
869f30b
Fix issue where aspell prevents restoration from alternate screen whe…
jhallen May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,48 @@

[Build instructions](INSTALL.md)

### JOE 4.8

* Enhancements

* Allow notmod in prompt windows: if you set it in a macro, this
suppresses adding the prompt to the history. Good for keeping
history clean.

* Save block filter prompt history in state file.

* Add parserr_homeonly option: compiler error parser will ignore
errors from files outside of user's home directory- suppresses
references to system include files.

* Bugs fixed

* Fix tags file security vulnerability: Someone could share a tags
file that tricks a user into executing a shell command by using
JOE's '!' filename syntax. This fix prevents '!' from working
when opening files specified in the tags file.

* Fix some build issues involving deprecated autoconf RETSIGTYPE.

* Do not use unicode arrow in tooltips for new syntax debugging
feature

* Fix a number of minor syntax coloring issues: sh, m4, debian, rust

* Fix integer global option setting issue

* Prevent segfault when referring to certain boolean options

* Fix issue where block filtering does not work if JOE is reading
from stdin pipe

* Fix asymmetric ^X / ^Z

* Fix selection glitches during Ctrl-Shift-Right / -Left

* Fix compiler error parser: it was not handling "new" (as of 9
years ago) delimiters from make

### JOE 4.7

* Enhancements
Expand Down
8 changes: 8 additions & 0 deletions acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,17 @@ AC_DEFUN([joe_REINSTALL_SIGHANDLERS],
#include <signal.h>
#endif

#ifndef RETSIGTYPE
typedef void RETSIGTYPE;
#endif

#ifndef HAVE_SIGHANDLER_T
typedef RETSIGTYPE (*sighandler_t)(int);
#endif

void set_signal(int signum, sighandler_t handler);
RETSIGTYPE sigint(int s);

int nsigint;

void set_signal(int signum, sighandler_t handler) {
Expand All @@ -86,6 +93,7 @@ void set_signal(int signum, sighandler_t handler) {
}

RETSIGTYPE sigint(int s) {
(void)s;
nsigint++;
}

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ AC_PREREQ([2.64])
AC_CONFIG_MACRO_DIR([m4])

#### Here's the only place where to change version number ####
AC_INIT([joe],[4.7])
AC_INIT([joe],[4.8])
AC_CONFIG_SRCDIR([joe/b.c])

AC_CANONICAL_BUILD
Expand Down
13 changes: 13 additions & 0 deletions joe/b.c
Original file line number Diff line number Diff line change
Expand Up @@ -2513,6 +2513,19 @@ B *bread(int fi, off_t max, int binary)
return b;
}

/* Return true if filename will be interpreted as something other than a filename by bload()
It would be better to have a flag on bload, but more plumbing required */

int hack_check(const char *name)
{
if (name[0] == '!')
return 1;
else if (name[0] == '>' && name[1] == '>')
return 1;
else
return 0;
}

/* Parse file name.
*
* Removes ',xxx,yyy' from end of name and puts their value into skip and amnt
Expand Down
3 changes: 3 additions & 0 deletions joe/b.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,6 @@ int ansi_code(char *s);
char *ansi_string(int code);

extern int guess_utf16;

/* Return true if filename will be interpreted as something other than a filename */
int hack_check(const char *name);
3 changes: 2 additions & 1 deletion joe/bw.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ static struct state_debug_data out_osc8(const struct state_debug_data *oldstate,
ttputs(";");
ttputs(state_names[newstate->name]);
if (newstate->recolor && newstate->recolor != newstate->name) {
ttputs("→");
/* ugh, only ASCII for OSC-8 pop-up text */
ttputs("->");
ttputs(state_names[newstate->recolor]);
}
ttputs("\x1B\\");
Expand Down
4 changes: 2 additions & 2 deletions joe/cclass.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,8 @@ void rtree_opt(struct Rtree *r)

/* De-duplicate leaf nodes (it's not worth bothering with interior nodes) */

equiv = (int *)joe_malloc(SIZEOF(int) * r->leaf.alloc);
repl = (short *)joe_malloc(SIZEOF(short) * r->leaf.alloc);
equiv = r->leaf.alloc ? (int *)joe_malloc(SIZEOF(int) * r->leaf.alloc) : NULL;
repl = r->leaf.alloc ? (short *)joe_malloc(SIZEOF(short) * r->leaf.alloc) : NULL;

/* Create hash table index of all the leaf nodes */
dupcount = 0;
Expand Down
2 changes: 1 addition & 1 deletion joe/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const CMD cmds[] = {
{"nextw", TYPETW + TYPEPW + TYPEMENU + TYPEQW, unextw, NULL, 1, "prevw"},
{"nextword", TYPETW + TYPEPW + EFIXXCOL, u_goto_next, NULL, 1, "prevword"},
{"nmark", TYPETW + TYPEPW, unmark, NULL, 0, NULL},
{"notmod", TYPETW, unotmod, NULL, 0, NULL},
{"notmod", TYPETW + TYPEPW, unotmod, NULL, 0, NULL},
{"nxterr", TYPETW, unxterr, NULL, 1, "prverr"},
{"open", TYPETW + TYPEPW + EFIXXCOL + EMOD, uopen, NULL, 1, "deleol"},
{"parserr", TYPETW, uparserr, NULL, 0, NULL},
Expand Down
6 changes: 5 additions & 1 deletion joe/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ int main(int argc, char **real_argv, const char * const *envv)
xmsg = stagen(NULL, (BW *)(lastw(maint)->object), joe_gettext(xmsg), ' ');
msgnw(((BASE *)lastw(maint)->object)->parent, xmsg);
} else {
joe_snprintf_3(msgbuf,JOE_MSGBUFSIZE,joe_gettext(_("\\i** Joe's Own Editor v%s ** (%s) ** Copyright %s 2015 **\\i")),VERSION,locale_map->name,(locale_map->type ? "©" : "(C)"));
joe_snprintf_3(msgbuf,JOE_MSGBUFSIZE,joe_gettext(_("\\i** Joe's Own Editor v%s ** (%s) ** Copyright %s 1992 - 2026 **\\i")),VERSION,locale_map->name,(locale_map->type ? "©" : "(C)"));
msgnw(((BASE *)lastw(maint)->object)->parent, msgbuf);
}

Expand All @@ -755,6 +755,10 @@ int main(int argc, char **real_argv, const char * const *envv)
/* Close stdin, so that if user kills the copying the program feeding stdin sees a SIGPIPE */
/* It won't if there are any extra file descriptors open */
fclose(stdin);
if (!freopen("/dev/tty", "rb", stdin))
{
/* This should not fail */
}
}
}

Expand Down
18 changes: 16 additions & 2 deletions joe/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ struct glopts {
ptrdiff_t ofst; /* Local options structure member offset */
int low; /* Low limit for numeric options */
int high; /* High limit for numeric options */
/* For *_OPT_BOOL, if .yes=NULL or .no=NULL, a message using the menu
* string (if non-NULL) & "ON" or "OFF" will be generated at need */
} glopts[] = {
{"overwrite", LOC_OPT_BOOL, { NULL }, (char *) &fdefault.overtype, _("Overtype mode"), _("Insert mode"), _("Overtype mode"), 0, 0, 0 },
{"hex", LOC_OPT_BOOL, { NULL }, (char *) &fdefault.hex, _("Hex edit mode"), _("Text edit mode"), _("Hex edit display mode"), 0, 0, 0 },
Expand All @@ -335,6 +337,7 @@ struct glopts {
{"menu_explorer", GLO_OPT_BOOL, { &menu_explorer }, NULL, _("Menu explorer mode"), _("Simple completion mode"), _("Menu explorer mode"), 0, 0, 0 },
{"menu_above", GLO_OPT_BOOL, { &menu_above }, NULL, _("Menu above prompt"), _("Menu below prompt"), _("Menu above/below mode"), 0, 0, 0 },
{"notagsmenu", GLO_OPT_BOOL, { &notagsmenu }, NULL, _("Tags menu disabled"), _("Tags menu enabled"), _("Tags menu mode"), 0, 0, 0 },
{"parserr_homeonly", GLO_OPT_BOOL, { &parserr_homeonly }, NULL, 0, 0, _("Error logs: home dir only"), 0, 0, 0 },
{"search_prompting", GLO_OPT_BOOL, { &pico }, NULL, _("Search prompting on"), _("Search prompting off"), _("Search prompting mode"), 0, 0, 0 },
{"menu_jump", GLO_OPT_BOOL, { &menu_jump }, NULL, _("Jump into menu is on"), _("Jump into menu is off"), _("Jump into menu mode"), 0, 0, 0 },
{"autoswap", GLO_OPT_BOOL, { &autoswap }, NULL, _("Autoswap ^KB and ^KK"), _("Autoswap off "), _("Autoswap mode "), 0, 0, 0 },
Expand Down Expand Up @@ -689,7 +692,7 @@ int glopt(char *s, char *arg, OPTIONS *options, int set)
if (set && arg) {
val = ztoi(arg);
if (val >= opt->low && val <= opt->high)
*opt->set.b = val;
*opt->set.i = val;
}
ret = arg ? 2 : 1;
break;
Expand Down Expand Up @@ -1259,6 +1262,7 @@ static int find_option(char *s)
static int applyopt(BW *bw, int *optp, int y, int flg)
{
int oldval, newval;
const char *msg;

oldval = *optp;
if (flg == 0) {
Expand All @@ -1273,8 +1277,18 @@ static int applyopt(BW *bw, int *optp, int y, int flg)
}

*optp = newval;
msgnw(bw->parent, newval ? joe_gettext(glopts[y].yes) : joe_gettext(glopts[y].no));

msg = newval ? glopts[y].yes : glopts[y].no;
if (msg)
msgnw(bw->parent, joe_gettext(msg));
else {
msg = newval ? "ON" : "OFF";
if (glopts[y].menu) {
joe_snprintf_2(msgbuf, JOE_MSGBUFSIZE, "%s: %s", joe_gettext(glopts[y].menu), msg);
msgnw(bw->parent, msgbuf);
} else
msgnw(bw->parent, msg);
}
return oldval;
}

Expand Down
3 changes: 3 additions & 0 deletions joe/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ void save_state(void)
fprintf(f,"run\n"); save_hist(f,runhist);
fprintf(f,"build\n"); save_hist(f,buildhist);
fprintf(f,"grep\n"); save_hist(f,grephist);
fprintf(f,"filt\n"); save_hist(f,filthist);
fprintf(f,"cmd\n"); save_hist(f,cmdhist);
fprintf(f,"math\n"); save_hist(f,mathhist);
fprintf(f,"yank\n"); save_yank(f);
Expand Down Expand Up @@ -188,6 +189,8 @@ void load_state(void)
load_hist(f,&buildhist);
else if(!zcmp(buf,"grep\n"))
load_hist(f,&grephist);
else if(!zcmp(buf,"filt\n"))
load_hist(f,&filthist);
else if(!zcmp(buf,"cmd\n"))
load_hist(f,&cmdhist);
else if(!zcmp(buf,"math\n"))
Expand Down
10 changes: 8 additions & 2 deletions joe/ublock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,11 @@ static int dofilt(W *w, char *s, void *object, int *notify)
msgnw(bw->parent, joe_gettext(_("Couldn't create pipe")));
return -1;
}
npartial(bw->parent->t->t);
/* npartial is less jarring... */
/* npartial(bw->parent->t->t); */
/* But we must use nescape if we are using the ti te sequences, otherwise
JOE doesn't return from alternate screen if aspell is used */
nescape(bw->parent->t->t);
ttclsn();
#ifdef HAVE_FORK
if (!fork()) {
Expand Down Expand Up @@ -1275,13 +1279,15 @@ static int dofilt(W *w, char *s, void *object, int *notify)
}
vsrm(s);
ttopnn();
/* Use nreturn because we now use nescape */
nreturn(bw->parent->t->t);
if (filtflg)
unmark(bw->parent, 0);
bw->cursor->xcol = piscol(bw->cursor);
return 0;
}

static B *filthist = NULL;
B *filthist = NULL;

static void markall(BW *bw)
{
Expand Down
2 changes: 2 additions & 0 deletions joe/ublock.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ int blklr(BW *bw, double *,double *, double *, double *, double *, int, int);
char *blkget(BW *bw);
extern int autoswap; /* Automatically swap markb and markk if need to make a valid block */
extern int nowmarking; /* Now marking flag (so make block bigger) for Ctrl-arrow key block selection */

extern B *filthist; /* Filter command history */
2 changes: 2 additions & 0 deletions joe/uedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ static int p_goto_prev(P *ptr)
} else if (joe_isspace(map,c) || joe_ispunct(map,c)) {
while ((c=prgetc(p)), (joe_isspace(map,c) || joe_ispunct(map,c)))
/* Do nothing */;
if (c != NO_MORE_DATA)
pgetc(p);
while(joe_isalnum_(map,(c=prgetc(p))))
/* Do nothing */;
if (c != NO_MORE_DATA)
Expand Down
Loading