1
0
mirror of https://github.com/rfivet/uemacs.git synced 2025-11-23 11:41:15 -05:00

14 Commits

Author SHA1 Message Date
18962ffbe2 Fix display update of tabs when terminal width is not a multiple of tabwidth and current in line position is over the terminal width. 2025-07-05 13:30:08 +08:00
9562b0a2e8 Fix cursor location redrawing in incremental search (¨XS): backtracking using backspace/rubout over several forward-search (^S). 2025-04-26 11:33:24 +08:00
e4021d7780 Fetch ncursesw compilation flags and libs using ncurseswN-config. 2025-01-02 11:21:52 +08:00
d60640af0f Quick Mac Hack: add Mac mode for CR only EOL. 2024-11-30 16:32:16 +08:00
22e26fc885 Integrate online documentation in repository. 2024-08-14 10:39:45 +08:00
1ee0ebf4b9 Fix: avoid extra NL when newline/yank/insert-file at end of last line of non empty buffer.
Refactor yank.
Detab before commit.
2024-04-04 12:03:24 +08:00
12d307b5b4 Display non breaking space according to code page instead of \A0. 2024-04-01 11:17:19 +08:00
54145a48f8 Fix assertion violation when invoking help macro at end of help file. &mid function was not safe to call on empty line, same for &mid.
Minor reformatting of help file to avoid content to be mistaken as section reference by help macro.
2023-12-20 13:07:04 +08:00
5b2884b93c Fix point and mark update when inserting in buffer with multiple windows. 2022-09-04 16:08:37 +08:00
041210b228 Use memmove instead of memcpy for overlapping memory area. (reproducible on OpenBSD). 2022-08-26 11:16:45 +08:00
Rob Gowin
737fee5323 Changes to compile on macOS. (#2)
defines.h:
  Use (defined(__APPLE__) && defined(__MACH__)) to
  detect macOS, as suggested by https://stackoverflow.com/questions/7063303/macro-unix-not-defined-in-macos-x.
  Combined with __NetBSD__ to set BSD=1 and POSIX=1.

main.c:
  Include <unistd.h> to pick up sleep() declaration.

Co-authored-by: Rob Gowin <rob.gowin@gmail.com>
2022-08-24 10:28:13 +08:00
ca23e6c394 Ignore generated dependencies. 2022-03-03 07:40:31 +08:00
f2c53b5b1f Reviewed dependencies generation. 2022-02-05 10:56:12 +08:00
2befa53c3a Merge branch 'unicode' 2021-09-18 09:12:27 +08:00
24 changed files with 334 additions and 172 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,4 @@
depend.mak
ue
*.o
*.exe
*.dep

View File

@@ -1,5 +1,5 @@
# Makefile -- µEMACS
# Copyright © 2013-2021 Renaud Fivet
# Copyright © 2013-2025 Renaud Fivet
# Make the build silent by default
V =
@@ -15,26 +15,29 @@ export E Q
PROGRAM=ue
CC=gcc
NCWCFG=ncursesw6-config
NCWFLGS !=$(NCWCFG) --cflags
NCWLIBS !=$(NCWCFG) --libs
CC=cc
WARNINGS=-pedantic -Wall -Wextra -Wstrict-prototypes -Wno-unused-parameter
CFLAGS=-O2 $(WARNINGS)
LDFLAGS=-s
LIBS=-lcurses
DEFINES=-DPROGRAM=$(PROGRAM) -D_GNU_SOURCE # -DNDEBUG
LIBS=$(NCWLIBS)
DEFINES=-DPROGRAM=$(PROGRAM) $(NCWFLGS) # -DNDEBUG
BINDIR=/usr/bin
LIBDIR=/usr/lib
SRCS = $(sort $(wildcard *.c))
OBJS = $(SRCS:.c=.o)
$(PROGRAM): $(OBJS)
$(E) " LINK " $@
$(Q) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(PROGRAM): $(SRCS:.c=.o)
$(E) " LINK " $@
$(Q) $(CC) $(LDFLAGS) -o $@ $+ $(LIBS)
clean:
$(E) " CLEAN"
$(Q) rm -f $(PROGRAM) depend.mak *.o
$(Q) rm -f $(PROGRAM) *.dep *.o
install: $(PROGRAM)
strip $(PROGRAM)
@@ -45,13 +48,15 @@ install: $(PROGRAM)
chmod 644 ${LIBDIR}/emacs.hlp ${LIBDIR}/.emacsrc
.c.o:
$(E) " CC " $@
$(Q) ${CC} ${CFLAGS} ${DEFINES} -c $*.c
$(E) " CC " $@
$(Q) $(CC) $(CFLAGS) $(DEFINES) -c $*.c
depend.mak: $(wildcard *.h)
$(E) " DEPEND"
$(Q) $(CC) $(DEFINES) -MM $(SRCS) > depend.mak
%.dep: %.c
$(E) " DEPEND" $@
$(Q) $(CC) $(DEFINES) -MM $< > $@
include depend.mak
ifneq ($(MAKECMDGOALS),clean)
include $(SRCS:.c=.dep)
endif
# end of Makefile

View File

@@ -1,7 +1,7 @@
# README #
µEMACS (ue) on Cygwin/Linux/NetBSD, based on uEmacs/PK (em) from [kernel.org](
https://git.kernel.org/pub/scm/editors/uemacs/uemacs.git/).
µEMACS (ue) on Cygwin/MSYS2/Linux/NetBSD/OpenBSD, based on uEmacs/PK (em)
from [kernel.org](https://git.kernel.org/pub/scm/editors/uemacs/uemacs.git/).
### Changes compare to uEmacs/PK ###
@@ -26,6 +26,6 @@ https://git.kernel.org/pub/scm/editors/uemacs/uemacs.git/).
### How to build ###
* dependencies: gcc, gmake, ncurses-devel.
* dependencies: (gcc || clang) && gmake && ncurses-devel.
* make

View File

@@ -42,7 +42,7 @@ static unsigned getgoal( line_p dlp) {
col += tabwidth - col % tabwidth ;
else if( c < 0x20 || c == 0x7F) /* ^x */
col += 2 ;
else if( c >= 0x80 && c <= 0xA0) /* \xx */
else if( c >= 0x80 && c < 0xA0) /* \xx */
col += 3 ;
else
col += utf8_width( c) ;

View File

@@ -28,7 +28,7 @@ buffer_p blistp ; /* Buffer for C-X C-B */
const char *modename[ NUMMODES] = { /* name of modes */
"Wrap", "Cmode", "Exact", "View", "Over",
"Magic",
"Asave", "Utf-8", "Dos"
"Asave", "Utf-8", "Dos", "Mac"
} ;
int gmode = 0 ; /* global editor mode */
@@ -293,9 +293,9 @@ BINDABLE( listbuffers) {
int iflag; list hidden buffer flag
*/
/* Layout: "ACT MODES Size Buffer File"
AAA MMMMMMMMMSSSSSSSSSS BBBBBBBBBBBBBBB FFF...
FNAMSTART ---------------------------------------^
/* Layout: "ACT MODES Size Buffer File"
AAA MMMMMMMMMMSSSSSSSSSS BBBBBBBBBBBBBBB FFF...
FNAMSTART ----------------------------------------^
*/
#define FNAMSTART (3 + 1 + NUMMODES + 10 + 1 + (sizeof( bname_t) - 1) + 1)
@@ -303,7 +303,7 @@ static void do_layout( char *line, int mode) {
int i ;
/* build line to report global mode settings */
strcpy( line, " WCEVOMAUD Global Modes") ;
strcpy( line, " WCEVOmAUDM Global Modes") ;
/* output the mode codes */
for( i = 0 ; i < NUMMODES ; i++)
@@ -336,8 +336,8 @@ static int makelist( int iflag) {
blistp->b_fname[ 0] = 0 ; /* in case of user override */
if( addline("ACT MODES Size Buffer File") == FALSE
|| addline("‾‾‾ ‾‾‾‾‾ ‾‾‾‾ ‾‾‾‾‾‾ ‾‾‾‾") == FALSE)
if( addline("ACT MODES Size Buffer File") == FALSE
|| addline("‾‾‾ ‾‾‾‾‾ ‾‾‾‾ ‾‾‾‾‾‾ ‾‾‾‾") == FALSE)
return FALSE ;
/* report global mode settings */
@@ -369,7 +369,7 @@ static int makelist( int iflag) {
long nbytes = 0L; /* Count bytes in buf. */
long nlines = 0 ;
for( line_p lp = lforw( bp->b_linep) ; lp != bp->b_linep ;
lp = lforw( lp)) {
lp = lforw( lp)) {
nbytes += (long) llength(lp) + 1L;
nlines += 1 ;
}
@@ -377,8 +377,8 @@ static int makelist( int iflag) {
if( bp->b_mode & MDDOS)
nbytes += nlines ;
l_to_a( &line[ 13], 10 + 1, nbytes) ; /* "%10d" formatted numbers */
cp1 = &line[ 23] ;
l_to_a( &line[ 14], 10 + 1, nbytes) ; /* "%10d" formatted numbers */
cp1 = &line[ 24] ;
*cp1++ = ' ' ;
/* Display buffer name */

View File

@@ -44,7 +44,7 @@ extern buffer_p blistp ; /* Buffer for C-X C-B */
#define BFTRUNC 0x04 /* buffer was truncated when read */
/* mode flags */
#define NUMMODES 9 /* # of defined modes */
#define NUMMODES 10 /* # of defined modes */
#define MDWRAP 0x0001 /* word wrap */
#define MDCMOD 0x0002 /* C indentation and fence match */
@@ -55,6 +55,7 @@ extern buffer_p blistp ; /* Buffer for C-X C-B */
#define MDASAVE 0x0040 /* auto-save mode */
#define MDUTF8 0x0080 /* utf8 mode */
#define MDDOS 0x0100 /* CRLF eol mode */
#define MDMAC 0x0200 /* CR eol mode */
extern const char *modename[ NUMMODES] ; /* text names of modes */
extern int gmode ; /* global editor mode */

View File

@@ -2,9 +2,9 @@
#ifndef __DEFINES_H__
#define __DEFINES_H__
#if __unix__
#if __unix__ || (defined(__APPLE__) && defined(__MACH__))
# define UNIX 1
# if __NetBSD__
# if __NetBSD__ || __OpenBSD__ || (defined(__APPLE__) && defined(__MACH__))
# define BSD 1
# define POSIX 1
# elif __linux__

View File

@@ -230,12 +230,12 @@ static void vtputuc( unicode_t c) {
if( c == '\t') {
sane_vtputc( viewtab ? 0xBB : ' ') ; /* 0xBB: '»' */
while( ((vtcol + lbound) % tabwidth) != 0)
while( vtcol % tabwidth)
sane_vtputc( ' ') ;
} else if( c < 0x20 || c == 0x7F) {
sane_vtputc( '^') ;
sane_vtputc( c ^ 0x40) ;
} else if( c >= 0x80 && c <= 0xA0) {
} else if( c >= 0x80 && c < 0xA0) {
static const char hex[] = "0123456789abcdef" ;
sane_vtputc( '\\') ;
sane_vtputc( hex[ c >> 4]) ;
@@ -556,7 +556,7 @@ static void updpos( void) {
curcol += tabwidth - curcol % tabwidth ;
else if( c < 0x20 || c == 0x7F)
curcol += 2 ; /* displayed as ^c */
else if( c >= 0x80 && c <= 0xA0)
else if( c >= 0x80 && c < 0xA0)
curcol += 3 ; /* displayed as \xx */
else
curcol += utf8_width( c) ; /* non printable are displayed as \u */

BIN
docs/img/ue_425.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/img/ue_screensize.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

27
docs/index.html Normal file
View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>µEMACS</title>
<style>
body {
width: 1024px ;
margin-left: auto ;
margin-right: auto ;
}
</style>
</head>
<body>
<h1>µEMACS</h1>
<b>µEMACS</b> (ue) based on uEmacs/PK (em) from
<a href="https://git.kernel.org/pub/scm/editors/uemacs/uemacs.git/">kernel.org</a>.
Latest version built and tested on Cygwin, Ubuntu Linux and NetBSD.
<p>
<a href="quick.html">Quick build and install</a>
<p>
<img src="img/ue_425.png" alt="µEMACS sample screenshot">
<hr>© 2020-2024 Renaud Fivet
</body>
</html>

115
docs/quick.html Normal file
View File

@@ -0,0 +1,115 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quick µEMACS build and install</title>
<style>
body {
width: 1024px ;
margin-left: auto ;
margin-right: auto ;
}
pre {
background-color: #F3F6FA ;
margin-left: 1% ;
margin-right: 25% ;
}
</style>
</head>
<body>
<h1>Quick µEMACS build and install</h1>
<h2>Dependencies and build environment</h2>
To build µEMACS, you need to have gcc, GNU make and ncurses development
library installed.
<h2>Checking environment</h2>
gcc and GNU make are often preinstalled with GNU make set as the default
make. Use your favorite package manager to check their availability.
<pre>
% which gcc make
/usr/bin/gcc
/usr/bin/make
% apt list gcc make
gcc/focal,now 4:9.3.0-1ubuntu2 amd64 [installed]
make/focal,now 4.2.1-1.2 amd64 [installed]
</pre>
Use your favorite package manager if they need to be installed.
<pre>% sudo apt install gcc make</pre>
To check that make is actually GNU make:
<pre>
% make --version
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
</pre>
ncurses development library usually need to be installed. Query your
favorite package manager to check which packages are available for
installation:
<pre>% apt search libncurses</pre>
Use your favorite package manager to install the needed package:
<pre>% sudo apt install libncurses-dev</pre>
On Ubuntu, apt will select the package that matches your architecture
(amd64 or i386).
<h2>Getting the sources</h2>
µEMACS source code is available on
<a href="https://github.com/rfivet/uemacs">github</a> and mirrored at
<a href="https://git.sdf.org/rfivet/uemacs">git.sdf.org</a>. From github, you
can either clone the
<a href="https://github.com/rfivet/uemacs.git">git repository</a> or download a
<a href="https://github.com/rfivet/uemacs/archive/master.zip">zip archive</a>.
<p>
Move to working directory and clone:
<pre>
% mkdir ~/Projects
% cd ~/Projects
% git clone https://github.com/rfivet/uemacs.git
</pre>
<h2>Building</h2>
<pre>
% cd ~/Projects/uemacs
% make
</pre>
If <b>GNU make</b> is not set as the default make you will have to call it
explicitly
<pre>% gmake</pre>
<h2>Testing</h2>
Start the editor:
<pre>% ./ue</pre>
To leave the editor type CTL-X CTL-C
<p>
Execute a sample script:
<pre>% ./ue -x screensize.cmd</pre>
<img src="img/ue_screensize.png" alt="Executing script screensize.cmd">
<hr>© 2020-2024 Renaud Fivet
</body>
</html>

View File

@@ -111,8 +111,8 @@ Pipe command .......... ^X @ Execute buffer ........ not bound
Search forward ........ Meta S :: End string with Meta.
Incremental search .... ^X S :: Search next ^X, stop Meta, cancel ^G.
Search reverse ........ ^R
Reverse incremental search Hunt forward .......... Alt-S
....................... ^X R Hunt backward ......... Alt-R
Reverse incremental Hunt forward .......... Alt-S
search ^X R Hunt backward ......... Alt-R
Replace string ........ Meta R
Query replace string .. Meta ^R :: Yes/no Y/N, replace rest !, cancel ^G.
-------------------------------------------------------------------------------
@@ -164,9 +164,9 @@ Page overlap .......... $overlap :: # lines, default 0, 0 = 1/3 page
=> FILE NAME COMPLETION
File name completion can be used with all file commands (find-file,
view-file, ...) but it works only under UNIX and MS-DOS. It is invoked
by a <Space> or <Tab>. If there exist more than one possible completions
they are displayed one by one. If the file name contains wild card
characters, the name is expanded instead of simple completion. Special
characters can be entered verbatim by prefixing them with ^V (or ^Q).
view-file, ...). It is invoked by a <Space> or <Tab>. If there exist more
than one possible completions they are displayed one by one. If the file
name contains wild card characters, the name is expanded instead of simple
completion. Special characters can be entered verbatim by prefixing them
with ^V (or ^Q).
-------------------------------------------------------------------------------

18
eval.c
View File

@@ -395,13 +395,8 @@ static const char *gtfun( char *fname) {
case UFLEFT:
sz1 = strlen( argv[ 0]) ;
sz = 0 ;
for( int i = atoi( argv[ 1]) ; i > 0 ; i -= 1) {
unicode_t c ;
for( int i = atoi( argv[ 1]) ; sz < sz1 && i > 0 ; i -= 1)
sz += utf8_to_unicode( argv[ 0], sz, sz1, &c) ;
if( sz == sz1)
break ;
}
if( sz >= ressize) {
free( result) ;
@@ -431,19 +426,12 @@ static const char *gtfun( char *fname) {
case UFMID:
sz1 = strlen( argv[ 0]) ;
int start = 0 ;
for( i = atoi( argv[ 1]) - 1 ; i > 0 ; i -= 1) {
for( i = atoi( argv[ 1]) - 1 ; start < sz1 && i > 0 ; i -= 1)
start += utf8_to_unicode( argv[ 0], start, sz1, &c) ;
if( start == sz1)
break ;
}
sz = start ;
if( sz < sz1)
for( i = atoi( argv[ 2]) ; i > 0 ; i -= 1) {
for( i = atoi( argv[ 2]) ; sz < sz1 && i > 0 ; i -= 1)
sz += utf8_to_unicode( argv[ 0], sz, sz1, &c) ;
if( sz == sz1)
break ;
}
sz -= start ;
if( sz >= ressize) {

6
exec.c
View File

@@ -557,9 +557,7 @@ static int dobuf( buffer_p bp) {
/* remove leading spaces */
if( eline != lp->l_text) {
int size = lp->l_used = eol - eline ;
if( size)
memcpy( lp->l_text, eline, size) ;
memmove( lp->l_text, eline, size) ;
eline = lp->l_text ;
eol = &lp->l_text[ size] ;
}
@@ -595,7 +593,7 @@ static int dobuf( buffer_p bp) {
/* turn line into a string */
int size = lp->l_used - 6 ;
if( size)
memcpy( lp->l_text, &eline[ 6], size) ;
memmove( lp->l_text, &eline[ 6], size) ;
eline = lp->l_text ;
eline[ size] = 0 ;

3
file.c
View File

@@ -310,6 +310,7 @@ int readin( const char *fname, boolean lockfl) {
break ;
case FTYPE_MAC:
found_eol = EOL_MAC ;
curbp->b_mode |= MDMAC ;
break ;
case FTYPE_NONE:
found_eol = EOL_NONE ;
@@ -474,7 +475,7 @@ int writeout( const char *fn) {
mloutstr( "(Writing...)") ; /* tell us we are writing */
for( lp = lforw( curbp->b_linep) ; lp != curbp->b_linep ; lp = lforw( lp)) {
s = ffputline( lp->l_text, llength( lp), curbp->b_mode & MDDOS) ;
s = ffputline( lp->l_text, llength( lp), curbp->b_mode >> 8) ; // Mack Hack
if( s != FIOSUC)
break ;

View File

@@ -66,13 +66,14 @@ fio_code ffclose( void) {
buffer, and the "nbuf" is its length, less the free newline. Return the
status. Check only at the newline.
*/
fio_code ffputline( char *buf, int nbuf, int dosflag) {
fio_code ffputline( char *buf, int nbuf, int eolflag) {
fwrite( buf, 1, nbuf, ffp) ;
if( dosflag)
if( eolflag) // DOS and Mac
fputc( '\r', ffp) ;
fputc( '\n', ffp) ;
if( eolflag != 2) // Not Mac
fputc( '\n', ffp) ;
if( ferror( ffp))
return FIOERR ;

View File

@@ -28,7 +28,7 @@ extern int fpayload ; /* actual length of fline content */
fio_code ffclose( void) ;
fio_code ffgetline( void) ;
fio_code ffputline( char *buf, int nbuf, int dosflag) ;
fio_code ffputline( char *buf, int nbuf, int eolflag) ;
fio_code ffropen( const char *fn) ;
fio_code ffwopen( const char *fn) ;

View File

@@ -263,6 +263,7 @@ static BINDABLE( isearch) {
cmd_buff[--cmd_offset] = '\0'; /* Yes, delete last char */
curwp->w_dotp = curline; /* Reset the line pointer */
curwp->w_doto = curoff; /* and the offset */
curwp->w_flag |= WFMOVE ; /* Say we've moved */
n = init_direction; /* Reset the search direction */
mystrscpy( pat, pat_save, sizeof pat) ; /* Restore the old search str */
cmd_reexecute = 0; /* Start the whole mess over */

211
line.c
View File

@@ -38,11 +38,11 @@ static int ldelnewline( void) ;
* was taken up by the keycode structure).
*/
#define KBLOCK 248 /* sizeof kill buffer chunks */
#define KBLOCK 248 /* sizeof kill buffer chunks */
typedef struct kill {
struct kill *d_next ; /* Link to next chunk, NULL if last. */
char d_chunk[ KBLOCK] ; /* Deleted text. */
struct kill *d_next ; /* Link to next chunk, NULL if last. */
unsigned char d_chunk[ KBLOCK] ; /* Deleted text. */
} *kill_p ;
static kill_p kbufp = NULL ; /* current kill buffer chunk pointer */
@@ -57,7 +57,7 @@ static char *value = NULL ; /* temp buffer for value */
const char *getkill( void) {
/* no kill buffer or no memory .... just return a null string */
if( kbufh == NULL
|| (value = realloc( value, klen + 1)) == NULL)
|| (value = realloc( value, klen + 1)) == NULL)
return "" ;
char *cp = value ;
@@ -94,26 +94,26 @@ BBINDABLE( backchar) {
curwp->w_doto = llength( lp) ;
curwp->w_flag |= WFMOVE ;
} else {
unsigned pos ;
/* move back over combining unicode */
combined:
unsigned pos ;
/* move back over combining unicode */
combined:
pos = curwp->w_doto -= 1 ;
/* check if at end of unicode */
/* check if at end of unicode */
if( pos > 0) {
unsigned delta = utf8_revdelta(
(unsigned char *) &( (curwp->w_dotp)->l_text[ pos]), pos) ;
if( delta != 0) {
pos = curwp->w_doto -= delta ;
if( pos > 0) { /* check if on combining unicode */
unicode_t unc ;
utf8_to_unicode( curwp->w_dotp->l_text, pos,
llength( curwp->w_dotp), &unc) ;
if( utf8_width( unc) == 0)
goto combined ;
}
}
}
(unsigned char *) &( (curwp->w_dotp)->l_text[ pos]), pos) ;
if( delta != 0) {
pos = curwp->w_doto -= delta ;
if( pos > 0) { /* check if on combining unicode */
unicode_t unc ;
utf8_to_unicode( curwp->w_dotp->l_text, pos,
llength( curwp->w_dotp), &unc) ;
if( utf8_width( unc) == 0)
goto combined ;
}
}
}
}
}
@@ -215,7 +215,7 @@ void lfree( line_p lp) {
bp->b_dotp = lp->l_fp ;
bp->b_doto = 0 ;
}
if( bp->b_markp == lp) {
bp->b_markp = lp->l_fp ;
bp->b_marko = 0 ;
@@ -270,7 +270,7 @@ boolean linstr( char *instr) {
while( (c = (unsigned char) *instr++)) {
status = (c == '\n') ? lnewline() : linsert_byte( 1, c) ;
if( status != TRUE) { /* Insertion error? */
if( status != TRUE) { /* Insertion error? */
mloutstr( "%Out of memory while inserting") ;
break ;
}
@@ -293,13 +293,13 @@ boolean linstr( char *instr) {
boolean linsert_byte( int n, int c) {
char *cp1;
char *cp2;
line_p lp2, lp3 ;
int i ;
line_p lp2 ;
int i ;
assert( (curbp->b_mode & MDVIEW) == 0) ;
lchange( WFEDIT) ;
line_p lp1 = curwp->w_dotp ; /* Current line */
line_p lp1 = curwp->w_dotp ; /* Current line */
if( lp1 == curbp->b_linep) { /* At the end: special */
if( curwp->w_doto != 0)
return mloutfail( "bug: linsert") ;
@@ -308,20 +308,38 @@ boolean linsert_byte( int n, int c) {
if( lp2 == NULL)
return FALSE ;
lp3 = lp1->l_bp ; /* Previous line */
lp3->l_fp = lp2 ; /* Link in */
/* Insert after previous line */
lp1->l_bp->l_fp = lp2 ;
lp2->l_fp = lp1 ;
lp2->l_bp = lp1->l_bp ;
lp1->l_bp = lp2 ;
lp2->l_bp = lp3 ;
for( i = 0 ; i < n ; ++i)
lp2->l_text[ i] = c ;
/* update point of current window */
curwp->w_dotp = lp2 ;
curwp->w_doto = n ;
/* update all windows displaying current buffer */
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
if( wp->w_bufp == curbp) {
/* update top window line */
if( wp->w_linep == lp1)
wp->w_linep = lp2 ;
/* dot at end of buffer is now at beginning of new line */
if( wp->w_dotp == lp1)
wp->w_dotp = lp2 ;
/* mark at end of buffer is now at beginning of new line */
if( wp->w_markp == lp1)
wp->w_markp = lp2 ;
}
return TRUE ;
}
int doto = curwp->w_doto ; /* Save for later. */
int doto = curwp->w_doto ; /* Save for later. */
if( lp1->l_used + n > lp1->l_size) { /* Hard: reallocate */
lp2 = lalloc( lp1->l_used + n) ;
if( lp2 == NULL)
@@ -447,37 +465,48 @@ boolean lnewline( void) {
#else
lchange(WFHARD);
#endif
line_p lp1 = curwp->w_dotp ; /* Get the address and */
int doto = curwp->w_doto ; /* offset of "." */
line_p lp2 = lalloc( doto) ; /* New first half line */
line_p lp1 = curwp->w_dotp ; /* Get the address and */
int doto = curwp->w_doto ; /* offset of "." */
/* at end of last line of non empty buffer */
if( lp1->l_fp == curbp->b_linep && lp1 != curbp->b_linep &&
doto == lp1->l_used) {
/* move dot at end of buffer, no nl inserted */
curwp->w_dotp = curbp->b_linep ;
curwp->w_doto = 0 ;
return TRUE ;
}
line_p lp2 = lalloc( doto) ; /* New first half line */
if( lp2 == NULL)
return FALSE ;
memcpy( lp2->l_text, lp1->l_text, doto) ;
lp1->l_used -= doto ;
memcpy( lp1->l_text, &lp1->l_text[ doto], lp1->l_used) ;
memmove( lp1->l_text, &lp1->l_text[ doto], lp1->l_used) ;
lp2->l_fp = lp1 ;
lp2->l_bp = lp1->l_bp ;
lp1->l_bp = lp2 ;
lp2->l_bp->l_fp = lp2 ;
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
if( wp->w_linep == lp1)
wp->w_linep = lp2 ;
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
if( wp->w_bufp == curbp) {
if( wp->w_linep == lp1) /* adjust top line of window */
wp->w_linep = lp2 ;
if( wp->w_dotp == lp1) {
if( wp->w_doto < doto)
wp->w_dotp = lp2 ;
else
wp->w_doto -= doto ;
}
if( wp->w_dotp == lp1) {
if( wp == curwp || wp->w_doto > doto)
wp->w_doto -= doto ;
else
wp->w_dotp = lp2 ;
}
if (wp->w_markp == lp1) {
if( wp->w_marko < doto)
wp->w_markp = lp2 ;
else
wp->w_marko -= doto ;
if( wp->w_markp == lp1) {
if( wp->w_marko > doto)
wp->w_marko -= doto ;
else
wp->w_markp = lp2 ;
}
}
}
return TRUE ;
}
@@ -487,8 +516,8 @@ boolean lnewline( void) {
* get unicode value and return UTF-8 size of character at dot.
*/
int lgetchar( unicode_t *cp) {
if( curwp->w_dotp->l_used == curwp->w_doto) { /* at EOL? */
*cp = (curbp->b_mode & MDDOS) ? '\r' : '\n' ;
if( curwp->w_dotp->l_used == curwp->w_doto) { /* at EOL? */
*cp = (curbp->b_mode & (MDDOS | MDMAC)) ? '\r' : '\n' ;
return 1 ;
} else
return utf8_to_unicode( curwp->w_dotp->l_text, curwp->w_doto,
@@ -500,28 +529,28 @@ int lgetchar( unicode_t *cp) {
* return total UTF-8 size of combined character at dot.
*/
static int lcombinedsize( void) {
if( curwp->w_dotp->l_used == curwp->w_doto) /* EOL? */
if( curwp->w_dotp->l_used == curwp->w_doto) /* EOL? */
return 1 ;
else {
unicode_t c ;
unicode_t c ;
int pos = curwp->w_doto ;
int pos = curwp->w_doto ;
unsigned bytes = utf8_to_unicode( curwp->w_dotp->l_text, pos,
llength( curwp->w_dotp), &c) ;
/* check if followed by combining unicode character */
pos += bytes ;
while( pos < llength( curwp->w_dotp) - 1) { /* at least 2 bytes */
unsigned cnt = utf8_to_unicode( curwp->w_dotp->l_text, pos,
/* check if followed by combining unicode character */
pos += bytes ;
while( pos < llength( curwp->w_dotp) - 1) { /* at least 2 bytes */
unsigned cnt = utf8_to_unicode( curwp->w_dotp->l_text, pos,
llength( curwp->w_dotp), &c) ;
if( utf8_width( c) == 0) {
bytes += cnt ;
pos += cnt ;
} else
break ;
}
return bytes ;
}
if( utf8_width( c) == 0) {
bytes += cnt ;
pos += cnt ;
} else
break ;
}
return bytes ;
}
}
@@ -557,11 +586,11 @@ boolean ldelete( long n, boolean kflag) {
while( n > 0) {
line_p dotp = curwp->w_dotp ;
if( dotp == curbp->b_linep) /* Hit end of buffer. */
if( dotp == curbp->b_linep) /* Hit end of buffer. */
return FALSE ;
int doto = curwp->w_doto ;
int chunk = dotp->l_used - doto ; /* Size of chunk. */
int chunk = dotp->l_used - doto ; /* Size of chunk. */
if( chunk == 0) { /* End of line, merge. */
#if SCROLLCODE
lchange( WFHARD | WFKILLS) ;
@@ -578,13 +607,13 @@ boolean ldelete( long n, boolean kflag) {
chunk = n ;
lchange( WFEDIT) ;
char *cp1 = &dotp->l_text[ doto] ; /* Scrunch text. */
char *cp1 = &dotp->l_text[ doto] ; /* Scrunch text. */
char *cp2 = cp1 + chunk ;
if( kflag != FALSE) { /* Kill? */
while( cp1 != cp2) {
if( kinsert( *cp1) == FALSE)
return FALSE ;
++cp1 ;
}
@@ -596,7 +625,7 @@ boolean ldelete( long n, boolean kflag) {
dotp->l_used -= chunk ;
/* Fix windows */
/* Fix windows */
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
if( wp->w_dotp == dotp && wp->w_doto >= doto) {
wp->w_doto -= chunk ;
@@ -629,7 +658,7 @@ boolean ldelete( long n, boolean kflag) {
static int ldelnewline( void) {
char *cp1;
char *cp2;
window_p wp ;
window_p wp ;
assert( (curbp->b_mode & MDVIEW) == 0) ;
@@ -641,7 +670,7 @@ static int ldelnewline( void) {
return TRUE ;
}
if( lp2->l_used <= lp1->l_size - lp1->l_used) {
cp1 = &lp1->l_text[ lp1->l_used] ;
cp2 = lp2->l_text ;
@@ -719,7 +748,7 @@ static int ldelnewline( void) {
void kdelete( void) {
if( kbufh != NULL) {
/* first, delete all the chunks */
freelist( (list_p) kbufh) ;
freelist( (list_p) kbufh) ;
/* and reset all the kill buffer pointers */
kbufh = kbufp = NULL ;
@@ -770,40 +799,28 @@ int kinsert( int c) {
* check for errors. Bound to "C-Y".
*/
BINDABLE( yank) {
int c;
int i;
char *sp; /* pointer into string to insert */
kill_p kp; /* pointer into kill buffer */
assert( !(curbp->b_mode & MDVIEW)) ;
if (n < 0)
return FALSE;
/* make sure there is something to yank */
/* make sure there is something to yank */
if (kbufh == NULL)
return TRUE; /* not an error, just nothing */
/* for each time.... */
/* for each time.... */
while (n--) {
kp = kbufh;
while (kp != NULL) {
if (kp->d_next == NULL)
i = kused;
else
i = KBLOCK;
sp = kp->d_chunk;
for( kill_p kp = kbufh ; kp != NULL ; kp = kp->d_next) {
unsigned char *sp = kp->d_chunk ;
int i = (kp->d_next == NULL) ? kused : KBLOCK ;
while (i--) {
if ((c = *sp++) == '\n') {
if (lnewline() == FALSE)
return FALSE;
} else {
if (linsert_byte(1, c) == FALSE)
return FALSE;
}
int c = *sp++ ;
if( FALSE == (( c == '\n') ? lnewline() : linsert_byte( 1, c)))
return FALSE ;
}
kp = kp->d_next;
}
}
return TRUE;
}

1
main.c
View File

@@ -69,6 +69,7 @@
#include "defines.h" /* OS specific customization */
#if UNIX
# include <signal.h>
# include <unistd.h>
#endif
#include "basic.h"

View File

@@ -12,11 +12,7 @@
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#ifdef SVR4
#include <string.h>
#else
#include <strings.h>
#endif
#include <errno.h>
#include "util.h"

View File

@@ -31,8 +31,12 @@ int ttcol = -1 ; /* Column location of HW cursor */
/* Define missing macroes for BSD and CYGWIN environment */
#if BSD
#define OLCUC 0000002
#define XCASE 0000004
# ifndef OLCUC
# define OLCUC 0000002
# endif
# ifndef XCASE
# define XCASE 0000004
# endif
#endif
#ifdef __CYGWIN__ /* gcc predefined (see cpp -dM) */

View File

@@ -814,10 +814,17 @@ static int adjustmode( int kind, int global) {
if( strcasecmp( cbuf, modename[ i]) == 0) {
/* finding a match, we process it */
if (kind == TRUE)
if (global)
if (global) {
if( i > 7) // Mac Hack
gmode &= 0xFF ;
gmode |= (1 << i);
else
} else {
if( i > 7) //Mac Hack
curbp->b_mode &= 0xFF ;
curbp->b_mode |= (1 << i);
}
else if (global)
gmode &= ~(1 << i);
else