From 203651b9b2e2f478c9a2be25f86ce9712a21a796 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 14:11:19 +0100 Subject: [PATCH 01/26] patch 8.1.0823: not sufficient testing of xxd Problem: Not sufficient testing of xxd. Solution: Add some more test coverage. --- src/testdir/test_xxd.vim | 20 +++++++++++++++++++- src/version.c | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim index b1a7b0888f..7762667119 100644 --- a/src/testdir/test_xxd.vim +++ b/src/testdir/test_xxd.vim @@ -75,7 +75,7 @@ func Test_xxd() let s:test += 1 for arg in ['-l 13', '-l13', '-len 13'] %d - exe '0r! ' . s:xxd_cmd . ' -s 0x36 -l 13 -cols 13 ' . fname + exe '0r! ' . s:xxd_cmd . ' -s 0x36 ' . arg . ' -cols 13 ' . fname $d call assert_equal('00000036: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test)) endfor @@ -131,6 +131,24 @@ func Test_xxd() call delete('XXDfile') endfor + " Test 11: reverse with CR, hex upper, Postscript style with a TAB + let s:test += 1 + call writefile([" 54455354\t610B6364 30390A TESTa\0x0bcd09.\r"], 'Xinput') + silent exe '!' . s:xxd_cmd . ' -r -p < Xinput > XXDfile' + let blob = readfile('XXDfile', 'B') + call assert_equal(0z54455354.610B6364.30390A, blob) + call delete('Xinput') + call delete('XXDfile') + + " Test 12: reverse with seek + let s:test += 1 + call writefile(["00000000: 54455354\t610B6364 30390A TESTa\0x0bcd09.\r"], 'Xinput') + silent exe '!' . s:xxd_cmd . ' -r -seek 5 < Xinput > XXDfile' + let blob = readfile('XXDfile', 'B') + call assert_equal(0z0000000000.54455354.610B6364.30390A, blob) + call delete('Xinput') + call delete('XXDfile') + " TODO: " -o -offset diff --git a/src/version.c b/src/version.c index 4d7730cf55..b9522911a4 100644 --- a/src/version.c +++ b/src/version.c @@ -787,6 +787,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 823, /**/ 822, /**/ From 1ecc5e4a995ade68ae216bb56f6ac9bd5c0b7e4b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 15:12:55 +0100 Subject: [PATCH 02/26] patch 8.1.0824: SunOS/Solaris has a problem with ttys Problem: SunOS/Solaris has a problem with ttys. Solution: Add mch_isatty() with extra handling for SunOS. (Ozaki Kiichi, closes #3865) --- src/auto/configure | 2 +- src/channel.c | 2 +- src/config.h.in | 1 + src/configure.ac | 2 +- src/os_unix.c | 129 ++++++++++++++++++++++++++++++--------------- src/proto/pty.pro | 5 +- src/pty.c | 66 ++++++++++++++++------- src/terminal.c | 6 +-- src/version.c | 2 + 9 files changed, 147 insertions(+), 68 deletions(-) diff --git a/src/auto/configure b/src/auto/configure index a3302d2857..8052cebf6e 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -11131,7 +11131,7 @@ for ac_header in stdint.h stdlib.h string.h \ unistd.h stropts.h errno.h sys/resource.h \ sys/systeminfo.h locale.h sys/stream.h termios.h \ libc.h sys/statfs.h poll.h sys/poll.h pwd.h \ - utime.h sys/param.h libintl.h libgen.h \ + utime.h sys/param.h sys/ptms.h libintl.h libgen.h \ util/debug.h util/msg18n.h frame.h sys/acl.h \ sys/access.h sys/sysinfo.h wchar.h wctype.h do : diff --git a/src/channel.c b/src/channel.c index b013a8558d..7c649b1714 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1048,7 +1048,7 @@ channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err) # if defined(UNIX) /* Do not end the job when all output channels are closed, wait until * the job ended. */ - if (isatty(in)) + if (mch_isatty(in)) channel->ch_to_be_closed |= (1U << PART_IN); # endif } diff --git a/src/config.h.in b/src/config.h.in index e13cc635f6..d1aaf708ea 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -258,6 +258,7 @@ #undef HAVE_SYS_PARAM_H #undef HAVE_SYS_POLL_H #undef HAVE_SYS_PTEM_H +#undef HAVE_SYS_PTMS_H #undef HAVE_SYS_RESOURCE_H #undef HAVE_SYS_SELECT_H #undef HAVE_SYS_STATFS_H diff --git a/src/configure.ac b/src/configure.ac index e5525eaa63..2b7725b0a7 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -3265,7 +3265,7 @@ AC_CHECK_HEADERS(stdint.h stdlib.h string.h \ unistd.h stropts.h errno.h sys/resource.h \ sys/systeminfo.h locale.h sys/stream.h termios.h \ libc.h sys/statfs.h poll.h sys/poll.h pwd.h \ - utime.h sys/param.h libintl.h libgen.h \ + utime.h sys/param.h sys/ptms.h libintl.h libgen.h \ util/debug.h util/msg18n.h frame.h sys/acl.h \ sys/access.h sys/sysinfo.h wchar.h wctype.h) diff --git a/src/os_unix.c b/src/os_unix.c index 5ab3bd3cf3..765cd57e7a 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -338,7 +338,9 @@ mch_chdir(char *path) } /* Why is NeXT excluded here (and not in os_unixx.h)? */ -#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__) +#if defined(ECHOE) && defined(ICANON) \ + && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) \ + && !defined(__NeXT__) # define NEW_TTY_SYSTEM #endif @@ -3448,6 +3450,58 @@ may_core_dump(void) #ifndef VMS +/* + * Get the file descriptor to use for tty operations. + */ + static int +get_tty_fd(int fd) +{ + int tty_fd = fd; + +#if defined(HAVE_SVR4_PTYS) && defined(SUN_SYSTEM) + // On SunOS: Get the terminal parameters from "fd", or the slave device of + // "fd" when it is a master device. + if (mch_isatty(fd) > 1) + { + char *name; + + name = ptsname(fd); + if (name == NULL) + return -1; + + tty_fd = open(name, O_RDONLY | O_NOCTTY | O_EXTRA, 0); + if (tty_fd < 0) + return -1; + } +#endif + return tty_fd; +} + + static int +mch_tcgetattr(int fd, void *term) +{ + int tty_fd; + int retval = -1; + + tty_fd = get_tty_fd(fd); + if (tty_fd >= 0) + { +#ifdef NEW_TTY_SYSTEM +# ifdef HAVE_TERMIOS_H + retval = tcgetattr(tty_fd, (struct termios *)term); +# else + retval = ioctl(tty_fd, TCGETA, (struct termio *)term); +# endif +#else + // for "old" tty systems + retval = ioctl(tty_fd, TIOCGETP, (struct sgttyb *)term); +#endif + if (tty_fd != fd) + close(tty_fd); + } + return retval; +} + void mch_settmode(int tmode) { @@ -3465,11 +3519,7 @@ mch_settmode(int tmode) if (first) { first = FALSE; -# if defined(HAVE_TERMIOS_H) - tcgetattr(read_cmd_fd, &told); -# else - ioctl(read_cmd_fd, TCGETA, &told); -# endif + mch_tcgetattr(read_cmd_fd, &told); } tnew = told; @@ -3527,7 +3577,7 @@ mch_settmode(int tmode) if (first) { first = FALSE; - ioctl(read_cmd_fd, TIOCGETP, &ttybold); + mch_tcgetattr(read_cmd_fd, &ttybold); } ttybnew = ttybold; @@ -3587,13 +3637,7 @@ get_tty_info(int fd, ttyinfo_T *info) struct termio keys; # endif - if ( -# if defined(HAVE_TERMIOS_H) - tcgetattr(fd, &keys) != -1 -# else - ioctl(fd, TCGETA, &keys) != -1 -# endif - ) + if (mch_tcgetattr(fd, &keys) != -1) { info->backspace = keys.c_cc[VERASE]; info->interrupt = keys.c_cc[VINTR]; @@ -3611,7 +3655,7 @@ get_tty_info(int fd, ttyinfo_T *info) /* for "old" tty systems */ struct sgttyb keys; - if (ioctl(fd, TIOCGETP, &keys) != -1) + if (mch_tcgetattr(fd, &keys) != -1) { info->backspace = keys.sg_erase; info->interrupt = keys.sg_kill; @@ -4070,34 +4114,35 @@ mch_get_shellsize(void) int mch_report_winsize(int fd, int rows, int cols) { -# ifdef TIOCSWINSZ - struct winsize ws; + int tty_fd; + int retval = -1; - ws.ws_col = cols; - ws.ws_row = rows; - ws.ws_xpixel = cols * 5; - ws.ws_ypixel = rows * 10; - if (ioctl(fd, TIOCSWINSZ, &ws) == 0) + tty_fd = get_tty_fd(fd); + if (tty_fd >= 0) { - ch_log(NULL, "ioctl(TIOCSWINSZ) success"); - return OK; - } - ch_log(NULL, "ioctl(TIOCSWINSZ) failed"); -# else -# ifdef TIOCSSIZE - struct ttysize ts; +# if defined(TIOCSWINSZ) + struct winsize ws; - ts.ts_cols = cols; - ts.ts_lines = rows; - if (ioctl(fd, TIOCSSIZE, &ws) == 0) - { - ch_log(NULL, "ioctl(TIOCSSIZE) success"); - return OK; - } - ch_log(NULL, "ioctl(TIOCSSIZE) failed"); -# endif + ws.ws_col = cols; + ws.ws_row = rows; + ws.ws_xpixel = cols * 5; + ws.ws_ypixel = rows * 10; + retval = ioctl(tty_fd, TIOCSWINSZ, &ws); + ch_log(NULL, "ioctl(TIOCSWINSZ) %s", + retval == 0 ? "success" : "failed"); +# elif defined(TIOCSSIZE) + struct ttysize ts; + + ts.ts_cols = cols; + ts.ts_lines = rows; + retval = ioctl(tty_fd, TIOCSSIZE, &ts); + ch_log(NULL, "ioctl(TIOCSSIZE) %s", + retval == 0 ? "success" : "failed"); # endif - return FAIL; + if (tty_fd != fd) + close(tty_fd); + } + return retval == 0 ? OK : FAIL; } #endif @@ -4273,7 +4318,7 @@ open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **namep) { char *tty_name; - *pty_master_fd = OpenPTY(&tty_name); /* open pty */ + *pty_master_fd = mch_openpty(&tty_name); // open pty if (*pty_master_fd >= 0) { /* Leaving out O_NOCTTY may lead to waitpid() always returning @@ -4721,7 +4766,7 @@ mch_call_shell_fork( { /* push stream discipline modules */ if (options & SHELL_COOKED) - SetupSlavePTY(pty_slave_fd); + setup_slavepty(pty_slave_fd); # ifdef TIOCSCTTY /* Try to become controlling tty (probably doesn't work, * unless run by root) */ @@ -5579,7 +5624,7 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal) if (pty_slave_fd >= 0) { /* push stream discipline modules */ - SetupSlavePTY(pty_slave_fd); + setup_slavepty(pty_slave_fd); # ifdef TIOCSCTTY /* Try to become controlling tty (probably doesn't work, * unless run by root) */ diff --git a/src/proto/pty.pro b/src/proto/pty.pro index 35e5c2b7ac..52e20ef674 100644 --- a/src/proto/pty.pro +++ b/src/proto/pty.pro @@ -1,4 +1,5 @@ /* pty.c */ -int SetupSlavePTY(int fd); -int OpenPTY(char **ttyn); +int setup_slavepty(int fd); +int mch_openpty(char **ttyn); +int mch_isatty(int fd); /* vim: set ft=c : */ diff --git a/src/pty.c b/src/pty.c index 7171734758..23ea0c06c5 100644 --- a/src/pty.c +++ b/src/pty.c @@ -56,16 +56,19 @@ #endif #if HAVE_STROPTS_H -#include -#ifdef sinix -#define buf_T __system_buf_t__ -#endif -#include -#ifdef sinix -#undef buf_T -#endif +# include +# ifdef sinix +# define buf_T __system_buf_t__ +# endif +# include +# ifdef sinix +# undef buf_T +# endif # ifdef SUN_SYSTEM # include +# if defined(HAVE_SYS_PTMS_H) && defined(HAVE_SVR4_PTYS) +# include +# endif # endif #endif @@ -155,11 +158,12 @@ initmaster(int f UNUSED) * pty on others. Needs to be tuned... */ int -SetupSlavePTY(int fd) +setup_slavepty(int fd) { if (fd < 0) return 0; -#if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) && !defined(linux) && !defined(__osf__) && !defined(M_UNIX) +#if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) \ + && !defined(linux) && !defined(__osf__) && !defined(M_UNIX) # if defined(HAVE_SYS_PTEM_H) || defined(hpux) if (ioctl(fd, I_PUSH, "ptem") != 0) return -1; @@ -178,7 +182,7 @@ SetupSlavePTY(int fd) #if defined(OSX) && !defined(PTY_DONE) #define PTY_DONE int -OpenPTY(char **ttyn) +mch_openpty(char **ttyn) { int f; static char TtyName[32]; @@ -195,7 +199,7 @@ OpenPTY(char **ttyn) && !defined(PTY_DONE) #define PTY_DONE int -OpenPTY(char **ttyn) +mch_openpty(char **ttyn) { char *m, *s; int f; @@ -219,7 +223,7 @@ OpenPTY(char **ttyn) #if defined(__sgi) && !defined(PTY_DONE) #define PTY_DONE int -OpenPTY(char **ttyn) +mch_openpty(char **ttyn) { int f; char *name; @@ -244,7 +248,7 @@ OpenPTY(char **ttyn) #if defined(MIPS) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE) #define PTY_DONE int -OpenPTY(char **ttyn) +mch_openpty(char **ttyn) { int f; stat_T buf; @@ -272,7 +276,7 @@ OpenPTY(char **ttyn) * Same for Mac OS X Leopard (10.5). */ #define PTY_DONE int -OpenPTY(char **ttyn) +mch_openpty(char **ttyn) { int f; char *m; @@ -313,7 +317,7 @@ int aixhack = -1; #endif int -OpenPTY(char **ttyn) +mch_openpty(char **ttyn) { int f; /* used for opening a new pty-pair: */ @@ -359,7 +363,7 @@ static char TtyProto[] = "/dev/ttyXY"; # endif int -OpenPTY(char **ttyn) +mch_openpty(char **ttyn) { char *p, *q, *l, *d; int f; @@ -410,4 +414,30 @@ OpenPTY(char **ttyn) } #endif -#endif /* FEAT_GUI || FEAT_TERMINAL */ +/* + * Call isatty(fd), except for SunOS where it's done differently. + */ + int +mch_isatty(int fd) +{ +# if defined(I_STR) && defined(HAVE_SYS_PTMS_H) && defined(HAVE_SVR4_PTYS) \ + && defined(SUN_SYSTEM) + // On SunOS, isatty() for /dev/ptmx returns false or sometimes can hang up + // in the inner ioctl(), and therefore first determine whether "fd" is a + // master device. + struct strioctl istr; + + istr.ic_cmd = ISPTM; + istr.ic_timout = 0; + istr.ic_dp = NULL; + istr.ic_len = 0; + + if (ioctl(fd, I_STR, &istr) == 0) + // Trick: return 2 in order to advice the caller that "fd" is a master + // device. cf. src/os_unix.c:get_tty_fd() + return 2; +# endif + return isatty(fd); +} + +#endif /* FEAT_GUI || FEAT_JOB_CHANNEL */ diff --git a/src/terminal.c b/src/terminal.c index d485b745f3..f33521a9f3 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -873,7 +873,7 @@ get_tty_part(term_T *term) { int fd = term->tl_job->jv_channel->ch_part[parts[i]].ch_fd; - if (isatty(fd)) + if (mch_isatty(fd)) return parts[i]; } #endif @@ -2182,7 +2182,7 @@ terminal_loop(int blocking) * them for every typed character is a bit of overhead, but it's needed * for the first character typed, e.g. when Vim starts in a shell. */ - if (isatty(tty_fd)) + if (mch_isatty(tty_fd)) { ttyinfo_T info; @@ -5882,7 +5882,7 @@ term_report_winsize(term_T *term, int rows, int cols) for (part = PART_OUT; part < PART_COUNT; ++part) { fd = term->tl_job->jv_channel->ch_part[part].ch_fd; - if (isatty(fd)) + if (mch_isatty(fd)) break; } if (part < PART_COUNT && mch_report_winsize(fd, rows, cols) == OK) diff --git a/src/version.c b/src/version.c index b9522911a4..ddf9b1496c 100644 --- a/src/version.c +++ b/src/version.c @@ -787,6 +787,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 824, /**/ 823, /**/ From 3e460fd8b72db905fbf9f01b00371384ffc415b8 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 16:21:07 +0100 Subject: [PATCH 03/26] patch 8.1.0825: code for autocommands is mixed with file I/O code Problem: Code for autocommands is mixed with file I/O code. Solution: Move autocommand code to a separate file. (Yegappan Lakshmanan, closes #3863) --- Filelist | 2 + src/Make_bc5.mak | 1 + src/Make_cyg_ming.mak | 1 + src/Make_dice.mak | 4 + src/Make_ivc.mak | 5 + src/Make_manx.mak | 6 + src/Make_morph.mak | 1 + src/Make_mvc.mak | 4 + src/Make_sas.mak | 5 + src/Make_vms.mms | 5 +- src/Makefile | 10 + src/README.txt | 1 + src/autocmd.c | 2579 ++++++++++++++++++++++++++++++++++++++++ src/fileio.c | 2588 +---------------------------------------- src/globals.h | 1 + src/proto.h | 1 + src/proto/autocmd.pro | 39 + src/proto/fileio.pro | 37 +- src/version.c | 2 + 19 files changed, 2672 insertions(+), 2620 deletions(-) create mode 100644 src/autocmd.c create mode 100644 src/proto/autocmd.pro diff --git a/Filelist b/Filelist index d3fcba6356..1eb9aa2cb0 100644 --- a/Filelist +++ b/Filelist @@ -14,6 +14,7 @@ SRC_ALL = \ src/arabic.c \ src/arabic.h \ src/ascii.h \ + src/autocmd.c \ src/beval.c \ src/beval.h \ src/blob.c \ @@ -146,6 +147,7 @@ SRC_ALL = \ src/proto.h \ src/protodef.h \ src/proto/arabic.pro \ + src/proto/autocmd.pro \ src/proto/beval.pro \ src/proto/blob.pro \ src/proto/blowfish.pro \ diff --git a/src/Make_bc5.mak b/src/Make_bc5.mak index 9760d8f7b2..d0d31d4eb9 100644 --- a/src/Make_bc5.mak +++ b/src/Make_bc5.mak @@ -525,6 +525,7 @@ vimwinmain = \ vimobj = \ $(OBJDIR)\arabic.obj \ + $(OBJDIR)\autocmd.obj \ $(OBJDIR)\blowfish.obj \ $(OBJDIR)\buffer.obj \ $(OBJDIR)\charset.obj \ diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 7aef61ac33..8d8666ffbe 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -695,6 +695,7 @@ GUIOBJ = $(OUTDIR)/gui.o $(OUTDIR)/gui_w32.o $(OUTDIR)/gui_beval.o $(OUTDIR)/os CUIOBJ = $(OUTDIR)/iscygpty.o OBJ = \ $(OUTDIR)/arabic.o \ + $(OUTDIR)/autocmd.o \ $(OUTDIR)/beval.o \ $(OUTDIR)/blob.o \ $(OUTDIR)/blowfish.o \ diff --git a/src/Make_dice.mak b/src/Make_dice.mak index 2daa8d72bf..83614ca911 100644 --- a/src/Make_dice.mak +++ b/src/Make_dice.mak @@ -27,6 +27,7 @@ LD = dcc SRC = \ arabic.c \ + autocmd.c \ blowfish.c \ buffer.c \ charset.c \ @@ -84,6 +85,7 @@ SRC = \ version.c OBJ = o/arabic.o \ + o/autocmd.o \ o/blowfish.o \ o/buffer.o \ o/charset.o \ @@ -161,6 +163,8 @@ $(SYMS) : vim.h globals.h keymap.h macros.h ascii.h term.h os_amiga.h structs.h o/arabic.o: arabic.c $(SYMS) +o/autocmd.o: autocmd.c $(SYMS) + o/blowfish.o: blowfish.c $(SYMS) o/buffer.o: buffer.c $(SYMS) diff --git a/src/Make_ivc.mak b/src/Make_ivc.mak index 784cab9312..0459984dab 100644 --- a/src/Make_ivc.mak +++ b/src/Make_ivc.mak @@ -211,6 +211,7 @@ ALL : .\$(VIM).exe vimrun.exe install.exe uninstal.exe xxd/xxd.exe GvimExt/gvime LINK32_OBJS= \ $(EXTRAS) \ "$(INTDIR)/arabic.obj" \ + "$(INTDIR)/autocmd.obj" \ "$(INTDIR)/blowfish.obj" \ "$(INTDIR)/buffer.obj" \ "$(INTDIR)/charset.obj" \ @@ -341,6 +342,10 @@ GvimExt/gvimext.dll: GvimExt/gvimext.cpp GvimExt/gvimext.rc GvimExt/gvimext.h SOURCE=.\arabic.c # End Source File # Begin Source File +# +SOURCE=.\autocmd.c +# End Source File +# Begin Source File SOURCE=.\blowfish.c # End Source File diff --git a/src/Make_manx.mak b/src/Make_manx.mak index 04560d4034..b71b923ded 100644 --- a/src/Make_manx.mak +++ b/src/Make_manx.mak @@ -37,6 +37,7 @@ REN = $(SHELL) -c mv -f DEL = $(SHELL) -c rm -f SRC = arabic.c \ + autocmd.c \ blowfish.c \ buffer.c \ charset.c \ @@ -96,6 +97,7 @@ SRC = arabic.c \ INCL = vim.h feature.h keymap.h macros.h ascii.h term.h structs.h os_amiga.h OBJ = obj/arabic.o \ + obj/autocmd.o \ obj/blowfish.o \ obj/buffer.o \ obj/charset.o \ @@ -153,6 +155,7 @@ OBJ = obj/arabic.o \ $(TERMLIB) PRO = proto/arabic.pro \ + proto/autocmd.pro \ proto/blowfish.pro \ proto/buffer.pro \ proto/charset.pro \ @@ -256,6 +259,9 @@ $(OBJ): $(SYMS) obj/arabic.o: arabic.c $(CCSYM) $@ arabic.c +obj/autocmd.o: autocmd.c + $(CCSYM) $@ autocmd.c + obj/blowfish.o: blowfish.c $(CCSYM) $@ blowfish.c diff --git a/src/Make_morph.mak b/src/Make_morph.mak index 70ab5377a3..ae490416f4 100644 --- a/src/Make_morph.mak +++ b/src/Make_morph.mak @@ -25,6 +25,7 @@ RM = rm ${CC} ${CFLAGS} $< -o $@ SRC = arabic.c \ + autocmd.c \ blowfish.c \ buffer.c \ charset.c \ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index a3c66819a5..3f8c8a0384 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -700,6 +700,7 @@ INCL = vim.h alloc.h arabic.h ascii.h ex_cmds.h farsi.h feature.h globals.h \ OBJ = \ $(OUTDIR)\arabic.obj \ + $(OUTDIR)\autocmd.obj \ $(OUTDIR)\beval.obj \ $(OUTDIR)\blob.obj \ $(OUTDIR)\blowfish.obj \ @@ -1345,6 +1346,8 @@ $(NEW_TESTS): $(OUTDIR)/arabic.obj: $(OUTDIR) arabic.c $(INCL) +$(OUTDIR)/autocmd.obj: $(OUTDIR) autocmd.c $(INCL) + $(OUTDIR)/beval.obj: $(OUTDIR) beval.c $(INCL) $(OUTDIR)/blob.obj: $(OUTDIR) blob.c $(INCL) @@ -1619,6 +1622,7 @@ auto: # End Custom Build proto.h: \ proto/arabic.pro \ + proto/autocmd.pro \ proto/blob.pro \ proto/blowfish.pro \ proto/buffer.pro \ diff --git a/src/Make_sas.mak b/src/Make_sas.mak index a16908e9c1..c621360eab 100644 --- a/src/Make_sas.mak +++ b/src/Make_sas.mak @@ -90,6 +90,7 @@ PROPT = DEF=PROTO GPROTO GPPARM MAXIMUMERRORS=999 GENPROTOSTATICS GENPROTOPARAME SRC = \ arabic.c \ + autocmd.c \ blowfish.c \ buffer.c \ charset.c \ @@ -148,6 +149,7 @@ SRC = \ OBJ = \ arabic.o \ + autocmd.o \ blowfish.o \ buffer.o \ charset.o \ @@ -206,6 +208,7 @@ OBJ = \ PRO = \ proto/arabic.pro \ + proto/autocmd.pro \ proto/blowfish.pro \ proto/buffer.pro \ proto/charset.pro \ @@ -319,6 +322,8 @@ $(PRO): $(GST) vim.h # dependencies arabic.o: arabic.c proto/arabic.pro: arabic.c +autocmd.o: autocmd.c +proto/autocmd.pro: autocmd.c blowfish.o: blowfish.c proto/blowfish.pro: blowfish.c buffer.o: buffer.c diff --git a/src/Make_vms.mms b/src/Make_vms.mms index 18c68142d8..6a3508980f 100644 --- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -312,7 +312,7 @@ ALL_CFLAGS_VER = /def=($(MODEL_DEF)$(DEFS)$(DEBUG_DEF)$(PERL_DEF)$(PYTHON_DEF) - ALL_LIBS = $(LIBS) $(GUI_LIB_DIR) $(GUI_LIB) \ $(PERL_LIB) $(PYTHON_LIB) $(TCL_LIB) $(RUBY_LIB) -SRC = arabic.c beval.obj blob.c blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c \ +SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c \ evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c if_xcmdsrv.c farsi.c fileio.c fold.c \ getchar.c hardcopy.c hashtab.c json.c list.c main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \ misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c search.c sha256.c sign.c \ @@ -321,7 +321,7 @@ SRC = arabic.c beval.obj blob.c blowfish.c buffer.c charset.c crypt.c crypt_zip. $(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \ $(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC) -OBJ = arabic.obj beval.obj blob.obj blowfish.obj buffer.obj charset.obj crypt.obj crypt_zip.obj dict.obj diff.obj digraph.obj \ +OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj charset.obj crypt.obj crypt_zip.obj dict.obj diff.obj digraph.obj \ edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj \ if_xcmdsrv.obj farsi.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj json.obj list.obj main.obj mark.obj \ menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \ @@ -500,6 +500,7 @@ ruby_env : .ENDIF arabic.obj : arabic.c vim.h +autocmd.obj : autocmd.c vim.h [.auto]config.h feature.h os_unix.h blowfish.obj : blowfish.c vim.h [.auto]config.h feature.h os_unix.h blob.obj : blob.c vim.h [.auto]config.h feature.h os_unix.h buffer.obj : buffer.c vim.h [.auto]config.h feature.h os_unix.h \ diff --git a/src/Makefile b/src/Makefile index 23f01c38bc..2c409f0a62 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1572,6 +1572,7 @@ include testdir/Make_all.mak BASIC_SRC = \ arabic.c \ + autocmd.c \ beval.c \ blob.c \ blowfish.c \ @@ -1684,6 +1685,7 @@ LINT_SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) \ OBJ_COMMON = \ objects/arabic.o \ + objects/autocmd.o \ objects/beval.o \ objects/buffer.o \ objects/blob.o \ @@ -1809,6 +1811,7 @@ ALL_OBJ = $(OBJ_COMMON) \ PRO_AUTO = \ arabic.pro \ + autocmd.pro \ blowfish.pro \ buffer.pro \ charset.pro \ @@ -2934,6 +2937,9 @@ $(ALL_OBJ): objects/.dirstamp objects/arabic.o: arabic.c $(CCC) -o $@ arabic.c +objects/autocmd.o: autocmd.c + $(CCC) -o $@ autocmd.c + objects/blob.o: blob.c $(CCC) -o $@ blob.c @@ -3376,6 +3382,10 @@ objects/arabic.o: arabic.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h farsi.h arabic.h +objects/autocmd.o: autocmd.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h os_mac.h ascii.h keymap.h term.h macros.h option.h beval.h \ + structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h proto.h globals.h \ + farsi.h arabic.h objects/beval.o: beval.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/README.txt b/src/README.txt index 6e7094cec0..e1dc36f69c 100644 --- a/src/README.txt +++ b/src/README.txt @@ -17,6 +17,7 @@ use the CTRL-] command. Use CTRL-T or CTRL-O to jump back. To jump to a file, move the cursor on its name and use the "gf" command. Most code can be found in a file with an obvious name (incomplete list): + autocmd.c autocommands buffer.c manipulating buffers (loaded files) diff.c diff mode (vimdiff) eval.c expression evaluation diff --git a/src/autocmd.c b/src/autocmd.c new file mode 100644 index 0000000000..55650b46f7 --- /dev/null +++ b/src/autocmd.c @@ -0,0 +1,2579 @@ +/* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +/* + * autocmd.c: Autocommand related functions + */ + +#include "vim.h" + +/* + * The autocommands are stored in a list for each event. + * Autocommands for the same pattern, that are consecutive, are joined + * together, to avoid having to match the pattern too often. + * The result is an array of Autopat lists, which point to AutoCmd lists: + * + * last_autopat[0] -----------------------------+ + * V + * first_autopat[0] --> Autopat.next --> Autopat.next --> NULL + * Autopat.cmds Autopat.cmds + * | | + * V V + * AutoCmd.next AutoCmd.next + * | | + * V V + * AutoCmd.next NULL + * | + * V + * NULL + * + * last_autopat[1] --------+ + * V + * first_autopat[1] --> Autopat.next --> NULL + * Autopat.cmds + * | + * V + * AutoCmd.next + * | + * V + * NULL + * etc. + * + * The order of AutoCmds is important, this is the order in which they were + * defined and will have to be executed. + */ +typedef struct AutoCmd +{ + char_u *cmd; // The command to be executed (NULL + // when command has been removed). + char nested; // If autocommands nest here. + char last; // last command in list +#ifdef FEAT_EVAL + sctx_T script_ctx; // script context where defined +#endif + struct AutoCmd *next; // next AutoCmd in list +} AutoCmd; + +typedef struct AutoPat +{ + struct AutoPat *next; // Next AutoPat in AutoPat list; MUST + // be the first entry. + char_u *pat; // pattern as typed (NULL when pattern + // has been removed) + regprog_T *reg_prog; // compiled regprog for pattern + AutoCmd *cmds; // list of commands to do + int group; // group ID + int patlen; // strlen() of pat + int buflocal_nr; // !=0 for buffer-local AutoPat + char allow_dirs; // Pattern may match whole path + char last; // last pattern for apply_autocmds() +} AutoPat; + +static struct event_name +{ + char *name; // event name + event_T event; // event number +} event_names[] = +{ + {"BufAdd", EVENT_BUFADD}, + {"BufCreate", EVENT_BUFADD}, + {"BufDelete", EVENT_BUFDELETE}, + {"BufEnter", EVENT_BUFENTER}, + {"BufFilePost", EVENT_BUFFILEPOST}, + {"BufFilePre", EVENT_BUFFILEPRE}, + {"BufHidden", EVENT_BUFHIDDEN}, + {"BufLeave", EVENT_BUFLEAVE}, + {"BufNew", EVENT_BUFNEW}, + {"BufNewFile", EVENT_BUFNEWFILE}, + {"BufRead", EVENT_BUFREADPOST}, + {"BufReadCmd", EVENT_BUFREADCMD}, + {"BufReadPost", EVENT_BUFREADPOST}, + {"BufReadPre", EVENT_BUFREADPRE}, + {"BufUnload", EVENT_BUFUNLOAD}, + {"BufWinEnter", EVENT_BUFWINENTER}, + {"BufWinLeave", EVENT_BUFWINLEAVE}, + {"BufWipeout", EVENT_BUFWIPEOUT}, + {"BufWrite", EVENT_BUFWRITEPRE}, + {"BufWritePost", EVENT_BUFWRITEPOST}, + {"BufWritePre", EVENT_BUFWRITEPRE}, + {"BufWriteCmd", EVENT_BUFWRITECMD}, + {"CmdlineChanged", EVENT_CMDLINECHANGED}, + {"CmdlineEnter", EVENT_CMDLINEENTER}, + {"CmdlineLeave", EVENT_CMDLINELEAVE}, + {"CmdwinEnter", EVENT_CMDWINENTER}, + {"CmdwinLeave", EVENT_CMDWINLEAVE}, + {"CmdUndefined", EVENT_CMDUNDEFINED}, + {"ColorScheme", EVENT_COLORSCHEME}, + {"ColorSchemePre", EVENT_COLORSCHEMEPRE}, + {"CompleteDone", EVENT_COMPLETEDONE}, + {"CursorHold", EVENT_CURSORHOLD}, + {"CursorHoldI", EVENT_CURSORHOLDI}, + {"CursorMoved", EVENT_CURSORMOVED}, + {"CursorMovedI", EVENT_CURSORMOVEDI}, + {"DiffUpdated", EVENT_DIFFUPDATED}, + {"DirChanged", EVENT_DIRCHANGED}, + {"EncodingChanged", EVENT_ENCODINGCHANGED}, + {"ExitPre", EVENT_EXITPRE}, + {"FileEncoding", EVENT_ENCODINGCHANGED}, + {"FileAppendPost", EVENT_FILEAPPENDPOST}, + {"FileAppendPre", EVENT_FILEAPPENDPRE}, + {"FileAppendCmd", EVENT_FILEAPPENDCMD}, + {"FileChangedShell",EVENT_FILECHANGEDSHELL}, + {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST}, + {"FileChangedRO", EVENT_FILECHANGEDRO}, + {"FileReadPost", EVENT_FILEREADPOST}, + {"FileReadPre", EVENT_FILEREADPRE}, + {"FileReadCmd", EVENT_FILEREADCMD}, + {"FileType", EVENT_FILETYPE}, + {"FileWritePost", EVENT_FILEWRITEPOST}, + {"FileWritePre", EVENT_FILEWRITEPRE}, + {"FileWriteCmd", EVENT_FILEWRITECMD}, + {"FilterReadPost", EVENT_FILTERREADPOST}, + {"FilterReadPre", EVENT_FILTERREADPRE}, + {"FilterWritePost", EVENT_FILTERWRITEPOST}, + {"FilterWritePre", EVENT_FILTERWRITEPRE}, + {"FocusGained", EVENT_FOCUSGAINED}, + {"FocusLost", EVENT_FOCUSLOST}, + {"FuncUndefined", EVENT_FUNCUNDEFINED}, + {"GUIEnter", EVENT_GUIENTER}, + {"GUIFailed", EVENT_GUIFAILED}, + {"InsertChange", EVENT_INSERTCHANGE}, + {"InsertEnter", EVENT_INSERTENTER}, + {"InsertLeave", EVENT_INSERTLEAVE}, + {"InsertCharPre", EVENT_INSERTCHARPRE}, + {"MenuPopup", EVENT_MENUPOPUP}, + {"OptionSet", EVENT_OPTIONSET}, + {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST}, + {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE}, + {"QuitPre", EVENT_QUITPRE}, + {"RemoteReply", EVENT_REMOTEREPLY}, + {"SessionLoadPost", EVENT_SESSIONLOADPOST}, + {"ShellCmdPost", EVENT_SHELLCMDPOST}, + {"ShellFilterPost", EVENT_SHELLFILTERPOST}, + {"SourceCmd", EVENT_SOURCECMD}, + {"SourcePre", EVENT_SOURCEPRE}, + {"SourcePost", EVENT_SOURCEPOST}, + {"SpellFileMissing",EVENT_SPELLFILEMISSING}, + {"StdinReadPost", EVENT_STDINREADPOST}, + {"StdinReadPre", EVENT_STDINREADPRE}, + {"SwapExists", EVENT_SWAPEXISTS}, + {"Syntax", EVENT_SYNTAX}, + {"TabNew", EVENT_TABNEW}, + {"TabClosed", EVENT_TABCLOSED}, + {"TabEnter", EVENT_TABENTER}, + {"TabLeave", EVENT_TABLEAVE}, + {"TermChanged", EVENT_TERMCHANGED}, + {"TerminalOpen", EVENT_TERMINALOPEN}, + {"TermResponse", EVENT_TERMRESPONSE}, + {"TextChanged", EVENT_TEXTCHANGED}, + {"TextChangedI", EVENT_TEXTCHANGEDI}, + {"TextChangedP", EVENT_TEXTCHANGEDP}, + {"User", EVENT_USER}, + {"VimEnter", EVENT_VIMENTER}, + {"VimLeave", EVENT_VIMLEAVE}, + {"VimLeavePre", EVENT_VIMLEAVEPRE}, + {"WinNew", EVENT_WINNEW}, + {"WinEnter", EVENT_WINENTER}, + {"WinLeave", EVENT_WINLEAVE}, + {"VimResized", EVENT_VIMRESIZED}, + {"TextYankPost", EVENT_TEXTYANKPOST}, + {NULL, (event_T)0} +}; + +static AutoPat *first_autopat[NUM_EVENTS] = +{ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static AutoPat *last_autopat[NUM_EVENTS] = +{ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#define AUGROUP_DEFAULT -1 // default autocmd group +#define AUGROUP_ERROR -2 // erroneous autocmd group +#define AUGROUP_ALL -3 // all autocmd groups + +/* + * struct used to keep status while executing autocommands for an event. + */ +typedef struct AutoPatCmd +{ + AutoPat *curpat; // next AutoPat to examine + AutoCmd *nextcmd; // next AutoCmd to execute + int group; // group being used + char_u *fname; // fname to match with + char_u *sfname; // sfname to match with + char_u *tail; // tail of fname + event_T event; // current event + int arg_bufnr; // Initially equal to , set to zero when + // buf is deleted. + struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation +} AutoPatCmd; + +static AutoPatCmd *active_apc_list = NULL; /* stack of active autocommands */ + +/* + * augroups stores a list of autocmd group names. + */ +static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL}; +#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i]) +/* use get_deleted_augroup() to get this */ +static char_u *deleted_augroup = NULL; + +/* + * Set by the apply_autocmds_group function if the given event is equal to + * EVENT_FILETYPE. Used by the readfile function in order to determine if + * EVENT_BUFREADPOST triggered the EVENT_FILETYPE. + * + * Relying on this value requires one to reset it prior calling + * apply_autocmds_group. + */ +int au_did_filetype INIT(= FALSE); + +/* + * The ID of the current group. Group 0 is the default one. + */ +static int current_augroup = AUGROUP_DEFAULT; + +static int au_need_clean = FALSE; /* need to delete marked patterns */ + +static char_u *event_nr2name(event_T event); +static int au_get_grouparg(char_u **argp); +static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group); +static int apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap); +static void auto_next_pat(AutoPatCmd *apc, int stop_at_last); +static int au_find_group(char_u *name); + +static event_T last_event; +static int last_group; +static int autocmd_blocked = 0; /* block all autocmds */ + + static char_u * +get_deleted_augroup(void) +{ + if (deleted_augroup == NULL) + deleted_augroup = (char_u *)_("--Deleted--"); + return deleted_augroup; +} + +/* + * Show the autocommands for one AutoPat. + */ + static void +show_autocmd(AutoPat *ap, event_T event) +{ + AutoCmd *ac; + + // Check for "got_int" (here and at various places below), which is set + // when "q" has been hit for the "--more--" prompt + if (got_int) + return; + if (ap->pat == NULL) // pattern has been removed + return; + + msg_putchar('\n'); + if (got_int) + return; + if (event != last_event || ap->group != last_group) + { + if (ap->group != AUGROUP_DEFAULT) + { + if (AUGROUP_NAME(ap->group) == NULL) + msg_puts_attr((char *)get_deleted_augroup(), HL_ATTR(HLF_E)); + else + msg_puts_attr((char *)AUGROUP_NAME(ap->group), HL_ATTR(HLF_T)); + msg_puts(" "); + } + msg_puts_attr((char *)event_nr2name(event), HL_ATTR(HLF_T)); + last_event = event; + last_group = ap->group; + msg_putchar('\n'); + if (got_int) + return; + } + msg_col = 4; + msg_outtrans(ap->pat); + + for (ac = ap->cmds; ac != NULL; ac = ac->next) + { + if (ac->cmd != NULL) // skip removed commands + { + if (msg_col >= 14) + msg_putchar('\n'); + msg_col = 14; + if (got_int) + return; + msg_outtrans(ac->cmd); +#ifdef FEAT_EVAL + if (p_verbose > 0) + last_set_msg(ac->script_ctx); +#endif + if (got_int) + return; + if (ac->next != NULL) + { + msg_putchar('\n'); + if (got_int) + return; + } + } + } +} + +/* + * Mark an autocommand pattern for deletion. + */ + static void +au_remove_pat(AutoPat *ap) +{ + VIM_CLEAR(ap->pat); + ap->buflocal_nr = -1; + au_need_clean = TRUE; +} + +/* + * Mark all commands for a pattern for deletion. + */ + static void +au_remove_cmds(AutoPat *ap) +{ + AutoCmd *ac; + + for (ac = ap->cmds; ac != NULL; ac = ac->next) + VIM_CLEAR(ac->cmd); + au_need_clean = TRUE; +} + +/* + * Cleanup autocommands and patterns that have been deleted. + * This is only done when not executing autocommands. + */ + static void +au_cleanup(void) +{ + AutoPat *ap, **prev_ap; + AutoCmd *ac, **prev_ac; + event_T event; + + if (autocmd_busy || !au_need_clean) + return; + + // loop over all events + for (event = (event_T)0; (int)event < (int)NUM_EVENTS; + event = (event_T)((int)event + 1)) + { + // loop over all autocommand patterns + prev_ap = &(first_autopat[(int)event]); + for (ap = *prev_ap; ap != NULL; ap = *prev_ap) + { + // loop over all commands for this pattern + prev_ac = &(ap->cmds); + for (ac = *prev_ac; ac != NULL; ac = *prev_ac) + { + // remove the command if the pattern is to be deleted or when + // the command has been marked for deletion + if (ap->pat == NULL || ac->cmd == NULL) + { + *prev_ac = ac->next; + vim_free(ac->cmd); + vim_free(ac); + } + else + prev_ac = &(ac->next); + } + + // remove the pattern if it has been marked for deletion + if (ap->pat == NULL) + { + if (ap->next == NULL) + { + if (prev_ap == &(first_autopat[(int)event])) + last_autopat[(int)event] = NULL; + else + // this depends on the "next" field being the first in + // the struct + last_autopat[(int)event] = (AutoPat *)prev_ap; + } + *prev_ap = ap->next; + vim_regfree(ap->reg_prog); + vim_free(ap); + } + else + prev_ap = &(ap->next); + } + } + + au_need_clean = FALSE; +} + +/* + * Called when buffer is freed, to remove/invalidate related buffer-local + * autocmds. + */ + void +aubuflocal_remove(buf_T *buf) +{ + AutoPat *ap; + event_T event; + AutoPatCmd *apc; + + // invalidate currently executing autocommands + for (apc = active_apc_list; apc; apc = apc->next) + if (buf->b_fnum == apc->arg_bufnr) + apc->arg_bufnr = 0; + + // invalidate buflocals looping through events + for (event = (event_T)0; (int)event < (int)NUM_EVENTS; + event = (event_T)((int)event + 1)) + // loop over all autocommand patterns + for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) + if (ap->buflocal_nr == buf->b_fnum) + { + au_remove_pat(ap); + if (p_verbose >= 6) + { + verbose_enter(); + smsg(_("auto-removing autocommand: %s "), + event_nr2name(event), buf->b_fnum); + verbose_leave(); + } + } + au_cleanup(); +} + +/* + * Add an autocmd group name. + * Return its ID. Returns AUGROUP_ERROR (< 0) for error. + */ + static int +au_new_group(char_u *name) +{ + int i; + + i = au_find_group(name); + if (i == AUGROUP_ERROR) // the group doesn't exist yet, add it + { + // First try using a free entry. + for (i = 0; i < augroups.ga_len; ++i) + if (AUGROUP_NAME(i) == NULL) + break; + if (i == augroups.ga_len && ga_grow(&augroups, 1) == FAIL) + return AUGROUP_ERROR; + + AUGROUP_NAME(i) = vim_strsave(name); + if (AUGROUP_NAME(i) == NULL) + return AUGROUP_ERROR; + if (i == augroups.ga_len) + ++augroups.ga_len; + } + + return i; +} + + static void +au_del_group(char_u *name) +{ + int i; + + i = au_find_group(name); + if (i == AUGROUP_ERROR) // the group doesn't exist + semsg(_("E367: No such group: \"%s\""), name); + else if (i == current_augroup) + emsg(_("E936: Cannot delete the current group")); + else + { + event_T event; + AutoPat *ap; + int in_use = FALSE; + + for (event = (event_T)0; (int)event < (int)NUM_EVENTS; + event = (event_T)((int)event + 1)) + { + for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) + if (ap->group == i && ap->pat != NULL) + { + give_warning((char_u *)_("W19: Deleting augroup that is still in use"), TRUE); + in_use = TRUE; + event = NUM_EVENTS; + break; + } + } + vim_free(AUGROUP_NAME(i)); + if (in_use) + { + AUGROUP_NAME(i) = get_deleted_augroup(); + } + else + AUGROUP_NAME(i) = NULL; + } +} + +/* + * Find the ID of an autocmd group name. + * Return its ID. Returns AUGROUP_ERROR (< 0) for error. + */ + static int +au_find_group(char_u *name) +{ + int i; + + for (i = 0; i < augroups.ga_len; ++i) + if (AUGROUP_NAME(i) != NULL && AUGROUP_NAME(i) != get_deleted_augroup() + && STRCMP(AUGROUP_NAME(i), name) == 0) + return i; + return AUGROUP_ERROR; +} + +/* + * Return TRUE if augroup "name" exists. + */ + int +au_has_group(char_u *name) +{ + return au_find_group(name) != AUGROUP_ERROR; +} + +/* + * ":augroup {name}". + */ + void +do_augroup(char_u *arg, int del_group) +{ + int i; + + if (del_group) + { + if (*arg == NUL) + emsg(_(e_argreq)); + else + au_del_group(arg); + } + else if (STRICMP(arg, "end") == 0) // ":aug end": back to group 0 + current_augroup = AUGROUP_DEFAULT; + else if (*arg) // ":aug xxx": switch to group xxx + { + i = au_new_group(arg); + if (i != AUGROUP_ERROR) + current_augroup = i; + } + else // ":aug": list the group names + { + msg_start(); + for (i = 0; i < augroups.ga_len; ++i) + { + if (AUGROUP_NAME(i) != NULL) + { + msg_puts((char *)AUGROUP_NAME(i)); + msg_puts(" "); + } + } + msg_clr_eos(); + msg_end(); + } +} + +#if defined(EXITFREE) || defined(PROTO) + void +free_all_autocmds(void) +{ + int i; + char_u *s; + + for (current_augroup = -1; current_augroup < augroups.ga_len; + ++current_augroup) + do_autocmd((char_u *)"", TRUE); + + for (i = 0; i < augroups.ga_len; ++i) + { + s = ((char_u **)(augroups.ga_data))[i]; + if (s != get_deleted_augroup()) + vim_free(s); + } + ga_clear(&augroups); +} +#endif + +/* + * Return the event number for event name "start". + * Return NUM_EVENTS if the event name was not found. + * Return a pointer to the next event name in "end". + */ + static event_T +event_name2nr(char_u *start, char_u **end) +{ + char_u *p; + int i; + int len; + + // the event name ends with end of line, '|', a blank or a comma + for (p = start; *p && !VIM_ISWHITE(*p) && *p != ',' && *p != '|'; ++p) + ; + for (i = 0; event_names[i].name != NULL; ++i) + { + len = (int)STRLEN(event_names[i].name); + if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0) + break; + } + if (*p == ',') + ++p; + *end = p; + if (event_names[i].name == NULL) + return NUM_EVENTS; + return event_names[i].event; +} + +/* + * Return the name for event "event". + */ + static char_u * +event_nr2name(event_T event) +{ + int i; + + for (i = 0; event_names[i].name != NULL; ++i) + if (event_names[i].event == event) + return (char_u *)event_names[i].name; + return (char_u *)"Unknown"; +} + +/* + * Scan over the events. "*" stands for all events. + */ + static char_u * +find_end_event( + char_u *arg, + int have_group) // TRUE when group name was found +{ + char_u *pat; + char_u *p; + + if (*arg == '*') + { + if (arg[1] && !VIM_ISWHITE(arg[1])) + { + semsg(_("E215: Illegal character after *: %s"), arg); + return NULL; + } + pat = arg + 1; + } + else + { + for (pat = arg; *pat && *pat != '|' && !VIM_ISWHITE(*pat); pat = p) + { + if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) + { + if (have_group) + semsg(_("E216: No such event: %s"), pat); + else + semsg(_("E216: No such group or event: %s"), pat); + return NULL; + } + } + } + return pat; +} + +/* + * Return TRUE if "event" is included in 'eventignore'. + */ + static int +event_ignored(event_T event) +{ + char_u *p = p_ei; + + while (*p != NUL) + { + if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) + return TRUE; + if (event_name2nr(p, &p) == event) + return TRUE; + } + + return FALSE; +} + +/* + * Return OK when the contents of p_ei is valid, FAIL otherwise. + */ + int +check_ei(void) +{ + char_u *p = p_ei; + + while (*p) + { + if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) + { + p += 3; + if (*p == ',') + ++p; + } + else if (event_name2nr(p, &p) == NUM_EVENTS) + return FAIL; + } + + return OK; +} + +# if defined(FEAT_SYN_HL) || defined(PROTO) + +/* + * Add "what" to 'eventignore' to skip loading syntax highlighting for every + * buffer loaded into the window. "what" must start with a comma. + * Returns the old value of 'eventignore' in allocated memory. + */ + char_u * +au_event_disable(char *what) +{ + char_u *new_ei; + char_u *save_ei; + + save_ei = vim_strsave(p_ei); + if (save_ei != NULL) + { + new_ei = vim_strnsave(p_ei, (int)(STRLEN(p_ei) + STRLEN(what))); + if (new_ei != NULL) + { + if (*what == ',' && *p_ei == NUL) + STRCPY(new_ei, what + 1); + else + STRCAT(new_ei, what); + set_string_option_direct((char_u *)"ei", -1, new_ei, + OPT_FREE, SID_NONE); + vim_free(new_ei); + } + } + return save_ei; +} + + void +au_event_restore(char_u *old_ei) +{ + if (old_ei != NULL) + { + set_string_option_direct((char_u *)"ei", -1, old_ei, + OPT_FREE, SID_NONE); + vim_free(old_ei); + } +} +# endif /* FEAT_SYN_HL */ + +/* + * do_autocmd() -- implements the :autocmd command. Can be used in the + * following ways: + * + * :autocmd Add to the list of commands that + * will be automatically executed for + * when editing a file matching , in + * the current group. + * :autocmd Show the autocommands associated with + * and . + * :autocmd Show the autocommands associated with + * . + * :autocmd Show all autocommands. + * :autocmd! Remove all autocommands associated with + * and , and add the command + * , for the current group. + * :autocmd! Remove all autocommands associated with + * and for the current group. + * :autocmd! Remove all autocommands associated with + * for the current group. + * :autocmd! Remove ALL autocommands for the current + * group. + * + * Multiple events and patterns may be given separated by commas. Here are + * some examples: + * :autocmd bufread,bufenter *.c,*.h set tw=0 smartindent noic + * :autocmd bufleave * set tw=79 nosmartindent ic infercase + * + * :autocmd * *.c show all autocommands for *.c files. + * + * Mostly a {group} argument can optionally appear before . + */ + void +do_autocmd(char_u *arg_in, int forceit) +{ + char_u *arg = arg_in; + char_u *pat; + char_u *envpat = NULL; + char_u *cmd; + event_T event; + int need_free = FALSE; + int nested = FALSE; + int group; + + if (*arg == '|') + { + arg = (char_u *)""; + group = AUGROUP_ALL; // no argument, use all groups + } + else + { + /* + * Check for a legal group name. If not, use AUGROUP_ALL. + */ + group = au_get_grouparg(&arg); + if (arg == NULL) // out of memory + return; + } + + /* + * Scan over the events. + * If we find an illegal name, return here, don't do anything. + */ + pat = find_end_event(arg, group != AUGROUP_ALL); + if (pat == NULL) + return; + + pat = skipwhite(pat); + if (*pat == '|') + { + pat = (char_u *)""; + cmd = (char_u *)""; + } + else + { + /* + * Scan over the pattern. Put a NUL at the end. + */ + cmd = pat; + while (*cmd && (!VIM_ISWHITE(*cmd) || cmd[-1] == '\\')) + cmd++; + if (*cmd) + *cmd++ = NUL; + + // Expand environment variables in the pattern. Set 'shellslash', we + // want forward slashes here. + if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) + { +#ifdef BACKSLASH_IN_FILENAME + int p_ssl_save = p_ssl; + + p_ssl = TRUE; +#endif + envpat = expand_env_save(pat); +#ifdef BACKSLASH_IN_FILENAME + p_ssl = p_ssl_save; +#endif + if (envpat != NULL) + pat = envpat; + } + + /* + * Check for "nested" flag. + */ + cmd = skipwhite(cmd); + if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 + && VIM_ISWHITE(cmd[6])) + { + nested = TRUE; + cmd = skipwhite(cmd + 6); + } + + /* + * Find the start of the commands. + * Expand in it. + */ + if (*cmd != NUL) + { + cmd = expand_sfile(cmd); + if (cmd == NULL) // some error + return; + need_free = TRUE; + } + } + + /* + * Print header when showing autocommands. + */ + if (!forceit && *cmd == NUL) + // Highlight title + msg_puts_title(_("\n--- Autocommands ---")); + + /* + * Loop over the events. + */ + last_event = (event_T)-1; // for listing the event name + last_group = AUGROUP_ERROR; // for listing the group name + if (*arg == '*' || *arg == NUL || *arg == '|') + { + for (event = (event_T)0; (int)event < (int)NUM_EVENTS; + event = (event_T)((int)event + 1)) + if (do_autocmd_event(event, pat, + nested, cmd, forceit, group) == FAIL) + break; + } + else + { + while (*arg && *arg != '|' && !VIM_ISWHITE(*arg)) + if (do_autocmd_event(event_name2nr(arg, &arg), pat, + nested, cmd, forceit, group) == FAIL) + break; + } + + if (need_free) + vim_free(cmd); + vim_free(envpat); +} + +/* + * Find the group ID in a ":autocmd" or ":doautocmd" argument. + * The "argp" argument is advanced to the following argument. + * + * Returns the group ID, AUGROUP_ERROR for error (out of memory). + */ + static int +au_get_grouparg(char_u **argp) +{ + char_u *group_name; + char_u *p; + char_u *arg = *argp; + int group = AUGROUP_ALL; + + for (p = arg; *p && !VIM_ISWHITE(*p) && *p != '|'; ++p) + ; + if (p > arg) + { + group_name = vim_strnsave(arg, (int)(p - arg)); + if (group_name == NULL) // out of memory + return AUGROUP_ERROR; + group = au_find_group(group_name); + if (group == AUGROUP_ERROR) + group = AUGROUP_ALL; // no match, use all groups + else + *argp = skipwhite(p); // match, skip over group name + vim_free(group_name); + } + return group; +} + +/* + * do_autocmd() for one event. + * If *pat == NUL do for all patterns. + * If *cmd == NUL show entries. + * If forceit == TRUE delete entries. + * If group is not AUGROUP_ALL, only use this group. + */ + static int +do_autocmd_event( + event_T event, + char_u *pat, + int nested, + char_u *cmd, + int forceit, + int group) +{ + AutoPat *ap; + AutoPat **prev_ap; + AutoCmd *ac; + AutoCmd **prev_ac; + int brace_level; + char_u *endpat; + int findgroup; + int allgroups; + int patlen; + int is_buflocal; + int buflocal_nr; + char_u buflocal_pat[25]; /* for "" */ + + if (group == AUGROUP_ALL) + findgroup = current_augroup; + else + findgroup = group; + allgroups = (group == AUGROUP_ALL && !forceit && *cmd == NUL); + + /* + * Show or delete all patterns for an event. + */ + if (*pat == NUL) + { + for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) + { + if (forceit) // delete the AutoPat, if it's in the current group + { + if (ap->group == findgroup) + au_remove_pat(ap); + } + else if (group == AUGROUP_ALL || ap->group == group) + show_autocmd(ap, event); + } + } + + /* + * Loop through all the specified patterns. + */ + for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat)) + { + /* + * Find end of the pattern. + * Watch out for a comma in braces, like "*.\{obj,o\}". + */ + brace_level = 0; + for (endpat = pat; *endpat && (*endpat != ',' || brace_level + || (endpat > pat && endpat[-1] == '\\')); ++endpat) + { + if (*endpat == '{') + brace_level++; + else if (*endpat == '}') + brace_level--; + } + if (pat == endpat) // ignore single comma + continue; + patlen = (int)(endpat - pat); + + /* + * detect special buffer-local patterns + */ + is_buflocal = FALSE; + buflocal_nr = 0; + + if (patlen >= 8 && STRNCMP(pat, "') + { + // "": Error will be printed only for addition. + // printing and removing will proceed silently. + is_buflocal = TRUE; + if (patlen == 8) + // "" + buflocal_nr = curbuf->b_fnum; + else if (patlen > 9 && pat[7] == '=') + { + if (patlen == 13 && STRNICMP(pat, "", 13) == 0) + // "" + buflocal_nr = autocmd_bufnr; + else if (skipdigits(pat + 8) == pat + patlen - 1) + // "" + buflocal_nr = atoi((char *)pat + 8); + } + } + + if (is_buflocal) + { + // normalize pat into standard "#N" form + sprintf((char *)buflocal_pat, "", buflocal_nr); + pat = buflocal_pat; // can modify pat and patlen + patlen = (int)STRLEN(buflocal_pat); // but not endpat + } + + /* + * Find AutoPat entries with this pattern. When adding a command it + * always goes at or after the last one, so start at the end. + */ + if (!forceit && *cmd != NUL && last_autopat[(int)event] != NULL) + prev_ap = &last_autopat[(int)event]; + else + prev_ap = &first_autopat[(int)event]; + while ((ap = *prev_ap) != NULL) + { + if (ap->pat != NULL) + { + /* Accept a pattern when: + * - a group was specified and it's that group, or a group was + * not specified and it's the current group, or a group was + * not specified and we are listing + * - the length of the pattern matches + * - the pattern matches. + * For , this condition works because we normalize + * all buffer-local patterns. + */ + if ((allgroups || ap->group == findgroup) + && ap->patlen == patlen + && STRNCMP(pat, ap->pat, patlen) == 0) + { + /* + * Remove existing autocommands. + * If adding any new autocmd's for this AutoPat, don't + * delete the pattern from the autopat list, append to + * this list. + */ + if (forceit) + { + if (*cmd != NUL && ap->next == NULL) + { + au_remove_cmds(ap); + break; + } + au_remove_pat(ap); + } + + /* + * Show autocmd's for this autopat, or buflocals + */ + else if (*cmd == NUL) + show_autocmd(ap, event); + + /* + * Add autocmd to this autopat, if it's the last one. + */ + else if (ap->next == NULL) + break; + } + } + prev_ap = &ap->next; + } + + /* + * Add a new command. + */ + if (*cmd != NUL) + { + /* + * If the pattern we want to add a command to does appear at the + * end of the list (or not is not in the list at all), add the + * pattern at the end of the list. + */ + if (ap == NULL) + { + /* refuse to add buffer-local ap if buffer number is invalid */ + if (is_buflocal && (buflocal_nr == 0 + || buflist_findnr(buflocal_nr) == NULL)) + { + semsg(_("E680: : invalid buffer number "), + buflocal_nr); + return FAIL; + } + + ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat)); + if (ap == NULL) + return FAIL; + ap->pat = vim_strnsave(pat, patlen); + ap->patlen = patlen; + if (ap->pat == NULL) + { + vim_free(ap); + return FAIL; + } + + if (is_buflocal) + { + ap->buflocal_nr = buflocal_nr; + ap->reg_prog = NULL; + } + else + { + char_u *reg_pat; + + ap->buflocal_nr = 0; + reg_pat = file_pat_to_reg_pat(pat, endpat, + &ap->allow_dirs, TRUE); + if (reg_pat != NULL) + ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC); + vim_free(reg_pat); + if (reg_pat == NULL || ap->reg_prog == NULL) + { + vim_free(ap->pat); + vim_free(ap); + return FAIL; + } + } + ap->cmds = NULL; + *prev_ap = ap; + last_autopat[(int)event] = ap; + ap->next = NULL; + if (group == AUGROUP_ALL) + ap->group = current_augroup; + else + ap->group = group; + } + + /* + * Add the autocmd at the end of the AutoCmd list. + */ + prev_ac = &(ap->cmds); + while ((ac = *prev_ac) != NULL) + prev_ac = &ac->next; + ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd)); + if (ac == NULL) + return FAIL; + ac->cmd = vim_strsave(cmd); +#ifdef FEAT_EVAL + ac->script_ctx = current_sctx; + ac->script_ctx.sc_lnum += sourcing_lnum; +#endif + if (ac->cmd == NULL) + { + vim_free(ac); + return FAIL; + } + ac->next = NULL; + *prev_ac = ac; + ac->nested = nested; + } + } + + au_cleanup(); // may really delete removed patterns/commands now + return OK; +} + +/* + * Implementation of ":doautocmd [group] event [fname]". + * Return OK for success, FAIL for failure; + */ + int +do_doautocmd( + char_u *arg, + int do_msg, // give message for no matching autocmds? + int *did_something) +{ + char_u *fname; + int nothing_done = TRUE; + int group; + + if (did_something != NULL) + *did_something = FALSE; + + /* + * Check for a legal group name. If not, use AUGROUP_ALL. + */ + group = au_get_grouparg(&arg); + if (arg == NULL) // out of memory + return FAIL; + + if (*arg == '*') + { + emsg(_("E217: Can't execute autocommands for ALL events")); + return FAIL; + } + + /* + * Scan over the events. + * If we find an illegal name, return here, don't do anything. + */ + fname = find_end_event(arg, group != AUGROUP_ALL); + if (fname == NULL) + return FAIL; + + fname = skipwhite(fname); + + /* + * Loop over the events. + */ + while (*arg && !ends_excmd(*arg) && !VIM_ISWHITE(*arg)) + if (apply_autocmds_group(event_name2nr(arg, &arg), + fname, NULL, TRUE, group, curbuf, NULL)) + nothing_done = FALSE; + + if (nothing_done && do_msg) + msg(_("No matching autocommands")); + if (did_something != NULL) + *did_something = !nothing_done; + +#ifdef FEAT_EVAL + return aborting() ? FAIL : OK; +#else + return OK; +#endif +} + +/* + * ":doautoall": execute autocommands for each loaded buffer. + */ + void +ex_doautoall(exarg_T *eap) +{ + int retval; + aco_save_T aco; + buf_T *buf; + bufref_T bufref; + char_u *arg = eap->arg; + int call_do_modelines = check_nomodeline(&arg); + int did_aucmd; + + /* + * This is a bit tricky: For some commands curwin->w_buffer needs to be + * equal to curbuf, but for some buffers there may not be a window. + * So we change the buffer for the current window for a moment. This + * gives problems when the autocommands make changes to the list of + * buffers or windows... + */ + FOR_ALL_BUFFERS(buf) + { + if (buf->b_ml.ml_mfp != NULL) + { + // find a window for this buffer and save some values + aucmd_prepbuf(&aco, buf); + set_bufref(&bufref, buf); + + // execute the autocommands for this buffer + retval = do_doautocmd(arg, FALSE, &did_aucmd); + + if (call_do_modelines && did_aucmd) + { + // Execute the modeline settings, but don't set window-local + // options if we are using the current window for another + // buffer. + do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0); + } + + // restore the current window + aucmd_restbuf(&aco); + + // stop if there is some error or buffer was deleted + if (retval == FAIL || !bufref_valid(&bufref)) + break; + } + } + + check_cursor(); // just in case lines got deleted +} + +/* + * Check *argp for . When it is present return FALSE, otherwise + * return TRUE and advance *argp to after it. + * Thus return TRUE when do_modelines() should be called. + */ + int +check_nomodeline(char_u **argp) +{ + if (STRNCMP(*argp, "", 12) == 0) + { + *argp = skipwhite(*argp + 12); + return FALSE; + } + return TRUE; +} + +/* + * Prepare for executing autocommands for (hidden) buffer "buf". + * Search for a visible window containing the current buffer. If there isn't + * one then use "aucmd_win". + * Set "curbuf" and "curwin" to match "buf". + */ + void +aucmd_prepbuf( + aco_save_T *aco, // structure to save values in + buf_T *buf) // new curbuf +{ + win_T *win; + int save_ea; +#ifdef FEAT_AUTOCHDIR + int save_acd; +#endif + + // Find a window that is for the new buffer + if (buf == curbuf) // be quick when buf is curbuf + win = curwin; + else + FOR_ALL_WINDOWS(win) + if (win->w_buffer == buf) + break; + + // Allocate "aucmd_win" when needed. If this fails (out of memory) fall + // back to using the current window. + if (win == NULL && aucmd_win == NULL) + { + win_alloc_aucmd_win(); + if (aucmd_win == NULL) + win = curwin; + } + if (win == NULL && aucmd_win_used) + // Strange recursive autocommand, fall back to using the current + // window. Expect a few side effects... + win = curwin; + + aco->save_curwin = curwin; + aco->save_curbuf = curbuf; + aco->save_prevwin = prevwin; + if (win != NULL) + { + // There is a window for "buf" in the current tab page, make it the + // curwin. This is preferred, it has the least side effects (esp. if + // "buf" is curbuf). + aco->use_aucmd_win = FALSE; + curwin = win; + } + else + { + // There is no window for "buf", use "aucmd_win". To minimize the side + // effects, insert it in the current tab page. + // Anything related to a window (e.g., setting folds) may have + // unexpected results. + aco->use_aucmd_win = TRUE; + aucmd_win_used = TRUE; + aucmd_win->w_buffer = buf; +#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) + aucmd_win->w_s = &buf->b_s; +#endif + ++buf->b_nwindows; + win_init_empty(aucmd_win); // set cursor and topline to safe values + + // Make sure w_localdir and globaldir are NULL to avoid a chdir() in + // win_enter_ext(). + VIM_CLEAR(aucmd_win->w_localdir); + aco->globaldir = globaldir; + globaldir = NULL; + + + // Split the current window, put the aucmd_win in the upper half. + // We don't want the BufEnter or WinEnter autocommands. + block_autocmds(); + make_snapshot(SNAP_AUCMD_IDX); + save_ea = p_ea; + p_ea = FALSE; + +#ifdef FEAT_AUTOCHDIR + // Prevent chdir() call in win_enter_ext(), through do_autochdir(). + save_acd = p_acd; + p_acd = FALSE; +#endif + + (void)win_split_ins(0, WSP_TOP, aucmd_win, 0); + (void)win_comp_pos(); // recompute window positions + p_ea = save_ea; +#ifdef FEAT_AUTOCHDIR + p_acd = save_acd; +#endif + unblock_autocmds(); + curwin = aucmd_win; + } + curbuf = buf; + aco->new_curwin = curwin; + set_bufref(&aco->new_curbuf, curbuf); +} + +/* + * Cleanup after executing autocommands for a (hidden) buffer. + * Restore the window as it was (if possible). + */ + void +aucmd_restbuf( + aco_save_T *aco) // structure holding saved values +{ + int dummy; + + if (aco->use_aucmd_win) + { + --curbuf->b_nwindows; + // Find "aucmd_win", it can't be closed, but it may be in another tab + // page. Do not trigger autocommands here. + block_autocmds(); + if (curwin != aucmd_win) + { + tabpage_T *tp; + win_T *wp; + + FOR_ALL_TAB_WINDOWS(tp, wp) + { + if (wp == aucmd_win) + { + if (tp != curtab) + goto_tabpage_tp(tp, TRUE, TRUE); + win_goto(aucmd_win); + goto win_found; + } + } + } +win_found: + + // Remove the window and frame from the tree of frames. + (void)winframe_remove(curwin, &dummy, NULL); + win_remove(curwin, NULL); + aucmd_win_used = FALSE; + last_status(FALSE); // may need to remove last status line + + if (!valid_tabpage_win(curtab)) + // no valid window in current tabpage + close_tabpage(curtab); + + restore_snapshot(SNAP_AUCMD_IDX, FALSE); + (void)win_comp_pos(); // recompute window positions + unblock_autocmds(); + + if (win_valid(aco->save_curwin)) + curwin = aco->save_curwin; + else + // Hmm, original window disappeared. Just use the first one. + curwin = firstwin; + if (win_valid(aco->save_prevwin)) + prevwin = aco->save_prevwin; +#ifdef FEAT_EVAL + vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables + hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab +#endif + curbuf = curwin->w_buffer; + + vim_free(globaldir); + globaldir = aco->globaldir; + + // the buffer contents may have changed + check_cursor(); + if (curwin->w_topline > curbuf->b_ml.ml_line_count) + { + curwin->w_topline = curbuf->b_ml.ml_line_count; +#ifdef FEAT_DIFF + curwin->w_topfill = 0; +#endif + } +#if defined(FEAT_GUI) + // Hide the scrollbars from the aucmd_win and update. + gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_LEFT], FALSE); + gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_RIGHT], FALSE); + gui_may_update_scrollbars(); +#endif + } + else + { + // restore curwin + if (win_valid(aco->save_curwin)) + { + // Restore the buffer which was previously edited by curwin, if + // it was changed, we are still the same window and the buffer is + // valid. + if (curwin == aco->new_curwin + && curbuf != aco->new_curbuf.br_buf + && bufref_valid(&aco->new_curbuf) + && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) + { +# if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) + if (curwin->w_s == &curbuf->b_s) + curwin->w_s = &aco->new_curbuf.br_buf->b_s; +# endif + --curbuf->b_nwindows; + curbuf = aco->new_curbuf.br_buf; + curwin->w_buffer = curbuf; + ++curbuf->b_nwindows; + } + + curwin = aco->save_curwin; + curbuf = curwin->w_buffer; + if (win_valid(aco->save_prevwin)) + prevwin = aco->save_prevwin; + // In case the autocommand move the cursor to a position that that + // not exist in curbuf. + check_cursor(); + } + } +} + +static int autocmd_nested = FALSE; + +/* + * Execute autocommands for "event" and file name "fname". + * Return TRUE if some commands were executed. + */ + int +apply_autocmds( + event_T event, + char_u *fname, // NULL or empty means use actual file name + char_u *fname_io, // fname to use for on cmdline + int force, // when TRUE, ignore autocmd_busy + buf_T *buf) // buffer for +{ + return apply_autocmds_group(event, fname, fname_io, force, + AUGROUP_ALL, buf, NULL); +} + +/* + * Like apply_autocmds(), but with extra "eap" argument. This takes care of + * setting v:filearg. + */ + int +apply_autocmds_exarg( + event_T event, + char_u *fname, + char_u *fname_io, + int force, + buf_T *buf, + exarg_T *eap) +{ + return apply_autocmds_group(event, fname, fname_io, force, + AUGROUP_ALL, buf, eap); +} + +/* + * Like apply_autocmds(), but handles the caller's retval. If the script + * processing is being aborted or if retval is FAIL when inside a try + * conditional, no autocommands are executed. If otherwise the autocommands + * cause the script to be aborted, retval is set to FAIL. + */ + int +apply_autocmds_retval( + event_T event, + char_u *fname, // NULL or empty means use actual file name + char_u *fname_io, // fname to use for on cmdline + int force, // when TRUE, ignore autocmd_busy + buf_T *buf, // buffer for + int *retval) // pointer to caller's retval +{ + int did_cmd; + +#ifdef FEAT_EVAL + if (should_abort(*retval)) + return FALSE; +#endif + + did_cmd = apply_autocmds_group(event, fname, fname_io, force, + AUGROUP_ALL, buf, NULL); + if (did_cmd +#ifdef FEAT_EVAL + && aborting() +#endif + ) + *retval = FAIL; + return did_cmd; +} + +/* + * Return TRUE when there is a CursorHold autocommand defined. + */ + int +has_cursorhold(void) +{ + return (first_autopat[(int)(get_real_state() == NORMAL_BUSY + ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL); +} + +/* + * Return TRUE if the CursorHold event can be triggered. + */ + int +trigger_cursorhold(void) +{ + int state; + + if (!did_cursorhold + && has_cursorhold() + && reg_recording == 0 + && typebuf.tb_len == 0 +#ifdef FEAT_INS_EXPAND + && !ins_compl_active() +#endif + ) + { + state = get_real_state(); + if (state == NORMAL_BUSY || (state & INSERT) != 0) + return TRUE; + } + return FALSE; +} + +/* + * Return TRUE when there is a CursorMoved autocommand defined. + */ + int +has_cursormoved(void) +{ + return (first_autopat[(int)EVENT_CURSORMOVED] != NULL); +} + +#if defined(FEAT_CONCEAL) || defined(PROTO) +/* + * Return TRUE when there is a CursorMovedI autocommand defined. + */ + int +has_cursormovedI(void) +{ + return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL); +} +#endif + +/* + * Return TRUE when there is a TextChanged autocommand defined. + */ + int +has_textchanged(void) +{ + return (first_autopat[(int)EVENT_TEXTCHANGED] != NULL); +} + +/* + * Return TRUE when there is a TextChangedI autocommand defined. + */ + int +has_textchangedI(void) +{ + return (first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL); +} + +#if defined(FEAT_INS_EXPAND) || defined(PROTO) +/* + * Return TRUE when there is a TextChangedP autocommand defined. + */ + int +has_textchangedP(void) +{ + return (first_autopat[(int)EVENT_TEXTCHANGEDP] != NULL); +} +#endif + +/* + * Return TRUE when there is an InsertCharPre autocommand defined. + */ + int +has_insertcharpre(void) +{ + return (first_autopat[(int)EVENT_INSERTCHARPRE] != NULL); +} + +/* + * Return TRUE when there is an CmdUndefined autocommand defined. + */ + int +has_cmdundefined(void) +{ + return (first_autopat[(int)EVENT_CMDUNDEFINED] != NULL); +} + +/* + * Return TRUE when there is an FuncUndefined autocommand defined. + */ + int +has_funcundefined(void) +{ + return (first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL); +} + +#if defined(FEAT_EVAL) || defined(PROTO) +/* + * Return TRUE when there is a TextYankPost autocommand defined. + */ + int +has_textyankpost(void) +{ + return (first_autopat[(int)EVENT_TEXTYANKPOST] != NULL); +} +#endif + +/* + * Execute autocommands for "event" and file name "fname". + * Return TRUE if some commands were executed. + */ + static int +apply_autocmds_group( + event_T event, + char_u *fname, // NULL or empty means use actual file name + char_u *fname_io, // fname to use for on cmdline, NULL means + // use fname + int force, // when TRUE, ignore autocmd_busy + int group, // group ID, or AUGROUP_ALL + buf_T *buf, // buffer for + exarg_T *eap UNUSED) // command arguments +{ + char_u *sfname = NULL; // short file name + char_u *tail; + int save_changed; + buf_T *old_curbuf; + int retval = FALSE; + char_u *save_sourcing_name; + linenr_T save_sourcing_lnum; + char_u *save_autocmd_fname; + int save_autocmd_fname_full; + int save_autocmd_bufnr; + char_u *save_autocmd_match; + int save_autocmd_busy; + int save_autocmd_nested; + static int nesting = 0; + AutoPatCmd patcmd; + AutoPat *ap; +#ifdef FEAT_EVAL + sctx_T save_current_sctx; + funccal_entry_T funccal_entry; + char_u *save_cmdarg; + long save_cmdbang; +#endif + static int filechangeshell_busy = FALSE; +#ifdef FEAT_PROFILE + proftime_T wait_time; +#endif + int did_save_redobuff = FALSE; + save_redo_T save_redo; + int save_KeyTyped = KeyTyped; + + /* + * Quickly return if there are no autocommands for this event or + * autocommands are blocked. + */ + if (event == NUM_EVENTS || first_autopat[(int)event] == NULL + || autocmd_blocked > 0) + goto BYPASS_AU; + + /* + * When autocommands are busy, new autocommands are only executed when + * explicitly enabled with the "nested" flag. + */ + if (autocmd_busy && !(force || autocmd_nested)) + goto BYPASS_AU; + +#ifdef FEAT_EVAL + /* + * Quickly return when immediately aborting on error, or when an interrupt + * occurred or an exception was thrown but not caught. + */ + if (aborting()) + goto BYPASS_AU; +#endif + + /* + * FileChangedShell never nests, because it can create an endless loop. + */ + if (filechangeshell_busy && (event == EVENT_FILECHANGEDSHELL + || event == EVENT_FILECHANGEDSHELLPOST)) + goto BYPASS_AU; + + /* + * Ignore events in 'eventignore'. + */ + if (event_ignored(event)) + goto BYPASS_AU; + + /* + * Allow nesting of autocommands, but restrict the depth, because it's + * possible to create an endless loop. + */ + if (nesting == 10) + { + emsg(_("E218: autocommand nesting too deep")); + goto BYPASS_AU; + } + + /* + * Check if these autocommands are disabled. Used when doing ":all" or + * ":ball". + */ + if ( (autocmd_no_enter + && (event == EVENT_WINENTER || event == EVENT_BUFENTER)) + || (autocmd_no_leave + && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE))) + goto BYPASS_AU; + + /* + * Save the autocmd_* variables and info about the current buffer. + */ + save_autocmd_fname = autocmd_fname; + save_autocmd_fname_full = autocmd_fname_full; + save_autocmd_bufnr = autocmd_bufnr; + save_autocmd_match = autocmd_match; + save_autocmd_busy = autocmd_busy; + save_autocmd_nested = autocmd_nested; + save_changed = curbuf->b_changed; + old_curbuf = curbuf; + + /* + * Set the file name to be used for . + * Make a copy to avoid that changing a buffer name or directory makes it + * invalid. + */ + if (fname_io == NULL) + { + if (event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE + || event == EVENT_OPTIONSET) + autocmd_fname = NULL; + else if (fname != NULL && !ends_excmd(*fname)) + autocmd_fname = fname; + else if (buf != NULL) + autocmd_fname = buf->b_ffname; + else + autocmd_fname = NULL; + } + else + autocmd_fname = fname_io; + if (autocmd_fname != NULL) + autocmd_fname = vim_strsave(autocmd_fname); + autocmd_fname_full = FALSE; // call FullName_save() later + + /* + * Set the buffer number to be used for . + */ + if (buf == NULL) + autocmd_bufnr = 0; + else + autocmd_bufnr = buf->b_fnum; + + /* + * When the file name is NULL or empty, use the file name of buffer "buf". + * Always use the full path of the file name to match with, in case + * "allow_dirs" is set. + */ + if (fname == NULL || *fname == NUL) + { + if (buf == NULL) + fname = NULL; + else + { +#ifdef FEAT_SYN_HL + if (event == EVENT_SYNTAX) + fname = buf->b_p_syn; + else +#endif + if (event == EVENT_FILETYPE) + fname = buf->b_p_ft; + else + { + if (buf->b_sfname != NULL) + sfname = vim_strsave(buf->b_sfname); + fname = buf->b_ffname; + } + } + if (fname == NULL) + fname = (char_u *)""; + fname = vim_strsave(fname); // make a copy, so we can change it + } + else + { + sfname = vim_strsave(fname); + // Don't try expanding FileType, Syntax, FuncUndefined, WindowID, + // ColorScheme, QuickFixCmd* or DirChanged + if (event == EVENT_FILETYPE + || event == EVENT_SYNTAX + || event == EVENT_CMDLINECHANGED + || event == EVENT_CMDLINEENTER + || event == EVENT_CMDLINELEAVE + || event == EVENT_CMDWINENTER + || event == EVENT_CMDWINLEAVE + || event == EVENT_CMDUNDEFINED + || event == EVENT_FUNCUNDEFINED + || event == EVENT_REMOTEREPLY + || event == EVENT_SPELLFILEMISSING + || event == EVENT_QUICKFIXCMDPRE + || event == EVENT_COLORSCHEME + || event == EVENT_COLORSCHEMEPRE + || event == EVENT_OPTIONSET + || event == EVENT_QUICKFIXCMDPOST + || event == EVENT_DIRCHANGED) + { + fname = vim_strsave(fname); + autocmd_fname_full = TRUE; // don't expand it later + } + else + fname = FullName_save(fname, FALSE); + } + if (fname == NULL) // out of memory + { + vim_free(sfname); + retval = FALSE; + goto BYPASS_AU; + } + +#ifdef BACKSLASH_IN_FILENAME + /* + * Replace all backslashes with forward slashes. This makes the + * autocommand patterns portable between Unix and MS-DOS. + */ + if (sfname != NULL) + forward_slash(sfname); + forward_slash(fname); +#endif + +#ifdef VMS + // remove version for correct match + if (sfname != NULL) + vms_remove_version(sfname); + vms_remove_version(fname); +#endif + + /* + * Set the name to be used for . + */ + autocmd_match = fname; + + + // Don't redraw while doing autocommands. + ++RedrawingDisabled; + save_sourcing_name = sourcing_name; + sourcing_name = NULL; // don't free this one + save_sourcing_lnum = sourcing_lnum; + sourcing_lnum = 0; // no line number here + +#ifdef FEAT_EVAL + save_current_sctx = current_sctx; + +# ifdef FEAT_PROFILE + if (do_profiling == PROF_YES) + prof_child_enter(&wait_time); // doesn't count for the caller itself +# endif + + // Don't use local function variables, if called from a function. + save_funccal(&funccal_entry); +#endif + + /* + * When starting to execute autocommands, save the search patterns. + */ + if (!autocmd_busy) + { + save_search_patterns(); +#ifdef FEAT_INS_EXPAND + if (!ins_compl_active()) +#endif + { + saveRedobuff(&save_redo); + did_save_redobuff = TRUE; + } + did_filetype = keep_filetype; + } + + /* + * Note that we are applying autocmds. Some commands need to know. + */ + autocmd_busy = TRUE; + filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL); + ++nesting; // see matching decrement below + + // Remember that FileType was triggered. Used for did_filetype(). + if (event == EVENT_FILETYPE) + did_filetype = TRUE; + + tail = gettail(fname); + + // Find first autocommand that matches + patcmd.curpat = first_autopat[(int)event]; + patcmd.nextcmd = NULL; + patcmd.group = group; + patcmd.fname = fname; + patcmd.sfname = sfname; + patcmd.tail = tail; + patcmd.event = event; + patcmd.arg_bufnr = autocmd_bufnr; + patcmd.next = NULL; + auto_next_pat(&patcmd, FALSE); + + // found one, start executing the autocommands + if (patcmd.curpat != NULL) + { + // add to active_apc_list + patcmd.next = active_apc_list; + active_apc_list = &patcmd; + +#ifdef FEAT_EVAL + // set v:cmdarg (only when there is a matching pattern) + save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG); + if (eap != NULL) + { + save_cmdarg = set_cmdarg(eap, NULL); + set_vim_var_nr(VV_CMDBANG, (long)eap->forceit); + } + else + save_cmdarg = NULL; // avoid gcc warning +#endif + retval = TRUE; + // mark the last pattern, to avoid an endless loop when more patterns + // are added when executing autocommands + for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next) + ap->last = FALSE; + ap->last = TRUE; + check_lnums(TRUE); // make sure cursor and topline are valid + do_cmdline(NULL, getnextac, (void *)&patcmd, + DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); +#ifdef FEAT_EVAL + if (eap != NULL) + { + (void)set_cmdarg(NULL, save_cmdarg); + set_vim_var_nr(VV_CMDBANG, save_cmdbang); + } +#endif + // delete from active_apc_list + if (active_apc_list == &patcmd) // just in case + active_apc_list = patcmd.next; + } + + --RedrawingDisabled; + autocmd_busy = save_autocmd_busy; + filechangeshell_busy = FALSE; + autocmd_nested = save_autocmd_nested; + vim_free(sourcing_name); + sourcing_name = save_sourcing_name; + sourcing_lnum = save_sourcing_lnum; + vim_free(autocmd_fname); + autocmd_fname = save_autocmd_fname; + autocmd_fname_full = save_autocmd_fname_full; + autocmd_bufnr = save_autocmd_bufnr; + autocmd_match = save_autocmd_match; +#ifdef FEAT_EVAL + current_sctx = save_current_sctx; + restore_funccal(); +# ifdef FEAT_PROFILE + if (do_profiling == PROF_YES) + prof_child_exit(&wait_time); +# endif +#endif + KeyTyped = save_KeyTyped; + vim_free(fname); + vim_free(sfname); + --nesting; // see matching increment above + + /* + * When stopping to execute autocommands, restore the search patterns and + * the redo buffer. Free any buffers in the au_pending_free_buf list and + * free any windows in the au_pending_free_win list. + */ + if (!autocmd_busy) + { + restore_search_patterns(); + if (did_save_redobuff) + restoreRedobuff(&save_redo); + did_filetype = FALSE; + while (au_pending_free_buf != NULL) + { + buf_T *b = au_pending_free_buf->b_next; + vim_free(au_pending_free_buf); + au_pending_free_buf = b; + } + while (au_pending_free_win != NULL) + { + win_T *w = au_pending_free_win->w_next; + vim_free(au_pending_free_win); + au_pending_free_win = w; + } + } + + /* + * Some events don't set or reset the Changed flag. + * Check if still in the same buffer! + */ + if (curbuf == old_curbuf + && (event == EVENT_BUFREADPOST + || event == EVENT_BUFWRITEPOST + || event == EVENT_FILEAPPENDPOST + || event == EVENT_VIMLEAVE + || event == EVENT_VIMLEAVEPRE)) + { +#ifdef FEAT_TITLE + if (curbuf->b_changed != save_changed) + need_maketitle = TRUE; +#endif + curbuf->b_changed = save_changed; + } + + au_cleanup(); // may really delete removed patterns/commands now + +BYPASS_AU: + // When wiping out a buffer make sure all its buffer-local autocommands + // are deleted. + if (event == EVENT_BUFWIPEOUT && buf != NULL) + aubuflocal_remove(buf); + + if (retval == OK && event == EVENT_FILETYPE) + au_did_filetype = TRUE; + + return retval; +} + +# ifdef FEAT_EVAL +static char_u *old_termresponse = NULL; +# endif + +/* + * Block triggering autocommands until unblock_autocmd() is called. + * Can be used recursively, so long as it's symmetric. + */ + void +block_autocmds(void) +{ +# ifdef FEAT_EVAL + // Remember the value of v:termresponse. + if (autocmd_blocked == 0) + old_termresponse = get_vim_var_str(VV_TERMRESPONSE); +# endif + ++autocmd_blocked; +} + + void +unblock_autocmds(void) +{ + --autocmd_blocked; + +# ifdef FEAT_EVAL + // When v:termresponse was set while autocommands were blocked, trigger + // the autocommands now. Esp. useful when executing a shell command + // during startup (vimdiff). + if (autocmd_blocked == 0 + && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse) + apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf); +# endif +} + +#if defined(FEAT_EVAL) && (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM)) \ + || defined(PROTO) + int +is_autocmd_blocked(void) +{ + return autocmd_blocked != 0; +} +#endif + +/* + * Find next autocommand pattern that matches. + */ + static void +auto_next_pat( + AutoPatCmd *apc, + int stop_at_last) // stop when 'last' flag is set +{ + AutoPat *ap; + AutoCmd *cp; + char_u *name; + char *s; + + VIM_CLEAR(sourcing_name); + + for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next) + { + apc->curpat = NULL; + + // Only use a pattern when it has not been removed, has commands and + // the group matches. For buffer-local autocommands only check the + // buffer number. + if (ap->pat != NULL && ap->cmds != NULL + && (apc->group == AUGROUP_ALL || apc->group == ap->group)) + { + // execution-condition + if (ap->buflocal_nr == 0 + ? (match_file_pat(NULL, &ap->reg_prog, apc->fname, + apc->sfname, apc->tail, ap->allow_dirs)) + : ap->buflocal_nr == apc->arg_bufnr) + { + name = event_nr2name(apc->event); + s = _("%s Autocommands for \"%s\""); + sourcing_name = alloc((unsigned)(STRLEN(s) + + STRLEN(name) + ap->patlen + 1)); + if (sourcing_name != NULL) + { + sprintf((char *)sourcing_name, s, + (char *)name, (char *)ap->pat); + if (p_verbose >= 8) + { + verbose_enter(); + smsg(_("Executing %s"), sourcing_name); + verbose_leave(); + } + } + + apc->curpat = ap; + apc->nextcmd = ap->cmds; + // mark last command + for (cp = ap->cmds; cp->next != NULL; cp = cp->next) + cp->last = FALSE; + cp->last = TRUE; + } + line_breakcheck(); + if (apc->curpat != NULL) // found a match + break; + } + if (stop_at_last && ap->last) + break; + } +} + +/* + * Get next autocommand command. + * Called by do_cmdline() to get the next line for ":if". + * Returns allocated string, or NULL for end of autocommands. + */ + char_u * +getnextac(int c UNUSED, void *cookie, int indent UNUSED) +{ + AutoPatCmd *acp = (AutoPatCmd *)cookie; + char_u *retval; + AutoCmd *ac; + + // Can be called again after returning the last line. + if (acp->curpat == NULL) + return NULL; + + // repeat until we find an autocommand to execute + for (;;) + { + // skip removed commands + while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL) + if (acp->nextcmd->last) + acp->nextcmd = NULL; + else + acp->nextcmd = acp->nextcmd->next; + + if (acp->nextcmd != NULL) + break; + + // at end of commands, find next pattern that matches + if (acp->curpat->last) + acp->curpat = NULL; + else + acp->curpat = acp->curpat->next; + if (acp->curpat != NULL) + auto_next_pat(acp, TRUE); + if (acp->curpat == NULL) + return NULL; + } + + ac = acp->nextcmd; + + if (p_verbose >= 9) + { + verbose_enter_scroll(); + smsg(_("autocommand %s"), ac->cmd); + msg_puts("\n"); // don't overwrite this either + verbose_leave_scroll(); + } + retval = vim_strsave(ac->cmd); + autocmd_nested = ac->nested; +#ifdef FEAT_EVAL + current_sctx = ac->script_ctx; +#endif + if (ac->last) + acp->nextcmd = NULL; + else + acp->nextcmd = ac->next; + return retval; +} + +/* + * Return TRUE if there is a matching autocommand for "fname". + * To account for buffer-local autocommands, function needs to know + * in which buffer the file will be opened. + */ + int +has_autocmd(event_T event, char_u *sfname, buf_T *buf) +{ + AutoPat *ap; + char_u *fname; + char_u *tail = gettail(sfname); + int retval = FALSE; + + fname = FullName_save(sfname, FALSE); + if (fname == NULL) + return FALSE; + +#ifdef BACKSLASH_IN_FILENAME + /* + * Replace all backslashes with forward slashes. This makes the + * autocommand patterns portable between Unix and MS-DOS. + */ + sfname = vim_strsave(sfname); + if (sfname != NULL) + forward_slash(sfname); + forward_slash(fname); +#endif + + for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) + if (ap->pat != NULL && ap->cmds != NULL + && (ap->buflocal_nr == 0 + ? match_file_pat(NULL, &ap->reg_prog, + fname, sfname, tail, ap->allow_dirs) + : buf != NULL && ap->buflocal_nr == buf->b_fnum + )) + { + retval = TRUE; + break; + } + + vim_free(fname); +#ifdef BACKSLASH_IN_FILENAME + vim_free(sfname); +#endif + + return retval; +} + +#if defined(FEAT_CMDL_COMPL) || defined(PROTO) +/* + * Function given to ExpandGeneric() to obtain the list of autocommand group + * names. + */ + char_u * +get_augroup_name(expand_T *xp UNUSED, int idx) +{ + if (idx == augroups.ga_len) // add "END" add the end + return (char_u *)"END"; + if (idx >= augroups.ga_len) // end of list + return NULL; + if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup()) + // skip deleted entries + return (char_u *)""; + return AUGROUP_NAME(idx); // return a name +} + +static int include_groups = FALSE; + + char_u * +set_context_in_autocmd( + expand_T *xp, + char_u *arg, + int doautocmd) // TRUE for :doauto*, FALSE for :autocmd +{ + char_u *p; + int group; + + // check for a group name, skip it if present + include_groups = FALSE; + p = arg; + group = au_get_grouparg(&arg); + if (group == AUGROUP_ERROR) + return NULL; + // If there only is a group name that's what we expand. + if (*arg == NUL && group != AUGROUP_ALL && !VIM_ISWHITE(arg[-1])) + { + arg = p; + group = AUGROUP_ALL; + } + + // skip over event name + for (p = arg; *p != NUL && !VIM_ISWHITE(*p); ++p) + if (*p == ',') + arg = p + 1; + if (*p == NUL) + { + if (group == AUGROUP_ALL) + include_groups = TRUE; + xp->xp_context = EXPAND_EVENTS; // expand event name + xp->xp_pattern = arg; + return NULL; + } + + // skip over pattern + arg = skipwhite(p); + while (*arg && (!VIM_ISWHITE(*arg) || arg[-1] == '\\')) + arg++; + if (*arg) + return arg; // expand (next) command + + if (doautocmd) + xp->xp_context = EXPAND_FILES; // expand file names + else + xp->xp_context = EXPAND_NOTHING; // pattern is not expanded + return NULL; +} + +/* + * Function given to ExpandGeneric() to obtain the list of event names. + */ + char_u * +get_event_name(expand_T *xp UNUSED, int idx) +{ + if (idx < augroups.ga_len) // First list group names, if wanted + { + if (!include_groups || AUGROUP_NAME(idx) == NULL + || AUGROUP_NAME(idx) == get_deleted_augroup()) + return (char_u *)""; // skip deleted entries + return AUGROUP_NAME(idx); // return a name + } + return (char_u *)event_names[idx - augroups.ga_len].name; +} + +#endif // FEAT_CMDL_COMPL + +#if defined(FEAT_EVAL) || defined(PROTO) +/* + * Return TRUE if autocmd is supported. + */ + int +autocmd_supported(char_u *name) +{ + char_u *p; + + return (event_name2nr(name, &p) != NUM_EVENTS); +} + +/* + * Return TRUE if an autocommand is defined for a group, event and + * pattern: The group can be omitted to accept any group. "event" and "pattern" + * can be NULL to accept any event and pattern. "pattern" can be NULL to accept + * any pattern. Buffer-local patterns or are accepted. + * Used for: + * exists("#Group") or + * exists("#Group#Event") or + * exists("#Group#Event#pat") or + * exists("#Event") or + * exists("#Event#pat") + */ + int +au_exists(char_u *arg) +{ + char_u *arg_save; + char_u *pattern = NULL; + char_u *event_name; + char_u *p; + event_T event; + AutoPat *ap; + buf_T *buflocal_buf = NULL; + int group; + int retval = FALSE; + + // Make a copy so that we can change the '#' chars to a NUL. + arg_save = vim_strsave(arg); + if (arg_save == NULL) + return FALSE; + p = vim_strchr(arg_save, '#'); + if (p != NULL) + *p++ = NUL; + + // First, look for an autocmd group name + group = au_find_group(arg_save); + if (group == AUGROUP_ERROR) + { + // Didn't match a group name, assume the first argument is an event. + group = AUGROUP_ALL; + event_name = arg_save; + } + else + { + if (p == NULL) + { + // "Group": group name is present and it's recognized + retval = TRUE; + goto theend; + } + + // Must be "Group#Event" or "Group#Event#pat". + event_name = p; + p = vim_strchr(event_name, '#'); + if (p != NULL) + *p++ = NUL; // "Group#Event#pat" + } + + pattern = p; // "pattern" is NULL when there is no pattern + + // find the index (enum) for the event name + event = event_name2nr(event_name, &p); + + // return FALSE if the event name is not recognized + if (event == NUM_EVENTS) + goto theend; + + // Find the first autocommand for this event. + // If there isn't any, return FALSE; + // If there is one and no pattern given, return TRUE; + ap = first_autopat[(int)event]; + if (ap == NULL) + goto theend; + + // if pattern is "", special handling is needed which uses curbuf + // for pattern ", fnamecmp() will work fine + if (pattern != NULL && STRICMP(pattern, "") == 0) + buflocal_buf = curbuf; + + // Check if there is an autocommand with the given pattern. + for ( ; ap != NULL; ap = ap->next) + // only use a pattern when it has not been removed and has commands. + // For buffer-local autocommands, fnamecmp() works fine. + if (ap->pat != NULL && ap->cmds != NULL + && (group == AUGROUP_ALL || ap->group == group) + && (pattern == NULL + || (buflocal_buf == NULL + ? fnamecmp(ap->pat, pattern) == 0 + : ap->buflocal_nr == buflocal_buf->b_fnum))) + { + retval = TRUE; + break; + } + +theend: + vim_free(arg_save); + return retval; +} +#endif diff --git a/src/fileio.c b/src/fileio.c index 4cb13f27a5..bf724f642f 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -42,12 +42,6 @@ static int msg_add_fileformat(int eol_type); static void msg_add_eol(void); static int check_mtime(buf_T *buf, stat_T *s); static int time_differs(long t1, long t2); -static int apply_autocmds_exarg(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, exarg_T *eap); -static int au_find_group(char_u *name); - -#define AUGROUP_DEFAULT -1 /* default autocmd group */ -#define AUGROUP_ERROR -2 /* erroneous autocmd group */ -#define AUGROUP_ALL -3 /* all autocmd groups */ #define HAS_BW_FLAGS #define FIO_LATIN1 0x01 /* convert Latin1 */ @@ -120,16 +114,6 @@ static int get_mac_fio_flags(char_u *ptr); #endif static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name"); -/* - * Set by the apply_autocmds_group function if the given event is equal to - * EVENT_FILETYPE. Used by the readfile function in order to determine if - * EVENT_BUFREADPOST triggered the EVENT_FILETYPE. - * - * Relying on this value requires one to reset it prior calling - * apply_autocmds_group. - */ -static int au_did_filetype INIT(= FALSE); - void filemess( buf_T *buf, @@ -6866,6 +6850,11 @@ buf_check_timestamp( reason = "deleted"; else if (bufIsChanged(buf)) reason = "conflict"; + /* + * Check if the file contents really changed to avoid giving a + * warning when only the timestamp was set (e.g., checked out of + * CVS). Always warn when the buffer was changed. + */ else if (orig_size != buf->b_orig_size || buf_contents_changed(buf)) reason = "changed"; else if (orig_mode != buf->b_orig_mode) @@ -6912,12 +6901,6 @@ buf_check_timestamp( #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) can_reload = TRUE; #endif - /* - * Check if the file contents really changed to avoid - * giving a warning when only the timestamp was set (e.g., - * checked out of CVS). Always warn when the buffer was - * changed. - */ if (reason[2] == 'n') { mesg = _("W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well"); @@ -7552,2565 +7535,6 @@ forward_slash(char_u *fname) } #endif - -/* - * Code for automatic commands. - */ - -/* - * The autocommands are stored in a list for each event. - * Autocommands for the same pattern, that are consecutive, are joined - * together, to avoid having to match the pattern too often. - * The result is an array of Autopat lists, which point to AutoCmd lists: - * - * last_autopat[0] -----------------------------+ - * V - * first_autopat[0] --> Autopat.next --> Autopat.next --> NULL - * Autopat.cmds Autopat.cmds - * | | - * V V - * AutoCmd.next AutoCmd.next - * | | - * V V - * AutoCmd.next NULL - * | - * V - * NULL - * - * last_autopat[1] --------+ - * V - * first_autopat[1] --> Autopat.next --> NULL - * Autopat.cmds - * | - * V - * AutoCmd.next - * | - * V - * NULL - * etc. - * - * The order of AutoCmds is important, this is the order in which they were - * defined and will have to be executed. - */ -typedef struct AutoCmd -{ - char_u *cmd; /* The command to be executed (NULL - when command has been removed) */ - char nested; /* If autocommands nest here */ - char last; /* last command in list */ -#ifdef FEAT_EVAL - sctx_T script_ctx; /* script context where defined */ -#endif - struct AutoCmd *next; /* Next AutoCmd in list */ -} AutoCmd; - -typedef struct AutoPat -{ - struct AutoPat *next; /* next AutoPat in AutoPat list; MUST - * be the first entry */ - char_u *pat; /* pattern as typed (NULL when pattern - has been removed) */ - regprog_T *reg_prog; /* compiled regprog for pattern */ - AutoCmd *cmds; /* list of commands to do */ - int group; /* group ID */ - int patlen; /* strlen() of pat */ - int buflocal_nr; /* !=0 for buffer-local AutoPat */ - char allow_dirs; /* Pattern may match whole path */ - char last; /* last pattern for apply_autocmds() */ -} AutoPat; - -static struct event_name -{ - char *name; /* event name */ - event_T event; /* event number */ -} event_names[] = -{ - {"BufAdd", EVENT_BUFADD}, - {"BufCreate", EVENT_BUFADD}, - {"BufDelete", EVENT_BUFDELETE}, - {"BufEnter", EVENT_BUFENTER}, - {"BufFilePost", EVENT_BUFFILEPOST}, - {"BufFilePre", EVENT_BUFFILEPRE}, - {"BufHidden", EVENT_BUFHIDDEN}, - {"BufLeave", EVENT_BUFLEAVE}, - {"BufNew", EVENT_BUFNEW}, - {"BufNewFile", EVENT_BUFNEWFILE}, - {"BufRead", EVENT_BUFREADPOST}, - {"BufReadCmd", EVENT_BUFREADCMD}, - {"BufReadPost", EVENT_BUFREADPOST}, - {"BufReadPre", EVENT_BUFREADPRE}, - {"BufUnload", EVENT_BUFUNLOAD}, - {"BufWinEnter", EVENT_BUFWINENTER}, - {"BufWinLeave", EVENT_BUFWINLEAVE}, - {"BufWipeout", EVENT_BUFWIPEOUT}, - {"BufWrite", EVENT_BUFWRITEPRE}, - {"BufWritePost", EVENT_BUFWRITEPOST}, - {"BufWritePre", EVENT_BUFWRITEPRE}, - {"BufWriteCmd", EVENT_BUFWRITECMD}, - {"CmdlineChanged", EVENT_CMDLINECHANGED}, - {"CmdlineEnter", EVENT_CMDLINEENTER}, - {"CmdlineLeave", EVENT_CMDLINELEAVE}, - {"CmdwinEnter", EVENT_CMDWINENTER}, - {"CmdwinLeave", EVENT_CMDWINLEAVE}, - {"CmdUndefined", EVENT_CMDUNDEFINED}, - {"ColorScheme", EVENT_COLORSCHEME}, - {"ColorSchemePre", EVENT_COLORSCHEMEPRE}, - {"CompleteDone", EVENT_COMPLETEDONE}, - {"CursorHold", EVENT_CURSORHOLD}, - {"CursorHoldI", EVENT_CURSORHOLDI}, - {"CursorMoved", EVENT_CURSORMOVED}, - {"CursorMovedI", EVENT_CURSORMOVEDI}, - {"DiffUpdated", EVENT_DIFFUPDATED}, - {"DirChanged", EVENT_DIRCHANGED}, - {"EncodingChanged", EVENT_ENCODINGCHANGED}, - {"ExitPre", EVENT_EXITPRE}, - {"FileEncoding", EVENT_ENCODINGCHANGED}, - {"FileAppendPost", EVENT_FILEAPPENDPOST}, - {"FileAppendPre", EVENT_FILEAPPENDPRE}, - {"FileAppendCmd", EVENT_FILEAPPENDCMD}, - {"FileChangedShell",EVENT_FILECHANGEDSHELL}, - {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST}, - {"FileChangedRO", EVENT_FILECHANGEDRO}, - {"FileReadPost", EVENT_FILEREADPOST}, - {"FileReadPre", EVENT_FILEREADPRE}, - {"FileReadCmd", EVENT_FILEREADCMD}, - {"FileType", EVENT_FILETYPE}, - {"FileWritePost", EVENT_FILEWRITEPOST}, - {"FileWritePre", EVENT_FILEWRITEPRE}, - {"FileWriteCmd", EVENT_FILEWRITECMD}, - {"FilterReadPost", EVENT_FILTERREADPOST}, - {"FilterReadPre", EVENT_FILTERREADPRE}, - {"FilterWritePost", EVENT_FILTERWRITEPOST}, - {"FilterWritePre", EVENT_FILTERWRITEPRE}, - {"FocusGained", EVENT_FOCUSGAINED}, - {"FocusLost", EVENT_FOCUSLOST}, - {"FuncUndefined", EVENT_FUNCUNDEFINED}, - {"GUIEnter", EVENT_GUIENTER}, - {"GUIFailed", EVENT_GUIFAILED}, - {"InsertChange", EVENT_INSERTCHANGE}, - {"InsertEnter", EVENT_INSERTENTER}, - {"InsertLeave", EVENT_INSERTLEAVE}, - {"InsertCharPre", EVENT_INSERTCHARPRE}, - {"MenuPopup", EVENT_MENUPOPUP}, - {"OptionSet", EVENT_OPTIONSET}, - {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST}, - {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE}, - {"QuitPre", EVENT_QUITPRE}, - {"RemoteReply", EVENT_REMOTEREPLY}, - {"SessionLoadPost", EVENT_SESSIONLOADPOST}, - {"ShellCmdPost", EVENT_SHELLCMDPOST}, - {"ShellFilterPost", EVENT_SHELLFILTERPOST}, - {"SourceCmd", EVENT_SOURCECMD}, - {"SourcePre", EVENT_SOURCEPRE}, - {"SourcePost", EVENT_SOURCEPOST}, - {"SpellFileMissing",EVENT_SPELLFILEMISSING}, - {"StdinReadPost", EVENT_STDINREADPOST}, - {"StdinReadPre", EVENT_STDINREADPRE}, - {"SwapExists", EVENT_SWAPEXISTS}, - {"Syntax", EVENT_SYNTAX}, - {"TabNew", EVENT_TABNEW}, - {"TabClosed", EVENT_TABCLOSED}, - {"TabEnter", EVENT_TABENTER}, - {"TabLeave", EVENT_TABLEAVE}, - {"TermChanged", EVENT_TERMCHANGED}, - {"TerminalOpen", EVENT_TERMINALOPEN}, - {"TermResponse", EVENT_TERMRESPONSE}, - {"TextChanged", EVENT_TEXTCHANGED}, - {"TextChangedI", EVENT_TEXTCHANGEDI}, - {"TextChangedP", EVENT_TEXTCHANGEDP}, - {"User", EVENT_USER}, - {"VimEnter", EVENT_VIMENTER}, - {"VimLeave", EVENT_VIMLEAVE}, - {"VimLeavePre", EVENT_VIMLEAVEPRE}, - {"WinNew", EVENT_WINNEW}, - {"WinEnter", EVENT_WINENTER}, - {"WinLeave", EVENT_WINLEAVE}, - {"VimResized", EVENT_VIMRESIZED}, - {"TextYankPost", EVENT_TEXTYANKPOST}, - {NULL, (event_T)0} -}; - -static AutoPat *first_autopat[NUM_EVENTS] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -static AutoPat *last_autopat[NUM_EVENTS] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -/* - * struct used to keep status while executing autocommands for an event. - */ -typedef struct AutoPatCmd -{ - AutoPat *curpat; /* next AutoPat to examine */ - AutoCmd *nextcmd; /* next AutoCmd to execute */ - int group; /* group being used */ - char_u *fname; /* fname to match with */ - char_u *sfname; /* sfname to match with */ - char_u *tail; /* tail of fname */ - event_T event; /* current event */ - int arg_bufnr; /* initially equal to , set to zero when - buf is deleted */ - struct AutoPatCmd *next; /* chain of active apc-s for auto-invalidation*/ -} AutoPatCmd; - -static AutoPatCmd *active_apc_list = NULL; /* stack of active autocommands */ - -/* - * augroups stores a list of autocmd group names. - */ -static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL}; -#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i]) -/* use get_deleted_augroup() to get this */ -static char_u *deleted_augroup = NULL; - -/* - * The ID of the current group. Group 0 is the default one. - */ -static int current_augroup = AUGROUP_DEFAULT; - -static int au_need_clean = FALSE; /* need to delete marked patterns */ - -static char_u *event_nr2name(event_T event); -static int au_get_grouparg(char_u **argp); -static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group); -static int apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap); -static void auto_next_pat(AutoPatCmd *apc, int stop_at_last); -static int match_file_pat(char_u *pattern, regprog_T **prog, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs); - - -static event_T last_event; -static int last_group; -static int autocmd_blocked = 0; /* block all autocmds */ - - static char_u * -get_deleted_augroup(void) -{ - if (deleted_augroup == NULL) - deleted_augroup = (char_u *)_("--Deleted--"); - return deleted_augroup; -} - -/* - * Show the autocommands for one AutoPat. - */ - static void -show_autocmd(AutoPat *ap, event_T event) -{ - AutoCmd *ac; - - /* Check for "got_int" (here and at various places below), which is set - * when "q" has been hit for the "--more--" prompt */ - if (got_int) - return; - if (ap->pat == NULL) /* pattern has been removed */ - return; - - msg_putchar('\n'); - if (got_int) - return; - if (event != last_event || ap->group != last_group) - { - if (ap->group != AUGROUP_DEFAULT) - { - if (AUGROUP_NAME(ap->group) == NULL) - msg_puts_attr((char *)get_deleted_augroup(), HL_ATTR(HLF_E)); - else - msg_puts_attr((char *)AUGROUP_NAME(ap->group), HL_ATTR(HLF_T)); - msg_puts(" "); - } - msg_puts_attr((char *)event_nr2name(event), HL_ATTR(HLF_T)); - last_event = event; - last_group = ap->group; - msg_putchar('\n'); - if (got_int) - return; - } - msg_col = 4; - msg_outtrans(ap->pat); - - for (ac = ap->cmds; ac != NULL; ac = ac->next) - { - if (ac->cmd != NULL) /* skip removed commands */ - { - if (msg_col >= 14) - msg_putchar('\n'); - msg_col = 14; - if (got_int) - return; - msg_outtrans(ac->cmd); -#ifdef FEAT_EVAL - if (p_verbose > 0) - last_set_msg(ac->script_ctx); -#endif - if (got_int) - return; - if (ac->next != NULL) - { - msg_putchar('\n'); - if (got_int) - return; - } - } - } -} - -/* - * Mark an autocommand pattern for deletion. - */ - static void -au_remove_pat(AutoPat *ap) -{ - VIM_CLEAR(ap->pat); - ap->buflocal_nr = -1; - au_need_clean = TRUE; -} - -/* - * Mark all commands for a pattern for deletion. - */ - static void -au_remove_cmds(AutoPat *ap) -{ - AutoCmd *ac; - - for (ac = ap->cmds; ac != NULL; ac = ac->next) - VIM_CLEAR(ac->cmd); - au_need_clean = TRUE; -} - -/* - * Cleanup autocommands and patterns that have been deleted. - * This is only done when not executing autocommands. - */ - static void -au_cleanup(void) -{ - AutoPat *ap, **prev_ap; - AutoCmd *ac, **prev_ac; - event_T event; - - if (autocmd_busy || !au_need_clean) - return; - - /* loop over all events */ - for (event = (event_T)0; (int)event < (int)NUM_EVENTS; - event = (event_T)((int)event + 1)) - { - /* loop over all autocommand patterns */ - prev_ap = &(first_autopat[(int)event]); - for (ap = *prev_ap; ap != NULL; ap = *prev_ap) - { - /* loop over all commands for this pattern */ - prev_ac = &(ap->cmds); - for (ac = *prev_ac; ac != NULL; ac = *prev_ac) - { - /* remove the command if the pattern is to be deleted or when - * the command has been marked for deletion */ - if (ap->pat == NULL || ac->cmd == NULL) - { - *prev_ac = ac->next; - vim_free(ac->cmd); - vim_free(ac); - } - else - prev_ac = &(ac->next); - } - - /* remove the pattern if it has been marked for deletion */ - if (ap->pat == NULL) - { - if (ap->next == NULL) - { - if (prev_ap == &(first_autopat[(int)event])) - last_autopat[(int)event] = NULL; - else - /* this depends on the "next" field being the first in - * the struct */ - last_autopat[(int)event] = (AutoPat *)prev_ap; - } - *prev_ap = ap->next; - vim_regfree(ap->reg_prog); - vim_free(ap); - } - else - prev_ap = &(ap->next); - } - } - - au_need_clean = FALSE; -} - -/* - * Called when buffer is freed, to remove/invalidate related buffer-local - * autocmds. - */ - void -aubuflocal_remove(buf_T *buf) -{ - AutoPat *ap; - event_T event; - AutoPatCmd *apc; - - /* invalidate currently executing autocommands */ - for (apc = active_apc_list; apc; apc = apc->next) - if (buf->b_fnum == apc->arg_bufnr) - apc->arg_bufnr = 0; - - /* invalidate buflocals looping through events */ - for (event = (event_T)0; (int)event < (int)NUM_EVENTS; - event = (event_T)((int)event + 1)) - /* loop over all autocommand patterns */ - for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) - if (ap->buflocal_nr == buf->b_fnum) - { - au_remove_pat(ap); - if (p_verbose >= 6) - { - verbose_enter(); - smsg(_("auto-removing autocommand: %s "), - event_nr2name(event), buf->b_fnum); - verbose_leave(); - } - } - au_cleanup(); -} - -/* - * Add an autocmd group name. - * Return its ID. Returns AUGROUP_ERROR (< 0) for error. - */ - static int -au_new_group(char_u *name) -{ - int i; - - i = au_find_group(name); - if (i == AUGROUP_ERROR) /* the group doesn't exist yet, add it */ - { - /* First try using a free entry. */ - for (i = 0; i < augroups.ga_len; ++i) - if (AUGROUP_NAME(i) == NULL) - break; - if (i == augroups.ga_len && ga_grow(&augroups, 1) == FAIL) - return AUGROUP_ERROR; - - AUGROUP_NAME(i) = vim_strsave(name); - if (AUGROUP_NAME(i) == NULL) - return AUGROUP_ERROR; - if (i == augroups.ga_len) - ++augroups.ga_len; - } - - return i; -} - - static void -au_del_group(char_u *name) -{ - int i; - - i = au_find_group(name); - if (i == AUGROUP_ERROR) /* the group doesn't exist */ - semsg(_("E367: No such group: \"%s\""), name); - else if (i == current_augroup) - emsg(_("E936: Cannot delete the current group")); - else - { - event_T event; - AutoPat *ap; - int in_use = FALSE; - - for (event = (event_T)0; (int)event < (int)NUM_EVENTS; - event = (event_T)((int)event + 1)) - { - for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) - if (ap->group == i && ap->pat != NULL) - { - give_warning((char_u *)_("W19: Deleting augroup that is still in use"), TRUE); - in_use = TRUE; - event = NUM_EVENTS; - break; - } - } - vim_free(AUGROUP_NAME(i)); - if (in_use) - { - AUGROUP_NAME(i) = get_deleted_augroup(); - } - else - AUGROUP_NAME(i) = NULL; - } -} - -/* - * Find the ID of an autocmd group name. - * Return its ID. Returns AUGROUP_ERROR (< 0) for error. - */ - static int -au_find_group(char_u *name) -{ - int i; - - for (i = 0; i < augroups.ga_len; ++i) - if (AUGROUP_NAME(i) != NULL && AUGROUP_NAME(i) != get_deleted_augroup() - && STRCMP(AUGROUP_NAME(i), name) == 0) - return i; - return AUGROUP_ERROR; -} - -/* - * Return TRUE if augroup "name" exists. - */ - int -au_has_group(char_u *name) -{ - return au_find_group(name) != AUGROUP_ERROR; -} - -/* - * ":augroup {name}". - */ - void -do_augroup(char_u *arg, int del_group) -{ - int i; - - if (del_group) - { - if (*arg == NUL) - emsg(_(e_argreq)); - else - au_del_group(arg); - } - else if (STRICMP(arg, "end") == 0) /* ":aug end": back to group 0 */ - current_augroup = AUGROUP_DEFAULT; - else if (*arg) /* ":aug xxx": switch to group xxx */ - { - i = au_new_group(arg); - if (i != AUGROUP_ERROR) - current_augroup = i; - } - else /* ":aug": list the group names */ - { - msg_start(); - for (i = 0; i < augroups.ga_len; ++i) - { - if (AUGROUP_NAME(i) != NULL) - { - msg_puts((char *)AUGROUP_NAME(i)); - msg_puts(" "); - } - } - msg_clr_eos(); - msg_end(); - } -} - -#if defined(EXITFREE) || defined(PROTO) - void -free_all_autocmds(void) -{ - int i; - char_u *s; - - for (current_augroup = -1; current_augroup < augroups.ga_len; - ++current_augroup) - do_autocmd((char_u *)"", TRUE); - - for (i = 0; i < augroups.ga_len; ++i) - { - s = ((char_u **)(augroups.ga_data))[i]; - if (s != get_deleted_augroup()) - vim_free(s); - } - ga_clear(&augroups); -} -#endif - -/* - * Return the event number for event name "start". - * Return NUM_EVENTS if the event name was not found. - * Return a pointer to the next event name in "end". - */ - static event_T -event_name2nr(char_u *start, char_u **end) -{ - char_u *p; - int i; - int len; - - /* the event name ends with end of line, '|', a blank or a comma */ - for (p = start; *p && !VIM_ISWHITE(*p) && *p != ',' && *p != '|'; ++p) - ; - for (i = 0; event_names[i].name != NULL; ++i) - { - len = (int)STRLEN(event_names[i].name); - if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0) - break; - } - if (*p == ',') - ++p; - *end = p; - if (event_names[i].name == NULL) - return NUM_EVENTS; - return event_names[i].event; -} - -/* - * Return the name for event "event". - */ - static char_u * -event_nr2name(event_T event) -{ - int i; - - for (i = 0; event_names[i].name != NULL; ++i) - if (event_names[i].event == event) - return (char_u *)event_names[i].name; - return (char_u *)"Unknown"; -} - -/* - * Scan over the events. "*" stands for all events. - */ - static char_u * -find_end_event( - char_u *arg, - int have_group) /* TRUE when group name was found */ -{ - char_u *pat; - char_u *p; - - if (*arg == '*') - { - if (arg[1] && !VIM_ISWHITE(arg[1])) - { - semsg(_("E215: Illegal character after *: %s"), arg); - return NULL; - } - pat = arg + 1; - } - else - { - for (pat = arg; *pat && *pat != '|' && !VIM_ISWHITE(*pat); pat = p) - { - if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) - { - if (have_group) - semsg(_("E216: No such event: %s"), pat); - else - semsg(_("E216: No such group or event: %s"), pat); - return NULL; - } - } - } - return pat; -} - -/* - * Return TRUE if "event" is included in 'eventignore'. - */ - static int -event_ignored(event_T event) -{ - char_u *p = p_ei; - - while (*p != NUL) - { - if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) - return TRUE; - if (event_name2nr(p, &p) == event) - return TRUE; - } - - return FALSE; -} - -/* - * Return OK when the contents of p_ei is valid, FAIL otherwise. - */ - int -check_ei(void) -{ - char_u *p = p_ei; - - while (*p) - { - if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) - { - p += 3; - if (*p == ',') - ++p; - } - else if (event_name2nr(p, &p) == NUM_EVENTS) - return FAIL; - } - - return OK; -} - -# if defined(FEAT_SYN_HL) || defined(PROTO) - -/* - * Add "what" to 'eventignore' to skip loading syntax highlighting for every - * buffer loaded into the window. "what" must start with a comma. - * Returns the old value of 'eventignore' in allocated memory. - */ - char_u * -au_event_disable(char *what) -{ - char_u *new_ei; - char_u *save_ei; - - save_ei = vim_strsave(p_ei); - if (save_ei != NULL) - { - new_ei = vim_strnsave(p_ei, (int)(STRLEN(p_ei) + STRLEN(what))); - if (new_ei != NULL) - { - if (*what == ',' && *p_ei == NUL) - STRCPY(new_ei, what + 1); - else - STRCAT(new_ei, what); - set_string_option_direct((char_u *)"ei", -1, new_ei, - OPT_FREE, SID_NONE); - vim_free(new_ei); - } - } - return save_ei; -} - - void -au_event_restore(char_u *old_ei) -{ - if (old_ei != NULL) - { - set_string_option_direct((char_u *)"ei", -1, old_ei, - OPT_FREE, SID_NONE); - vim_free(old_ei); - } -} -# endif /* FEAT_SYN_HL */ - -/* - * do_autocmd() -- implements the :autocmd command. Can be used in the - * following ways: - * - * :autocmd Add to the list of commands that - * will be automatically executed for - * when editing a file matching , in - * the current group. - * :autocmd Show the autocommands associated with - * and . - * :autocmd Show the autocommands associated with - * . - * :autocmd Show all autocommands. - * :autocmd! Remove all autocommands associated with - * and , and add the command - * , for the current group. - * :autocmd! Remove all autocommands associated with - * and for the current group. - * :autocmd! Remove all autocommands associated with - * for the current group. - * :autocmd! Remove ALL autocommands for the current - * group. - * - * Multiple events and patterns may be given separated by commas. Here are - * some examples: - * :autocmd bufread,bufenter *.c,*.h set tw=0 smartindent noic - * :autocmd bufleave * set tw=79 nosmartindent ic infercase - * - * :autocmd * *.c show all autocommands for *.c files. - * - * Mostly a {group} argument can optionally appear before . - */ - void -do_autocmd(char_u *arg_in, int forceit) -{ - char_u *arg = arg_in; - char_u *pat; - char_u *envpat = NULL; - char_u *cmd; - event_T event; - int need_free = FALSE; - int nested = FALSE; - int group; - - if (*arg == '|') - { - arg = (char_u *)""; - group = AUGROUP_ALL; /* no argument, use all groups */ - } - else - { - /* - * Check for a legal group name. If not, use AUGROUP_ALL. - */ - group = au_get_grouparg(&arg); - if (arg == NULL) /* out of memory */ - return; - } - - /* - * Scan over the events. - * If we find an illegal name, return here, don't do anything. - */ - pat = find_end_event(arg, group != AUGROUP_ALL); - if (pat == NULL) - return; - - pat = skipwhite(pat); - if (*pat == '|') - { - pat = (char_u *)""; - cmd = (char_u *)""; - } - else - { - /* - * Scan over the pattern. Put a NUL at the end. - */ - cmd = pat; - while (*cmd && (!VIM_ISWHITE(*cmd) || cmd[-1] == '\\')) - cmd++; - if (*cmd) - *cmd++ = NUL; - - /* Expand environment variables in the pattern. Set 'shellslash', we want - * forward slashes here. */ - if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) - { -#ifdef BACKSLASH_IN_FILENAME - int p_ssl_save = p_ssl; - - p_ssl = TRUE; -#endif - envpat = expand_env_save(pat); -#ifdef BACKSLASH_IN_FILENAME - p_ssl = p_ssl_save; -#endif - if (envpat != NULL) - pat = envpat; - } - - /* - * Check for "nested" flag. - */ - cmd = skipwhite(cmd); - if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && VIM_ISWHITE(cmd[6])) - { - nested = TRUE; - cmd = skipwhite(cmd + 6); - } - - /* - * Find the start of the commands. - * Expand in it. - */ - if (*cmd != NUL) - { - cmd = expand_sfile(cmd); - if (cmd == NULL) /* some error */ - return; - need_free = TRUE; - } - } - - /* - * Print header when showing autocommands. - */ - if (!forceit && *cmd == NUL) - { - /* Highlight title */ - msg_puts_title(_("\n--- Autocommands ---")); - } - - /* - * Loop over the events. - */ - last_event = (event_T)-1; /* for listing the event name */ - last_group = AUGROUP_ERROR; /* for listing the group name */ - if (*arg == '*' || *arg == NUL || *arg == '|') - { - for (event = (event_T)0; (int)event < (int)NUM_EVENTS; - event = (event_T)((int)event + 1)) - if (do_autocmd_event(event, pat, - nested, cmd, forceit, group) == FAIL) - break; - } - else - { - while (*arg && *arg != '|' && !VIM_ISWHITE(*arg)) - if (do_autocmd_event(event_name2nr(arg, &arg), pat, - nested, cmd, forceit, group) == FAIL) - break; - } - - if (need_free) - vim_free(cmd); - vim_free(envpat); -} - -/* - * Find the group ID in a ":autocmd" or ":doautocmd" argument. - * The "argp" argument is advanced to the following argument. - * - * Returns the group ID, AUGROUP_ERROR for error (out of memory). - */ - static int -au_get_grouparg(char_u **argp) -{ - char_u *group_name; - char_u *p; - char_u *arg = *argp; - int group = AUGROUP_ALL; - - for (p = arg; *p && !VIM_ISWHITE(*p) && *p != '|'; ++p) - ; - if (p > arg) - { - group_name = vim_strnsave(arg, (int)(p - arg)); - if (group_name == NULL) /* out of memory */ - return AUGROUP_ERROR; - group = au_find_group(group_name); - if (group == AUGROUP_ERROR) - group = AUGROUP_ALL; /* no match, use all groups */ - else - *argp = skipwhite(p); /* match, skip over group name */ - vim_free(group_name); - } - return group; -} - -/* - * do_autocmd() for one event. - * If *pat == NUL do for all patterns. - * If *cmd == NUL show entries. - * If forceit == TRUE delete entries. - * If group is not AUGROUP_ALL, only use this group. - */ - static int -do_autocmd_event( - event_T event, - char_u *pat, - int nested, - char_u *cmd, - int forceit, - int group) -{ - AutoPat *ap; - AutoPat **prev_ap; - AutoCmd *ac; - AutoCmd **prev_ac; - int brace_level; - char_u *endpat; - int findgroup; - int allgroups; - int patlen; - int is_buflocal; - int buflocal_nr; - char_u buflocal_pat[25]; /* for "" */ - - if (group == AUGROUP_ALL) - findgroup = current_augroup; - else - findgroup = group; - allgroups = (group == AUGROUP_ALL && !forceit && *cmd == NUL); - - /* - * Show or delete all patterns for an event. - */ - if (*pat == NUL) - { - for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) - { - if (forceit) /* delete the AutoPat, if it's in the current group */ - { - if (ap->group == findgroup) - au_remove_pat(ap); - } - else if (group == AUGROUP_ALL || ap->group == group) - show_autocmd(ap, event); - } - } - - /* - * Loop through all the specified patterns. - */ - for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat)) - { - /* - * Find end of the pattern. - * Watch out for a comma in braces, like "*.\{obj,o\}". - */ - brace_level = 0; - for (endpat = pat; *endpat && (*endpat != ',' || brace_level - || (endpat > pat && endpat[-1] == '\\')); ++endpat) - { - if (*endpat == '{') - brace_level++; - else if (*endpat == '}') - brace_level--; - } - if (pat == endpat) /* ignore single comma */ - continue; - patlen = (int)(endpat - pat); - - /* - * detect special buffer-local patterns - */ - is_buflocal = FALSE; - buflocal_nr = 0; - - if (patlen >= 8 && STRNCMP(pat, "') - { - /* "": Error will be printed only for addition. - * printing and removing will proceed silently. */ - is_buflocal = TRUE; - if (patlen == 8) - /* "" */ - buflocal_nr = curbuf->b_fnum; - else if (patlen > 9 && pat[7] == '=') - { - if (patlen == 13 && STRNICMP(pat, "", 13) == 0) - /* "" */ - buflocal_nr = autocmd_bufnr; - else if (skipdigits(pat + 8) == pat + patlen - 1) - /* "" */ - buflocal_nr = atoi((char *)pat + 8); - } - } - - if (is_buflocal) - { - /* normalize pat into standard "#N" form */ - sprintf((char *)buflocal_pat, "", buflocal_nr); - pat = buflocal_pat; /* can modify pat and patlen */ - patlen = (int)STRLEN(buflocal_pat); /* but not endpat */ - } - - /* - * Find AutoPat entries with this pattern. When adding a command it - * always goes at or after the last one, so start at the end. - */ - if (!forceit && *cmd != NUL && last_autopat[(int)event] != NULL) - prev_ap = &last_autopat[(int)event]; - else - prev_ap = &first_autopat[(int)event]; - while ((ap = *prev_ap) != NULL) - { - if (ap->pat != NULL) - { - /* Accept a pattern when: - * - a group was specified and it's that group, or a group was - * not specified and it's the current group, or a group was - * not specified and we are listing - * - the length of the pattern matches - * - the pattern matches. - * For , this condition works because we normalize - * all buffer-local patterns. - */ - if ((allgroups || ap->group == findgroup) - && ap->patlen == patlen - && STRNCMP(pat, ap->pat, patlen) == 0) - { - /* - * Remove existing autocommands. - * If adding any new autocmd's for this AutoPat, don't - * delete the pattern from the autopat list, append to - * this list. - */ - if (forceit) - { - if (*cmd != NUL && ap->next == NULL) - { - au_remove_cmds(ap); - break; - } - au_remove_pat(ap); - } - - /* - * Show autocmd's for this autopat, or buflocals - */ - else if (*cmd == NUL) - show_autocmd(ap, event); - - /* - * Add autocmd to this autopat, if it's the last one. - */ - else if (ap->next == NULL) - break; - } - } - prev_ap = &ap->next; - } - - /* - * Add a new command. - */ - if (*cmd != NUL) - { - /* - * If the pattern we want to add a command to does appear at the - * end of the list (or not is not in the list at all), add the - * pattern at the end of the list. - */ - if (ap == NULL) - { - /* refuse to add buffer-local ap if buffer number is invalid */ - if (is_buflocal && (buflocal_nr == 0 - || buflist_findnr(buflocal_nr) == NULL)) - { - semsg(_("E680: : invalid buffer number "), - buflocal_nr); - return FAIL; - } - - ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat)); - if (ap == NULL) - return FAIL; - ap->pat = vim_strnsave(pat, patlen); - ap->patlen = patlen; - if (ap->pat == NULL) - { - vim_free(ap); - return FAIL; - } - - if (is_buflocal) - { - ap->buflocal_nr = buflocal_nr; - ap->reg_prog = NULL; - } - else - { - char_u *reg_pat; - - ap->buflocal_nr = 0; - reg_pat = file_pat_to_reg_pat(pat, endpat, - &ap->allow_dirs, TRUE); - if (reg_pat != NULL) - ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC); - vim_free(reg_pat); - if (reg_pat == NULL || ap->reg_prog == NULL) - { - vim_free(ap->pat); - vim_free(ap); - return FAIL; - } - } - ap->cmds = NULL; - *prev_ap = ap; - last_autopat[(int)event] = ap; - ap->next = NULL; - if (group == AUGROUP_ALL) - ap->group = current_augroup; - else - ap->group = group; - } - - /* - * Add the autocmd at the end of the AutoCmd list. - */ - prev_ac = &(ap->cmds); - while ((ac = *prev_ac) != NULL) - prev_ac = &ac->next; - ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd)); - if (ac == NULL) - return FAIL; - ac->cmd = vim_strsave(cmd); -#ifdef FEAT_EVAL - ac->script_ctx = current_sctx; - ac->script_ctx.sc_lnum += sourcing_lnum; -#endif - if (ac->cmd == NULL) - { - vim_free(ac); - return FAIL; - } - ac->next = NULL; - *prev_ac = ac; - ac->nested = nested; - } - } - - au_cleanup(); /* may really delete removed patterns/commands now */ - return OK; -} - -/* - * Implementation of ":doautocmd [group] event [fname]". - * Return OK for success, FAIL for failure; - */ - int -do_doautocmd( - char_u *arg, - int do_msg, /* give message for no matching autocmds? */ - int *did_something) -{ - char_u *fname; - int nothing_done = TRUE; - int group; - - if (did_something != NULL) - *did_something = FALSE; - - /* - * Check for a legal group name. If not, use AUGROUP_ALL. - */ - group = au_get_grouparg(&arg); - if (arg == NULL) /* out of memory */ - return FAIL; - - if (*arg == '*') - { - emsg(_("E217: Can't execute autocommands for ALL events")); - return FAIL; - } - - /* - * Scan over the events. - * If we find an illegal name, return here, don't do anything. - */ - fname = find_end_event(arg, group != AUGROUP_ALL); - if (fname == NULL) - return FAIL; - - fname = skipwhite(fname); - - /* - * Loop over the events. - */ - while (*arg && !ends_excmd(*arg) && !VIM_ISWHITE(*arg)) - if (apply_autocmds_group(event_name2nr(arg, &arg), - fname, NULL, TRUE, group, curbuf, NULL)) - nothing_done = FALSE; - - if (nothing_done && do_msg) - msg(_("No matching autocommands")); - if (did_something != NULL) - *did_something = !nothing_done; - -#ifdef FEAT_EVAL - return aborting() ? FAIL : OK; -#else - return OK; -#endif -} - -/* - * ":doautoall": execute autocommands for each loaded buffer. - */ - void -ex_doautoall(exarg_T *eap) -{ - int retval; - aco_save_T aco; - buf_T *buf; - bufref_T bufref; - char_u *arg = eap->arg; - int call_do_modelines = check_nomodeline(&arg); - int did_aucmd; - - /* - * This is a bit tricky: For some commands curwin->w_buffer needs to be - * equal to curbuf, but for some buffers there may not be a window. - * So we change the buffer for the current window for a moment. This - * gives problems when the autocommands make changes to the list of - * buffers or windows... - */ - FOR_ALL_BUFFERS(buf) - { - if (buf->b_ml.ml_mfp != NULL) - { - /* find a window for this buffer and save some values */ - aucmd_prepbuf(&aco, buf); - set_bufref(&bufref, buf); - - /* execute the autocommands for this buffer */ - retval = do_doautocmd(arg, FALSE, &did_aucmd); - - if (call_do_modelines && did_aucmd) - { - /* Execute the modeline settings, but don't set window-local - * options if we are using the current window for another - * buffer. */ - do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0); - } - - /* restore the current window */ - aucmd_restbuf(&aco); - - /* stop if there is some error or buffer was deleted */ - if (retval == FAIL || !bufref_valid(&bufref)) - break; - } - } - - check_cursor(); /* just in case lines got deleted */ -} - -/* - * Check *argp for . When it is present return FALSE, otherwise - * return TRUE and advance *argp to after it. - * Thus return TRUE when do_modelines() should be called. - */ - int -check_nomodeline(char_u **argp) -{ - if (STRNCMP(*argp, "", 12) == 0) - { - *argp = skipwhite(*argp + 12); - return FALSE; - } - return TRUE; -} - -/* - * Prepare for executing autocommands for (hidden) buffer "buf". - * Search for a visible window containing the current buffer. If there isn't - * one then use "aucmd_win". - * Set "curbuf" and "curwin" to match "buf". - */ - void -aucmd_prepbuf( - aco_save_T *aco, /* structure to save values in */ - buf_T *buf) /* new curbuf */ -{ - win_T *win; - int save_ea; -#ifdef FEAT_AUTOCHDIR - int save_acd; -#endif - - /* Find a window that is for the new buffer */ - if (buf == curbuf) /* be quick when buf is curbuf */ - win = curwin; - else - FOR_ALL_WINDOWS(win) - if (win->w_buffer == buf) - break; - - /* Allocate "aucmd_win" when needed. If this fails (out of memory) fall - * back to using the current window. */ - if (win == NULL && aucmd_win == NULL) - { - win_alloc_aucmd_win(); - if (aucmd_win == NULL) - win = curwin; - } - if (win == NULL && aucmd_win_used) - /* Strange recursive autocommand, fall back to using the current - * window. Expect a few side effects... */ - win = curwin; - - aco->save_curwin = curwin; - aco->save_curbuf = curbuf; - aco->save_prevwin = prevwin; - if (win != NULL) - { - /* There is a window for "buf" in the current tab page, make it the - * curwin. This is preferred, it has the least side effects (esp. if - * "buf" is curbuf). */ - aco->use_aucmd_win = FALSE; - curwin = win; - } - else - { - /* There is no window for "buf", use "aucmd_win". To minimize the side - * effects, insert it in the current tab page. - * Anything related to a window (e.g., setting folds) may have - * unexpected results. */ - aco->use_aucmd_win = TRUE; - aucmd_win_used = TRUE; - aucmd_win->w_buffer = buf; -#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) - aucmd_win->w_s = &buf->b_s; -#endif - ++buf->b_nwindows; - win_init_empty(aucmd_win); /* set cursor and topline to safe values */ - - /* Make sure w_localdir and globaldir are NULL to avoid a chdir() in - * win_enter_ext(). */ - VIM_CLEAR(aucmd_win->w_localdir); - aco->globaldir = globaldir; - globaldir = NULL; - - - /* Split the current window, put the aucmd_win in the upper half. - * We don't want the BufEnter or WinEnter autocommands. */ - block_autocmds(); - make_snapshot(SNAP_AUCMD_IDX); - save_ea = p_ea; - p_ea = FALSE; - -#ifdef FEAT_AUTOCHDIR - /* Prevent chdir() call in win_enter_ext(), through do_autochdir(). */ - save_acd = p_acd; - p_acd = FALSE; -#endif - - (void)win_split_ins(0, WSP_TOP, aucmd_win, 0); - (void)win_comp_pos(); /* recompute window positions */ - p_ea = save_ea; -#ifdef FEAT_AUTOCHDIR - p_acd = save_acd; -#endif - unblock_autocmds(); - curwin = aucmd_win; - } - curbuf = buf; - aco->new_curwin = curwin; - set_bufref(&aco->new_curbuf, curbuf); -} - -/* - * Cleanup after executing autocommands for a (hidden) buffer. - * Restore the window as it was (if possible). - */ - void -aucmd_restbuf( - aco_save_T *aco) /* structure holding saved values */ -{ - int dummy; - - if (aco->use_aucmd_win) - { - --curbuf->b_nwindows; - /* Find "aucmd_win", it can't be closed, but it may be in another tab - * page. Do not trigger autocommands here. */ - block_autocmds(); - if (curwin != aucmd_win) - { - tabpage_T *tp; - win_T *wp; - - FOR_ALL_TAB_WINDOWS(tp, wp) - { - if (wp == aucmd_win) - { - if (tp != curtab) - goto_tabpage_tp(tp, TRUE, TRUE); - win_goto(aucmd_win); - goto win_found; - } - } - } -win_found: - - /* Remove the window and frame from the tree of frames. */ - (void)winframe_remove(curwin, &dummy, NULL); - win_remove(curwin, NULL); - aucmd_win_used = FALSE; - last_status(FALSE); /* may need to remove last status line */ - - if (!valid_tabpage_win(curtab)) - /* no valid window in current tabpage */ - close_tabpage(curtab); - - restore_snapshot(SNAP_AUCMD_IDX, FALSE); - (void)win_comp_pos(); /* recompute window positions */ - unblock_autocmds(); - - if (win_valid(aco->save_curwin)) - curwin = aco->save_curwin; - else - /* Hmm, original window disappeared. Just use the first one. */ - curwin = firstwin; - if (win_valid(aco->save_prevwin)) - prevwin = aco->save_prevwin; -#ifdef FEAT_EVAL - vars_clear(&aucmd_win->w_vars->dv_hashtab); /* free all w: variables */ - hash_init(&aucmd_win->w_vars->dv_hashtab); /* re-use the hashtab */ -#endif - curbuf = curwin->w_buffer; - - vim_free(globaldir); - globaldir = aco->globaldir; - - /* the buffer contents may have changed */ - check_cursor(); - if (curwin->w_topline > curbuf->b_ml.ml_line_count) - { - curwin->w_topline = curbuf->b_ml.ml_line_count; -#ifdef FEAT_DIFF - curwin->w_topfill = 0; -#endif - } -#if defined(FEAT_GUI) - /* Hide the scrollbars from the aucmd_win and update. */ - gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_LEFT], FALSE); - gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_RIGHT], FALSE); - gui_may_update_scrollbars(); -#endif - } - else - { - /* restore curwin */ - if (win_valid(aco->save_curwin)) - { - /* Restore the buffer which was previously edited by curwin, if - * it was changed, we are still the same window and the buffer is - * valid. */ - if (curwin == aco->new_curwin - && curbuf != aco->new_curbuf.br_buf - && bufref_valid(&aco->new_curbuf) - && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) - { -# if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) - if (curwin->w_s == &curbuf->b_s) - curwin->w_s = &aco->new_curbuf.br_buf->b_s; -# endif - --curbuf->b_nwindows; - curbuf = aco->new_curbuf.br_buf; - curwin->w_buffer = curbuf; - ++curbuf->b_nwindows; - } - - curwin = aco->save_curwin; - curbuf = curwin->w_buffer; - if (win_valid(aco->save_prevwin)) - prevwin = aco->save_prevwin; - /* In case the autocommand move the cursor to a position that that - * not exist in curbuf. */ - check_cursor(); - } - } -} - -static int autocmd_nested = FALSE; - -/* - * Execute autocommands for "event" and file name "fname". - * Return TRUE if some commands were executed. - */ - int -apply_autocmds( - event_T event, - char_u *fname, /* NULL or empty means use actual file name */ - char_u *fname_io, /* fname to use for on cmdline */ - int force, /* when TRUE, ignore autocmd_busy */ - buf_T *buf) /* buffer for */ -{ - return apply_autocmds_group(event, fname, fname_io, force, - AUGROUP_ALL, buf, NULL); -} - -/* - * Like apply_autocmds(), but with extra "eap" argument. This takes care of - * setting v:filearg. - */ - static int -apply_autocmds_exarg( - event_T event, - char_u *fname, - char_u *fname_io, - int force, - buf_T *buf, - exarg_T *eap) -{ - return apply_autocmds_group(event, fname, fname_io, force, - AUGROUP_ALL, buf, eap); -} - -/* - * Like apply_autocmds(), but handles the caller's retval. If the script - * processing is being aborted or if retval is FAIL when inside a try - * conditional, no autocommands are executed. If otherwise the autocommands - * cause the script to be aborted, retval is set to FAIL. - */ - int -apply_autocmds_retval( - event_T event, - char_u *fname, /* NULL or empty means use actual file name */ - char_u *fname_io, /* fname to use for on cmdline */ - int force, /* when TRUE, ignore autocmd_busy */ - buf_T *buf, /* buffer for */ - int *retval) /* pointer to caller's retval */ -{ - int did_cmd; - -#ifdef FEAT_EVAL - if (should_abort(*retval)) - return FALSE; -#endif - - did_cmd = apply_autocmds_group(event, fname, fname_io, force, - AUGROUP_ALL, buf, NULL); - if (did_cmd -#ifdef FEAT_EVAL - && aborting() -#endif - ) - *retval = FAIL; - return did_cmd; -} - -/* - * Return TRUE when there is a CursorHold autocommand defined. - */ - int -has_cursorhold(void) -{ - return (first_autopat[(int)(get_real_state() == NORMAL_BUSY - ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL); -} - -/* - * Return TRUE if the CursorHold event can be triggered. - */ - int -trigger_cursorhold(void) -{ - int state; - - if (!did_cursorhold - && has_cursorhold() - && reg_recording == 0 - && typebuf.tb_len == 0 -#ifdef FEAT_INS_EXPAND - && !ins_compl_active() -#endif - ) - { - state = get_real_state(); - if (state == NORMAL_BUSY || (state & INSERT) != 0) - return TRUE; - } - return FALSE; -} - -/* - * Return TRUE when there is a CursorMoved autocommand defined. - */ - int -has_cursormoved(void) -{ - return (first_autopat[(int)EVENT_CURSORMOVED] != NULL); -} - -#if defined(FEAT_CONCEAL) || defined(PROTO) -/* - * Return TRUE when there is a CursorMovedI autocommand defined. - */ - int -has_cursormovedI(void) -{ - return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL); -} -#endif - -/* - * Return TRUE when there is a TextChanged autocommand defined. - */ - int -has_textchanged(void) -{ - return (first_autopat[(int)EVENT_TEXTCHANGED] != NULL); -} - -/* - * Return TRUE when there is a TextChangedI autocommand defined. - */ - int -has_textchangedI(void) -{ - return (first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL); -} - -#if defined(FEAT_INS_EXPAND) || defined(PROTO) -/* - * Return TRUE when there is a TextChangedP autocommand defined. - */ - int -has_textchangedP(void) -{ - return (first_autopat[(int)EVENT_TEXTCHANGEDP] != NULL); -} -#endif - -/* - * Return TRUE when there is an InsertCharPre autocommand defined. - */ - int -has_insertcharpre(void) -{ - return (first_autopat[(int)EVENT_INSERTCHARPRE] != NULL); -} - -/* - * Return TRUE when there is an CmdUndefined autocommand defined. - */ - int -has_cmdundefined(void) -{ - return (first_autopat[(int)EVENT_CMDUNDEFINED] != NULL); -} - -/* - * Return TRUE when there is an FuncUndefined autocommand defined. - */ - int -has_funcundefined(void) -{ - return (first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL); -} - -#if defined(FEAT_EVAL) || defined(PROTO) -/* - * Return TRUE when there is a TextYankPost autocommand defined. - */ - int -has_textyankpost(void) -{ - return (first_autopat[(int)EVENT_TEXTYANKPOST] != NULL); -} -#endif - -/* - * Execute autocommands for "event" and file name "fname". - * Return TRUE if some commands were executed. - */ - static int -apply_autocmds_group( - event_T event, - char_u *fname, /* NULL or empty means use actual file name */ - char_u *fname_io, /* fname to use for on cmdline, NULL means - use fname */ - int force, /* when TRUE, ignore autocmd_busy */ - int group, /* group ID, or AUGROUP_ALL */ - buf_T *buf, /* buffer for */ - exarg_T *eap UNUSED) /* command arguments */ -{ - char_u *sfname = NULL; /* short file name */ - char_u *tail; - int save_changed; - buf_T *old_curbuf; - int retval = FALSE; - char_u *save_sourcing_name; - linenr_T save_sourcing_lnum; - char_u *save_autocmd_fname; - int save_autocmd_fname_full; - int save_autocmd_bufnr; - char_u *save_autocmd_match; - int save_autocmd_busy; - int save_autocmd_nested; - static int nesting = 0; - AutoPatCmd patcmd; - AutoPat *ap; -#ifdef FEAT_EVAL - sctx_T save_current_sctx; - funccal_entry_T funccal_entry; - char_u *save_cmdarg; - long save_cmdbang; -#endif - static int filechangeshell_busy = FALSE; -#ifdef FEAT_PROFILE - proftime_T wait_time; -#endif - int did_save_redobuff = FALSE; - save_redo_T save_redo; - int save_KeyTyped = KeyTyped; - - /* - * Quickly return if there are no autocommands for this event or - * autocommands are blocked. - */ - if (event == NUM_EVENTS || first_autopat[(int)event] == NULL - || autocmd_blocked > 0) - goto BYPASS_AU; - - /* - * When autocommands are busy, new autocommands are only executed when - * explicitly enabled with the "nested" flag. - */ - if (autocmd_busy && !(force || autocmd_nested)) - goto BYPASS_AU; - -#ifdef FEAT_EVAL - /* - * Quickly return when immediately aborting on error, or when an interrupt - * occurred or an exception was thrown but not caught. - */ - if (aborting()) - goto BYPASS_AU; -#endif - - /* - * FileChangedShell never nests, because it can create an endless loop. - */ - if (filechangeshell_busy && (event == EVENT_FILECHANGEDSHELL - || event == EVENT_FILECHANGEDSHELLPOST)) - goto BYPASS_AU; - - /* - * Ignore events in 'eventignore'. - */ - if (event_ignored(event)) - goto BYPASS_AU; - - /* - * Allow nesting of autocommands, but restrict the depth, because it's - * possible to create an endless loop. - */ - if (nesting == 10) - { - emsg(_("E218: autocommand nesting too deep")); - goto BYPASS_AU; - } - - /* - * Check if these autocommands are disabled. Used when doing ":all" or - * ":ball". - */ - if ( (autocmd_no_enter - && (event == EVENT_WINENTER || event == EVENT_BUFENTER)) - || (autocmd_no_leave - && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE))) - goto BYPASS_AU; - - /* - * Save the autocmd_* variables and info about the current buffer. - */ - save_autocmd_fname = autocmd_fname; - save_autocmd_fname_full = autocmd_fname_full; - save_autocmd_bufnr = autocmd_bufnr; - save_autocmd_match = autocmd_match; - save_autocmd_busy = autocmd_busy; - save_autocmd_nested = autocmd_nested; - save_changed = curbuf->b_changed; - old_curbuf = curbuf; - - /* - * Set the file name to be used for . - * Make a copy to avoid that changing a buffer name or directory makes it - * invalid. - */ - if (fname_io == NULL) - { - if (event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE - || event == EVENT_OPTIONSET) - autocmd_fname = NULL; - else if (fname != NULL && !ends_excmd(*fname)) - autocmd_fname = fname; - else if (buf != NULL) - autocmd_fname = buf->b_ffname; - else - autocmd_fname = NULL; - } - else - autocmd_fname = fname_io; - if (autocmd_fname != NULL) - autocmd_fname = vim_strsave(autocmd_fname); - autocmd_fname_full = FALSE; /* call FullName_save() later */ - - /* - * Set the buffer number to be used for . - */ - if (buf == NULL) - autocmd_bufnr = 0; - else - autocmd_bufnr = buf->b_fnum; - - /* - * When the file name is NULL or empty, use the file name of buffer "buf". - * Always use the full path of the file name to match with, in case - * "allow_dirs" is set. - */ - if (fname == NULL || *fname == NUL) - { - if (buf == NULL) - fname = NULL; - else - { -#ifdef FEAT_SYN_HL - if (event == EVENT_SYNTAX) - fname = buf->b_p_syn; - else -#endif - if (event == EVENT_FILETYPE) - fname = buf->b_p_ft; - else - { - if (buf->b_sfname != NULL) - sfname = vim_strsave(buf->b_sfname); - fname = buf->b_ffname; - } - } - if (fname == NULL) - fname = (char_u *)""; - fname = vim_strsave(fname); /* make a copy, so we can change it */ - } - else - { - sfname = vim_strsave(fname); - /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID, - * ColorScheme, QuickFixCmd* or DirChanged */ - if (event == EVENT_FILETYPE - || event == EVENT_SYNTAX - || event == EVENT_CMDLINECHANGED - || event == EVENT_CMDLINEENTER - || event == EVENT_CMDLINELEAVE - || event == EVENT_CMDWINENTER - || event == EVENT_CMDWINLEAVE - || event == EVENT_CMDUNDEFINED - || event == EVENT_FUNCUNDEFINED - || event == EVENT_REMOTEREPLY - || event == EVENT_SPELLFILEMISSING - || event == EVENT_QUICKFIXCMDPRE - || event == EVENT_COLORSCHEME - || event == EVENT_COLORSCHEMEPRE - || event == EVENT_OPTIONSET - || event == EVENT_QUICKFIXCMDPOST - || event == EVENT_DIRCHANGED) - { - fname = vim_strsave(fname); - autocmd_fname_full = TRUE; /* don't expand it later */ - } - else - fname = FullName_save(fname, FALSE); - } - if (fname == NULL) /* out of memory */ - { - vim_free(sfname); - retval = FALSE; - goto BYPASS_AU; - } - -#ifdef BACKSLASH_IN_FILENAME - /* - * Replace all backslashes with forward slashes. This makes the - * autocommand patterns portable between Unix and MS-DOS. - */ - if (sfname != NULL) - forward_slash(sfname); - forward_slash(fname); -#endif - -#ifdef VMS - /* remove version for correct match */ - if (sfname != NULL) - vms_remove_version(sfname); - vms_remove_version(fname); -#endif - - /* - * Set the name to be used for . - */ - autocmd_match = fname; - - - /* Don't redraw while doing autocommands. */ - ++RedrawingDisabled; - save_sourcing_name = sourcing_name; - sourcing_name = NULL; /* don't free this one */ - save_sourcing_lnum = sourcing_lnum; - sourcing_lnum = 0; /* no line number here */ - -#ifdef FEAT_EVAL - save_current_sctx = current_sctx; - -# ifdef FEAT_PROFILE - if (do_profiling == PROF_YES) - prof_child_enter(&wait_time); /* doesn't count for the caller itself */ -# endif - - // Don't use local function variables, if called from a function. - save_funccal(&funccal_entry); -#endif - - /* - * When starting to execute autocommands, save the search patterns. - */ - if (!autocmd_busy) - { - save_search_patterns(); -#ifdef FEAT_INS_EXPAND - if (!ins_compl_active()) -#endif - { - saveRedobuff(&save_redo); - did_save_redobuff = TRUE; - } - did_filetype = keep_filetype; - } - - /* - * Note that we are applying autocmds. Some commands need to know. - */ - autocmd_busy = TRUE; - filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL); - ++nesting; /* see matching decrement below */ - - /* Remember that FileType was triggered. Used for did_filetype(). */ - if (event == EVENT_FILETYPE) - did_filetype = TRUE; - - tail = gettail(fname); - - /* Find first autocommand that matches */ - patcmd.curpat = first_autopat[(int)event]; - patcmd.nextcmd = NULL; - patcmd.group = group; - patcmd.fname = fname; - patcmd.sfname = sfname; - patcmd.tail = tail; - patcmd.event = event; - patcmd.arg_bufnr = autocmd_bufnr; - patcmd.next = NULL; - auto_next_pat(&patcmd, FALSE); - - /* found one, start executing the autocommands */ - if (patcmd.curpat != NULL) - { - /* add to active_apc_list */ - patcmd.next = active_apc_list; - active_apc_list = &patcmd; - -#ifdef FEAT_EVAL - /* set v:cmdarg (only when there is a matching pattern) */ - save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG); - if (eap != NULL) - { - save_cmdarg = set_cmdarg(eap, NULL); - set_vim_var_nr(VV_CMDBANG, (long)eap->forceit); - } - else - save_cmdarg = NULL; /* avoid gcc warning */ -#endif - retval = TRUE; - /* mark the last pattern, to avoid an endless loop when more patterns - * are added when executing autocommands */ - for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next) - ap->last = FALSE; - ap->last = TRUE; - check_lnums(TRUE); /* make sure cursor and topline are valid */ - do_cmdline(NULL, getnextac, (void *)&patcmd, - DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); -#ifdef FEAT_EVAL - if (eap != NULL) - { - (void)set_cmdarg(NULL, save_cmdarg); - set_vim_var_nr(VV_CMDBANG, save_cmdbang); - } -#endif - /* delete from active_apc_list */ - if (active_apc_list == &patcmd) /* just in case */ - active_apc_list = patcmd.next; - } - - --RedrawingDisabled; - autocmd_busy = save_autocmd_busy; - filechangeshell_busy = FALSE; - autocmd_nested = save_autocmd_nested; - vim_free(sourcing_name); - sourcing_name = save_sourcing_name; - sourcing_lnum = save_sourcing_lnum; - vim_free(autocmd_fname); - autocmd_fname = save_autocmd_fname; - autocmd_fname_full = save_autocmd_fname_full; - autocmd_bufnr = save_autocmd_bufnr; - autocmd_match = save_autocmd_match; -#ifdef FEAT_EVAL - current_sctx = save_current_sctx; - restore_funccal(); -# ifdef FEAT_PROFILE - if (do_profiling == PROF_YES) - prof_child_exit(&wait_time); -# endif -#endif - KeyTyped = save_KeyTyped; - vim_free(fname); - vim_free(sfname); - --nesting; /* see matching increment above */ - - /* - * When stopping to execute autocommands, restore the search patterns and - * the redo buffer. Free any buffers in the au_pending_free_buf list and - * free any windows in the au_pending_free_win list. - */ - if (!autocmd_busy) - { - restore_search_patterns(); - if (did_save_redobuff) - restoreRedobuff(&save_redo); - did_filetype = FALSE; - while (au_pending_free_buf != NULL) - { - buf_T *b = au_pending_free_buf->b_next; - vim_free(au_pending_free_buf); - au_pending_free_buf = b; - } - while (au_pending_free_win != NULL) - { - win_T *w = au_pending_free_win->w_next; - vim_free(au_pending_free_win); - au_pending_free_win = w; - } - } - - /* - * Some events don't set or reset the Changed flag. - * Check if still in the same buffer! - */ - if (curbuf == old_curbuf - && (event == EVENT_BUFREADPOST - || event == EVENT_BUFWRITEPOST - || event == EVENT_FILEAPPENDPOST - || event == EVENT_VIMLEAVE - || event == EVENT_VIMLEAVEPRE)) - { -#ifdef FEAT_TITLE - if (curbuf->b_changed != save_changed) - need_maketitle = TRUE; -#endif - curbuf->b_changed = save_changed; - } - - au_cleanup(); /* may really delete removed patterns/commands now */ - -BYPASS_AU: - /* When wiping out a buffer make sure all its buffer-local autocommands - * are deleted. */ - if (event == EVENT_BUFWIPEOUT && buf != NULL) - aubuflocal_remove(buf); - - if (retval == OK && event == EVENT_FILETYPE) - au_did_filetype = TRUE; - - return retval; -} - -# ifdef FEAT_EVAL -static char_u *old_termresponse = NULL; -# endif - -/* - * Block triggering autocommands until unblock_autocmd() is called. - * Can be used recursively, so long as it's symmetric. - */ - void -block_autocmds(void) -{ -# ifdef FEAT_EVAL - /* Remember the value of v:termresponse. */ - if (autocmd_blocked == 0) - old_termresponse = get_vim_var_str(VV_TERMRESPONSE); -# endif - ++autocmd_blocked; -} - - void -unblock_autocmds(void) -{ - --autocmd_blocked; - -# ifdef FEAT_EVAL - /* When v:termresponse was set while autocommands were blocked, trigger - * the autocommands now. Esp. useful when executing a shell command - * during startup (vimdiff). */ - if (autocmd_blocked == 0 - && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse) - apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf); -# endif -} - -#if defined(FEAT_EVAL) && (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM)) \ - || defined(PROTO) - int -is_autocmd_blocked(void) -{ - return autocmd_blocked != 0; -} -#endif - -/* - * Find next autocommand pattern that matches. - */ - static void -auto_next_pat( - AutoPatCmd *apc, - int stop_at_last) /* stop when 'last' flag is set */ -{ - AutoPat *ap; - AutoCmd *cp; - char_u *name; - char *s; - - VIM_CLEAR(sourcing_name); - - for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next) - { - apc->curpat = NULL; - - /* Only use a pattern when it has not been removed, has commands and - * the group matches. For buffer-local autocommands only check the - * buffer number. */ - if (ap->pat != NULL && ap->cmds != NULL - && (apc->group == AUGROUP_ALL || apc->group == ap->group)) - { - /* execution-condition */ - if (ap->buflocal_nr == 0 - ? (match_file_pat(NULL, &ap->reg_prog, apc->fname, - apc->sfname, apc->tail, ap->allow_dirs)) - : ap->buflocal_nr == apc->arg_bufnr) - { - name = event_nr2name(apc->event); - s = _("%s Autocommands for \"%s\""); - sourcing_name = alloc((unsigned)(STRLEN(s) - + STRLEN(name) + ap->patlen + 1)); - if (sourcing_name != NULL) - { - sprintf((char *)sourcing_name, s, - (char *)name, (char *)ap->pat); - if (p_verbose >= 8) - { - verbose_enter(); - smsg(_("Executing %s"), sourcing_name); - verbose_leave(); - } - } - - apc->curpat = ap; - apc->nextcmd = ap->cmds; - /* mark last command */ - for (cp = ap->cmds; cp->next != NULL; cp = cp->next) - cp->last = FALSE; - cp->last = TRUE; - } - line_breakcheck(); - if (apc->curpat != NULL) /* found a match */ - break; - } - if (stop_at_last && ap->last) - break; - } -} - -/* - * Get next autocommand command. - * Called by do_cmdline() to get the next line for ":if". - * Returns allocated string, or NULL for end of autocommands. - */ - char_u * -getnextac(int c UNUSED, void *cookie, int indent UNUSED) -{ - AutoPatCmd *acp = (AutoPatCmd *)cookie; - char_u *retval; - AutoCmd *ac; - - /* Can be called again after returning the last line. */ - if (acp->curpat == NULL) - return NULL; - - /* repeat until we find an autocommand to execute */ - for (;;) - { - /* skip removed commands */ - while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL) - if (acp->nextcmd->last) - acp->nextcmd = NULL; - else - acp->nextcmd = acp->nextcmd->next; - - if (acp->nextcmd != NULL) - break; - - /* at end of commands, find next pattern that matches */ - if (acp->curpat->last) - acp->curpat = NULL; - else - acp->curpat = acp->curpat->next; - if (acp->curpat != NULL) - auto_next_pat(acp, TRUE); - if (acp->curpat == NULL) - return NULL; - } - - ac = acp->nextcmd; - - if (p_verbose >= 9) - { - verbose_enter_scroll(); - smsg(_("autocommand %s"), ac->cmd); - msg_puts("\n"); /* don't overwrite this either */ - verbose_leave_scroll(); - } - retval = vim_strsave(ac->cmd); - autocmd_nested = ac->nested; -#ifdef FEAT_EVAL - current_sctx = ac->script_ctx; -#endif - if (ac->last) - acp->nextcmd = NULL; - else - acp->nextcmd = ac->next; - return retval; -} - -/* - * Return TRUE if there is a matching autocommand for "fname". - * To account for buffer-local autocommands, function needs to know - * in which buffer the file will be opened. - */ - int -has_autocmd(event_T event, char_u *sfname, buf_T *buf) -{ - AutoPat *ap; - char_u *fname; - char_u *tail = gettail(sfname); - int retval = FALSE; - - fname = FullName_save(sfname, FALSE); - if (fname == NULL) - return FALSE; - -#ifdef BACKSLASH_IN_FILENAME - /* - * Replace all backslashes with forward slashes. This makes the - * autocommand patterns portable between Unix and MS-DOS. - */ - sfname = vim_strsave(sfname); - if (sfname != NULL) - forward_slash(sfname); - forward_slash(fname); -#endif - - for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) - if (ap->pat != NULL && ap->cmds != NULL - && (ap->buflocal_nr == 0 - ? match_file_pat(NULL, &ap->reg_prog, - fname, sfname, tail, ap->allow_dirs) - : buf != NULL && ap->buflocal_nr == buf->b_fnum - )) - { - retval = TRUE; - break; - } - - vim_free(fname); -#ifdef BACKSLASH_IN_FILENAME - vim_free(sfname); -#endif - - return retval; -} - -#if defined(FEAT_CMDL_COMPL) || defined(PROTO) -/* - * Function given to ExpandGeneric() to obtain the list of autocommand group - * names. - */ - char_u * -get_augroup_name(expand_T *xp UNUSED, int idx) -{ - if (idx == augroups.ga_len) /* add "END" add the end */ - return (char_u *)"END"; - if (idx >= augroups.ga_len) /* end of list */ - return NULL; - if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup()) - /* skip deleted entries */ - return (char_u *)""; - return AUGROUP_NAME(idx); /* return a name */ -} - -static int include_groups = FALSE; - - char_u * -set_context_in_autocmd( - expand_T *xp, - char_u *arg, - int doautocmd) /* TRUE for :doauto*, FALSE for :autocmd */ -{ - char_u *p; - int group; - - /* check for a group name, skip it if present */ - include_groups = FALSE; - p = arg; - group = au_get_grouparg(&arg); - if (group == AUGROUP_ERROR) - return NULL; - /* If there only is a group name that's what we expand. */ - if (*arg == NUL && group != AUGROUP_ALL && !VIM_ISWHITE(arg[-1])) - { - arg = p; - group = AUGROUP_ALL; - } - - /* skip over event name */ - for (p = arg; *p != NUL && !VIM_ISWHITE(*p); ++p) - if (*p == ',') - arg = p + 1; - if (*p == NUL) - { - if (group == AUGROUP_ALL) - include_groups = TRUE; - xp->xp_context = EXPAND_EVENTS; /* expand event name */ - xp->xp_pattern = arg; - return NULL; - } - - /* skip over pattern */ - arg = skipwhite(p); - while (*arg && (!VIM_ISWHITE(*arg) || arg[-1] == '\\')) - arg++; - if (*arg) - return arg; /* expand (next) command */ - - if (doautocmd) - xp->xp_context = EXPAND_FILES; /* expand file names */ - else - xp->xp_context = EXPAND_NOTHING; /* pattern is not expanded */ - return NULL; -} - -/* - * Function given to ExpandGeneric() to obtain the list of event names. - */ - char_u * -get_event_name(expand_T *xp UNUSED, int idx) -{ - if (idx < augroups.ga_len) /* First list group names, if wanted */ - { - if (!include_groups || AUGROUP_NAME(idx) == NULL - || AUGROUP_NAME(idx) == get_deleted_augroup()) - return (char_u *)""; /* skip deleted entries */ - return AUGROUP_NAME(idx); /* return a name */ - } - return (char_u *)event_names[idx - augroups.ga_len].name; -} - -#endif /* FEAT_CMDL_COMPL */ - -#if defined(FEAT_EVAL) || defined(PROTO) -/* - * Return TRUE if autocmd is supported. - */ - int -autocmd_supported(char_u *name) -{ - char_u *p; - - return (event_name2nr(name, &p) != NUM_EVENTS); -} - -/* - * Return TRUE if an autocommand is defined for a group, event and - * pattern: The group can be omitted to accept any group. "event" and "pattern" - * can be NULL to accept any event and pattern. "pattern" can be NULL to accept - * any pattern. Buffer-local patterns or are accepted. - * Used for: - * exists("#Group") or - * exists("#Group#Event") or - * exists("#Group#Event#pat") or - * exists("#Event") or - * exists("#Event#pat") - */ - int -au_exists(char_u *arg) -{ - char_u *arg_save; - char_u *pattern = NULL; - char_u *event_name; - char_u *p; - event_T event; - AutoPat *ap; - buf_T *buflocal_buf = NULL; - int group; - int retval = FALSE; - - /* Make a copy so that we can change the '#' chars to a NUL. */ - arg_save = vim_strsave(arg); - if (arg_save == NULL) - return FALSE; - p = vim_strchr(arg_save, '#'); - if (p != NULL) - *p++ = NUL; - - /* First, look for an autocmd group name */ - group = au_find_group(arg_save); - if (group == AUGROUP_ERROR) - { - /* Didn't match a group name, assume the first argument is an event. */ - group = AUGROUP_ALL; - event_name = arg_save; - } - else - { - if (p == NULL) - { - /* "Group": group name is present and it's recognized */ - retval = TRUE; - goto theend; - } - - /* Must be "Group#Event" or "Group#Event#pat". */ - event_name = p; - p = vim_strchr(event_name, '#'); - if (p != NULL) - *p++ = NUL; /* "Group#Event#pat" */ - } - - pattern = p; /* "pattern" is NULL when there is no pattern */ - - /* find the index (enum) for the event name */ - event = event_name2nr(event_name, &p); - - /* return FALSE if the event name is not recognized */ - if (event == NUM_EVENTS) - goto theend; - - /* Find the first autocommand for this event. - * If there isn't any, return FALSE; - * If there is one and no pattern given, return TRUE; */ - ap = first_autopat[(int)event]; - if (ap == NULL) - goto theend; - - /* if pattern is "", special handling is needed which uses curbuf */ - /* for pattern ", fnamecmp() will work fine */ - if (pattern != NULL && STRICMP(pattern, "") == 0) - buflocal_buf = curbuf; - - /* Check if there is an autocommand with the given pattern. */ - for ( ; ap != NULL; ap = ap->next) - /* only use a pattern when it has not been removed and has commands. */ - /* For buffer-local autocommands, fnamecmp() works fine. */ - if (ap->pat != NULL && ap->cmds != NULL - && (group == AUGROUP_ALL || ap->group == group) - && (pattern == NULL - || (buflocal_buf == NULL - ? fnamecmp(ap->pat, pattern) == 0 - : ap->buflocal_nr == buflocal_buf->b_fnum))) - { - retval = TRUE; - break; - } - -theend: - vim_free(arg_save); - return retval; -} -#endif - - /* * Try matching a filename with a "pattern" ("prog" is NULL), or use the * precompiled regprog "prog" ("pattern" is NULL). That avoids calling @@ -10118,7 +7542,7 @@ theend: * Used for autocommands and 'wildignore'. * Returns TRUE if there is a match, FALSE otherwise. */ - static int + int match_file_pat( char_u *pattern, /* pattern to match with */ regprog_T **prog, /* pre-compiled regprog or NULL */ diff --git a/src/globals.h b/src/globals.h index 355b4bb349..c6fd710f17 100644 --- a/src/globals.h +++ b/src/globals.h @@ -397,6 +397,7 @@ EXTERN int autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */ EXTERN int autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */ EXTERN int modified_was_set; /* did ":set modified" */ EXTERN int did_filetype INIT(= FALSE); /* FileType event found */ +EXTERN int au_did_filetype INIT(= FALSE); EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when starting to execute autocommands */ diff --git a/src/proto.h b/src/proto.h index cb4add0029..e4153ebef2 100644 --- a/src/proto.h +++ b/src/proto.h @@ -62,6 +62,7 @@ extern int _stricoll(char *a, char *b); # include "crypt.pro" # include "crypt_zip.pro" # endif +# include "autocmd.pro" # include "buffer.pro" # include "charset.pro" # ifdef FEAT_CSCOPE diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro new file mode 100644 index 0000000000..8c6d18f754 --- /dev/null +++ b/src/proto/autocmd.pro @@ -0,0 +1,39 @@ +/* autocmd.c */ +void aubuflocal_remove(buf_T *buf); +int au_has_group(char_u *name); +void do_augroup(char_u *arg, int del_group); +void free_all_autocmds(void); +int check_ei(void); +char_u *au_event_disable(char *what); +void au_event_restore(char_u *old_ei); +void do_autocmd(char_u *arg_in, int forceit); +int do_doautocmd(char_u *arg, int do_msg, int *did_something); +void ex_doautoall(exarg_T *eap); +int check_nomodeline(char_u **argp); +void aucmd_prepbuf(aco_save_T *aco, buf_T *buf); +void aucmd_restbuf(aco_save_T *aco); +int apply_autocmds(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf); +int apply_autocmds_exarg(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, exarg_T *eap); +int apply_autocmds_retval(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, int *retval); +int has_cursorhold(void); +int trigger_cursorhold(void); +int has_cursormoved(void); +int has_cursormovedI(void); +int has_textchanged(void); +int has_textchangedI(void); +int has_textchangedP(void); +int has_insertcharpre(void); +int has_cmdundefined(void); +int has_funcundefined(void); +int has_textyankpost(void); +void block_autocmds(void); +void unblock_autocmds(void); +int is_autocmd_blocked(void); +char_u *getnextac(int c, void *cookie, int indent); +int has_autocmd(event_T event, char_u *sfname, buf_T *buf); +char_u *get_augroup_name(expand_T *xp, int idx); +char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd); +char_u *get_event_name(expand_T *xp, int idx); +int autocmd_supported(char_u *name); +int au_exists(char_u *arg); +/* vim: set ft=c : */ diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro index 990348143b..21ac55c9d1 100644 --- a/src/proto/fileio.pro +++ b/src/proto/fileio.pro @@ -28,42 +28,7 @@ int delete_recursive(char_u *name); void vim_deltempdir(void); char_u *vim_tempname(int extra_char, int keep); void forward_slash(char_u *fname); -void aubuflocal_remove(buf_T *buf); -int au_has_group(char_u *name); -void do_augroup(char_u *arg, int del_group); -void free_all_autocmds(void); -int check_ei(void); -char_u *au_event_disable(char *what); -void au_event_restore(char_u *old_ei); -void do_autocmd(char_u *arg_in, int forceit); -int do_doautocmd(char_u *arg, int do_msg, int *did_something); -void ex_doautoall(exarg_T *eap); -int check_nomodeline(char_u **argp); -void aucmd_prepbuf(aco_save_T *aco, buf_T *buf); -void aucmd_restbuf(aco_save_T *aco); -int apply_autocmds(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf); -int apply_autocmds_retval(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, int *retval); -int has_cursorhold(void); -int trigger_cursorhold(void); -int has_cursormoved(void); -int has_cursormovedI(void); -int has_textchanged(void); -int has_textchangedI(void); -int has_textchangedP(void); -int has_insertcharpre(void); -int has_cmdundefined(void); -int has_funcundefined(void); -int has_textyankpost(void); -void block_autocmds(void); -void unblock_autocmds(void); -int is_autocmd_blocked(void); -char_u *getnextac(int c, void *cookie, int indent); -int has_autocmd(event_T event, char_u *sfname, buf_T *buf); -char_u *get_augroup_name(expand_T *xp, int idx); -char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd); -char_u *get_event_name(expand_T *xp, int idx); -int autocmd_supported(char_u *name); -int au_exists(char_u *arg); +int match_file_pat(char_u *pattern, regprog_T **prog, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs); int match_file_list(char_u *list, char_u *sfname, char_u *ffname); char_u *file_pat_to_reg_pat(char_u *pat, char_u *pat_end, char *allow_dirs, int no_bslash); long read_eintr(int fd, void *buf, size_t bufsize); diff --git a/src/version.c b/src/version.c index ddf9b1496c..af0adc2760 100644 --- a/src/version.c +++ b/src/version.c @@ -787,6 +787,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 825, /**/ 824, /**/ From 29ddebef4038d2d2b3bc9d8d3b0109f4046d6fbf Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 17:28:26 +0100 Subject: [PATCH 04/26] patch 8.1.0826: too many #ifdefs Problem: Too many #ifdefs. Solution: Graduate FEAT_VIRTUALEDIT. Adds about 10Kbyte to the code. --- src/buffer.c | 10 +---- src/charset.c | 4 -- src/edit.c | 55 +++++-------------------- src/eval.c | 6 --- src/evalfunc.c | 31 +------------- src/ex_cmds.c | 2 - src/ex_docmd.c | 6 --- src/feature.h | 4 +- src/globals.h | 6 +-- src/gui.c | 2 - src/if_py_both.h | 2 - src/macros.h | 17 ++------ src/mark.c | 12 +----- src/mbyte.c | 10 +---- src/memline.c | 2 - src/menu.c | 2 - src/misc1.c | 17 +------- src/misc2.c | 33 +-------------- src/move.c | 11 +---- src/netbeans.c | 4 -- src/normal.c | 96 +++++-------------------------------------- src/ops.c | 104 +++++------------------------------------------ src/option.c | 9 ---- src/option.h | 12 +++--- src/screen.c | 22 +++------- src/search.c | 12 ------ src/spell.c | 2 - src/structs.h | 21 +++------- src/tag.c | 2 +- src/ui.c | 2 - src/undo.c | 22 ---------- src/userfunc.c | 2 - src/version.c | 6 +-- src/vim.h | 6 --- src/window.c | 4 -- 35 files changed, 65 insertions(+), 493 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 14152b7737..98d505f18e 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1729,9 +1729,7 @@ enter_buffer(buf_T *buf) /* Cursor on first line by default. */ curwin->w_cursor.lnum = 1; curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_set_curswant = TRUE; curwin->w_topline_was_set = FALSE; @@ -2333,9 +2331,7 @@ buflist_getfile( { curwin->w_cursor.col = col; check_cursor_col(); -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_set_curswant = TRUE; } return OK; @@ -2363,9 +2359,7 @@ buflist_getfpos(void) { curwin->w_cursor.col = fpos->col; check_cursor_col(); -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_set_curswant = TRUE; } } @@ -2958,7 +2952,7 @@ get_winopts(buf_T *buf) buflist_findfpos(buf_T *buf) { wininfo_T *wip; - static pos_T no_position = INIT_POS_T(1, 0, 0); + static pos_T no_position = {1, 0, 0}; wip = find_wininfo(buf, FALSE); if (wip != NULL) @@ -3955,9 +3949,7 @@ build_stl_str_hl( // Line may have changed since checking the cursor column, or the lnum // was adjusted above. wp->w_cursor.col = (colnr_T)len; -#ifdef FEAT_VIRTUALEDIT wp->w_cursor.coladd = 0; -#endif byteval = 0; } else diff --git a/src/charset.c b/src/charset.c index c1ca3f97c7..5b091ec4d1 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1365,17 +1365,14 @@ getvcol_nolist(pos_T *posp) colnr_T vcol; curwin->w_p_list = FALSE; -#ifdef FEAT_VIRTUALEDIT if (posp->coladd) getvvcol(curwin, posp, NULL, &vcol, NULL); else -#endif getvcol(curwin, posp, NULL, &vcol, NULL); curwin->w_p_list = list_save; return vcol; } -#if defined(FEAT_VIRTUALEDIT) || defined(PROTO) /* * Get virtual column in virtual mode. */ @@ -1425,7 +1422,6 @@ getvvcol( else getvcol(wp, pos, start, cursor, end); } -#endif /* * Get the leftmost and rightmost virtual column of pos1 and pos2. diff --git a/src/edit.c b/src/edit.c index f797d7f04e..de5adcb197 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1072,14 +1072,12 @@ doESCkey: break; ins_ctrl_o(); -#ifdef FEAT_VIRTUALEDIT /* don't move the cursor left when 'virtualedit' has "onemore". */ if (ve_flags & VE_ONEMORE) { ins_at_eol = FALSE; nomove = TRUE; } -#endif count = 0; goto doESCkey; @@ -7125,14 +7123,12 @@ stop_insert( { if (gchar_cursor() != NUL) inc_cursor(); -#ifdef FEAT_VIRTUALEDIT - /* If the cursor is still at the same character, also keep - * the "coladd". */ + // If the cursor is still at the same character, also keep + // the "coladd". if (gchar_cursor() == NUL && curwin->w_cursor.lnum == tpos.lnum && curwin->w_cursor.col == tpos.col) curwin->w_cursor.coladd = tpos.coladd; -#endif } } @@ -7182,9 +7178,7 @@ stop_insert( if (VIsual.col > len) { VIsual.col = len; -#ifdef FEAT_VIRTUALEDIT VIsual.coladd = 0; -#endif } } } @@ -7293,9 +7287,7 @@ beginline(int flags) else { curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif if (flags & (BL_WHITE | BL_SOL)) { @@ -7323,7 +7315,6 @@ oneright(void) char_u *ptr; int l; -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) { pos_T prevpos = curwin->w_cursor; @@ -7338,7 +7329,6 @@ oneright(void) return (prevpos.col != curwin->w_cursor.col || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL; } -#endif ptr = ml_get_cursor(); if (*ptr == NUL) @@ -7351,11 +7341,7 @@ oneright(void) /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit' * contains "onemore". */ - if (ptr[l] == NUL -#ifdef FEAT_VIRTUALEDIT - && (ve_flags & VE_ONEMORE) == 0 -#endif - ) + if (ptr[l] == NUL && (ve_flags & VE_ONEMORE) == 0) return FAIL; curwin->w_cursor.col += l; @@ -7366,18 +7352,17 @@ oneright(void) int oneleft(void) { -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) { -# ifdef FEAT_LINEBREAK +#ifdef FEAT_LINEBREAK int width; -# endif +#endif int v = getviscol(); if (v == 0) return FAIL; -# ifdef FEAT_LINEBREAK +#ifdef FEAT_LINEBREAK /* We might get stuck on 'showbreak', skip over it. */ width = 1; for (;;) @@ -7391,9 +7376,9 @@ oneleft(void) break; ++width; } -# else +#else coladvance(v - 1); -# endif +#endif if (curwin->w_cursor.coladd == 1) { @@ -7409,7 +7394,6 @@ oneleft(void) curwin->w_set_curswant = TRUE; return OK; } -#endif if (curwin->w_cursor.col == 0) return FAIL; @@ -8665,10 +8649,7 @@ ins_esc( */ if (!nomove && (curwin->w_cursor.col != 0 -#ifdef FEAT_VIRTUALEDIT - || curwin->w_cursor.coladd > 0 -#endif - ) + || curwin->w_cursor.coladd > 0) && (restart_edit == NUL || (gchar_cursor() == NUL && !VIsual_active)) #ifdef FEAT_RIGHTLEFT @@ -8676,7 +8657,6 @@ ins_esc( #endif ) { -#ifdef FEAT_VIRTUALEDIT if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) { oneleft(); @@ -8684,7 +8664,6 @@ ins_esc( ++curwin->w_cursor.coladd; } else -#endif { --curwin->w_cursor.col; /* Correct cursor for multi-byte character. */ @@ -8874,11 +8853,9 @@ ins_ctrl_o(void) restart_edit = 'R'; else restart_edit = 'I'; -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) ins_at_eol = FALSE; /* cursor always keeps its column */ else -#endif ins_at_eol = (gchar_cursor() == NUL); } @@ -9040,7 +9017,6 @@ ins_bs( inc_cursor(); #endif -#ifdef FEAT_VIRTUALEDIT /* Virtualedit: * BACKSPACE_CHAR eats a virtual space * BACKSPACE_WORD eats all coladd @@ -9060,7 +9036,6 @@ ins_bs( } curwin->w_cursor.coladd = 0; } -#endif /* * Delete newline! @@ -9744,9 +9719,7 @@ ins_home(int c) if (c == K_C_HOME) curwin->w_cursor.lnum = 1; curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_curswant = 0; start_arrow(&tpos); } @@ -9797,21 +9770,15 @@ ins_right( foldOpenCursor(); #endif undisplay_dollar(); - if (gchar_cursor() != NUL -#ifdef FEAT_VIRTUALEDIT - || virtual_active() -#endif - ) + if (gchar_cursor() != NUL || virtual_active()) { start_arrow_with_change(&curwin->w_cursor, end_change); if (!end_change) AppendCharToRedobuff(K_RIGHT); curwin->w_set_curswant = TRUE; -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) oneright(); else -#endif { if (has_mbyte) curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor()); @@ -10268,12 +10235,10 @@ ins_eol(int c) * in open_line(). */ -#ifdef FEAT_VIRTUALEDIT /* Put cursor on NUL if on the last char and coladd is 1 (happens after * CTRL-O). */ if (virtual_active() && curwin->w_cursor.coladd > 0) coladvance(getviscol()); -#endif #ifdef FEAT_RIGHTLEFT # ifdef FEAT_FKMAP diff --git a/src/eval.c b/src/eval.c index 82de63e1f8..3f9db7d16f 100644 --- a/src/eval.c +++ b/src/eval.c @@ -6207,12 +6207,10 @@ var2fpos( return NULL; /* invalid column number */ --pos.col; -#ifdef FEAT_VIRTUALEDIT /* Get the virtual offset. Defaults to zero. */ pos.coladd = list_find_nr(l, 2L, &error); if (error) pos.coladd = 0; -#endif return &pos; } @@ -6236,9 +6234,7 @@ var2fpos( return pp; } -#ifdef FEAT_VIRTUALEDIT pos.coladd = 0; -#endif if (name[0] == 'w' && dollar_lnum) { @@ -6323,13 +6319,11 @@ list2fpos( return FAIL; posp->col = n; -#ifdef FEAT_VIRTUALEDIT n = list_find_nr(l, i, NULL); /* off */ if (n < 0) posp->coladd = 0; else posp->coladd = n; -#endif if (curswantp != NULL) *curswantp = list_find_nr(l, i + 1, NULL); /* curswant */ diff --git a/src/evalfunc.c b/src/evalfunc.c index 269423f929..874e3a66da 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2517,7 +2517,6 @@ f_col(typval_T *argvars, typval_T *rettv) else { col = fp->col + 1; -#ifdef FEAT_VIRTUALEDIT /* col(".") when the cursor is on the NUL at the end of the line * because of "coladd" can be seen as an extra column. */ if (virtual_active() && fp == &curwin->w_cursor) @@ -2533,7 +2532,6 @@ f_col(typval_T *argvars, typval_T *rettv) col += l; } } -#endif } } rettv->vval.v_number = col; @@ -2838,9 +2836,7 @@ f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED) f_cursor(typval_T *argvars, typval_T *rettv) { long line, col; -#ifdef FEAT_VIRTUALEDIT long coladd = 0; -#endif int set_curswant = TRUE; rettv->vval.v_number = -1; @@ -2856,9 +2852,7 @@ f_cursor(typval_T *argvars, typval_T *rettv) } line = pos.lnum; col = pos.col; -#ifdef FEAT_VIRTUALEDIT coladd = pos.coladd; -#endif if (curswant >= 0) { curwin->w_curswant = curswant - 1; @@ -2869,24 +2863,16 @@ f_cursor(typval_T *argvars, typval_T *rettv) { line = tv_get_lnum(argvars); col = (long)tv_get_number_chk(&argvars[1], NULL); -#ifdef FEAT_VIRTUALEDIT if (argvars[2].v_type != VAR_UNKNOWN) coladd = (long)tv_get_number_chk(&argvars[2], NULL); -#endif } - if (line < 0 || col < 0 -#ifdef FEAT_VIRTUALEDIT - || coladd < 0 -#endif - ) + if (line < 0 || col < 0 || coladd < 0) return; /* type error; errmsg already given */ if (line > 0) curwin->w_cursor.lnum = line; if (col > 0) curwin->w_cursor.col = col - 1; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = coladd; -#endif /* Make sure the cursor is in a valid position. */ check_cursor(); @@ -4810,9 +4796,7 @@ f_getchangelist(typval_T *argvars, typval_T *rettv) return; dict_add_number(d, "lnum", (long)buf->b_changelist[i].lnum); dict_add_number(d, "col", (long)buf->b_changelist[i].col); -# ifdef FEAT_VIRTUALEDIT dict_add_number(d, "coladd", (long)buf->b_changelist[i].coladd); -# endif } #endif } @@ -5304,9 +5288,7 @@ f_getjumplist(typval_T *argvars, typval_T *rettv) return; dict_add_number(d, "lnum", (long)wp->w_jumplist[i].fmark.mark.lnum); dict_add_number(d, "col", (long)wp->w_jumplist[i].fmark.mark.col); -# ifdef FEAT_VIRTUALEDIT dict_add_number(d, "coladd", (long)wp->w_jumplist[i].fmark.mark.coladd); -# endif dict_add_number(d, "bufnr", (long)wp->w_jumplist[i].fmark.fnum); if (wp->w_jumplist[i].fname != NULL) dict_add_string(d, "filename", wp->w_jumplist[i].fname); @@ -5483,10 +5465,7 @@ getpos_both( list_append_number(l, (fp != NULL) ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) : (varnumber_T)0); - list_append_number(l, -#ifdef FEAT_VIRTUALEDIT - (fp != NULL) ? (varnumber_T)fp->coladd : -#endif + list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0); if (getcurpos) { @@ -6574,9 +6553,7 @@ f_has(typval_T *argvars, typval_T *rettv) "viminfo", #endif "vertsplit", -#ifdef FEAT_VIRTUALEDIT "virtualedit", -#endif "visual", "visualextra", "vreplace", @@ -14611,10 +14588,8 @@ f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, (char_u *)"lnum"); if (dict_find(dict, (char_u *)"col", -1) != NULL) curwin->w_cursor.col = (colnr_T)dict_get_number(dict, (char_u *)"col"); -#ifdef FEAT_VIRTUALEDIT if (dict_find(dict, (char_u *)"coladd", -1) != NULL) curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, (char_u *)"coladd"); -#endif if (dict_find(dict, (char_u *)"curswant", -1) != NULL) { curwin->w_curswant = (colnr_T)dict_get_number(dict, (char_u *)"curswant"); @@ -14661,9 +14636,7 @@ f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv) dict_add_number(dict, "lnum", (long)curwin->w_cursor.lnum); dict_add_number(dict, "col", (long)curwin->w_cursor.col); -#ifdef FEAT_VIRTUALEDIT dict_add_number(dict, "coladd", (long)curwin->w_cursor.coladd); -#endif update_curswant(); dict_add_number(dict, "curswant", (long)curwin->w_curswant); diff --git a/src/ex_cmds.c b/src/ex_cmds.c index a4e7cfb2a3..6d03d88ca7 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -4332,9 +4332,7 @@ do_ecmd( /* 'sol' is off: Use last known column. */ curwin->w_cursor.col = solcol; check_cursor_col(); -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_set_curswant = TRUE; } else diff --git a/src/ex_docmd.c b/src/ex_docmd.c index fc86f9eab7..93fa697317 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -4650,9 +4650,7 @@ get_address( pos.col = MAXCOL; else pos.col = 0; -#ifdef FEAT_VIRTUALEDIT pos.coladd = 0; -#endif if (searchit(curwin, curbuf, &pos, NULL, *cmd == '?' ? BACKWARD : FORWARD, (char_u *)"", 1L, SEARCH_MSG, @@ -9421,9 +9419,7 @@ ex_operators(exarg_T *eap) oa.end.lnum = eap->line2; oa.line_count = eap->line2 - eap->line1 + 1; oa.motion_type = MLINE; -#ifdef FEAT_VIRTUALEDIT virtual_op = FALSE; -#endif if (eap->cmdidx != CMD_yank) /* position cursor for undo */ { setpcmark(); @@ -9460,9 +9456,7 @@ ex_operators(exarg_T *eap) op_shift(&oa, FALSE, eap->amount); break; } -#ifdef FEAT_VIRTUALEDIT virtual_op = MAYBE; -#endif ex_may_print(eap); } diff --git a/src/feature.h b/src/feature.h index e2f9e2a004..a41e79f6f2 100644 --- a/src/feature.h +++ b/src/feature.h @@ -199,10 +199,8 @@ /* * +virtualedit 'virtualedit' option and its implementation + * Now always included. */ -#ifdef FEAT_NORMAL -# define FEAT_VIRTUALEDIT -#endif /* * +cmdline_info 'showcmd' and 'ruler' options. diff --git a/src/globals.h b/src/globals.h index c6fd710f17..0562610fd0 100644 --- a/src/globals.h +++ b/src/globals.h @@ -771,7 +771,7 @@ EXTERN int can_si_back INIT(= FALSE); EXTERN pos_T saved_cursor /* w_cursor before formatting text. */ #ifdef DO_INIT - = INIT_POS_T(0, 0, 0) + = {0, 0, 0} #endif ; @@ -1066,7 +1066,7 @@ EXTERN char_u *autocmd_match INIT(= NULL); /* name for on cmdline */ EXTERN int did_cursorhold INIT(= FALSE); /* set when CursorHold t'gerd */ EXTERN pos_T last_cursormoved /* for CursorMoved event */ # ifdef DO_INIT - = INIT_POS_T(0, 0, 0) + = {0, 0, 0} # endif ; @@ -1335,11 +1335,9 @@ EXTERN char psepcN INIT(= '/'); /* abnormal path separator character */ EXTERN char pseps[2] INIT(= {'\\' COMMA 0}); #endif -#ifdef FEAT_VIRTUALEDIT /* Set to TRUE when an operator is being executed with virtual editing, MAYBE * when no operator is being executed, FALSE otherwise. */ EXTERN int virtual_op INIT(= MAYBE); -#endif #ifdef FEAT_SYN_HL /* Display tick, incremented for each call to update_screen() */ diff --git a/src/gui.c b/src/gui.c index cbbe2af5cb..c22f47716b 100644 --- a/src/gui.c +++ b/src/gui.c @@ -4599,14 +4599,12 @@ gui_update_horiz_scrollbar(int force) longest_lnum = gui_find_longest_lnum(); max = scroll_line_len(longest_lnum); -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) { /* May move the cursor even further to the right. */ if (curwin->w_virtcol >= (colnr_T)max) max = curwin->w_virtcol; } -#endif #ifndef SCROLL_PAST_END max += curwin->w_width - 1; diff --git a/src/if_py_both.h b/src/if_py_both.h index f15bdc366e..a0c1663784 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -4033,9 +4033,7 @@ WindowSetattr(WindowObject *self, char *name, PyObject *valObject) self->win->w_cursor.lnum = lnum; self->win->w_cursor.col = col; self->win->w_set_curswant = TRUE; -#ifdef FEAT_VIRTUALEDIT self->win->w_cursor.coladd = 0; -#endif /* When column is out of range silently correct it. */ check_cursor_col_win(self->win); diff --git a/src/macros.h b/src/macros.h index ad243ccec2..29607db179 100644 --- a/src/macros.h +++ b/src/macros.h @@ -21,27 +21,18 @@ /* * Position comparisons */ -#ifdef FEAT_VIRTUALEDIT -# define LT_POS(a, b) (((a).lnum != (b).lnum) \ +#define LT_POS(a, b) (((a).lnum != (b).lnum) \ ? (a).lnum < (b).lnum \ : (a).col != (b).col \ ? (a).col < (b).col \ : (a).coladd < (b).coladd) -# define LT_POSP(a, b) (((a)->lnum != (b)->lnum) \ +#define LT_POSP(a, b) (((a)->lnum != (b)->lnum) \ ? (a)->lnum < (b)->lnum \ : (a)->col != (b)->col \ ? (a)->col < (b)->col \ : (a)->coladd < (b)->coladd) -# define EQUAL_POS(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && ((a).coladd == (b).coladd)) -# define CLEAR_POS(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0;} -#else -# define LT_POS(a, b) (((a).lnum != (b).lnum) \ - ? ((a).lnum < (b).lnum) : ((a).col < (b).col)) -# define LT_POSP(a, b) (((a)->lnum != (b)->lnum) \ - ? ((a)->lnum < (b)->lnum) : ((a)->col < (b)->col)) -# define EQUAL_POS(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col)) -# define CLEAR_POS(a) {(a)->lnum = 0; (a)->col = 0;} -#endif +#define EQUAL_POS(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && ((a).coladd == (b).coladd)) +#define CLEAR_POS(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0;} #define LTOREQ_POS(a, b) (LT_POS(a, b) || EQUAL_POS(a, b)) diff --git a/src/mark.c b/src/mark.c index de4b0f97b4..276391743c 100644 --- a/src/mark.c +++ b/src/mark.c @@ -414,9 +414,7 @@ getmark_buf_fnum( pos_copy.col = 0; else pos_copy.col = MAXCOL; -#ifdef FEAT_VIRTUALEDIT pos_copy.coladd = 0; -#endif } } else if (ASCII_ISLOWER(c)) /* normal named mark */ @@ -651,9 +649,7 @@ clrallmarks(buf_T *buf) buf->b_op_end.lnum = 0; buf->b_last_cursor.lnum = 1; /* '" mark cleared */ buf->b_last_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT buf->b_last_cursor.coladd = 0; -#endif buf->b_last_insert.lnum = 0; /* '^ mark cleared */ buf->b_last_change.lnum = 0; /* '. mark cleared */ #ifdef FEAT_JUMPLIST @@ -1052,7 +1048,7 @@ mark_adjust_internal( linenr_T *lp; win_T *win; tabpage_T *tab; - static pos_T initpos = INIT_POS_T(1, 0, 0); + static pos_T initpos = {1, 0, 0}; if (line2 < line1 && amount_after == 0L) /* nothing to do */ return; @@ -1451,9 +1447,7 @@ read_viminfo_filemark(vir_T *virp, int force) fm->fmark.mark.lnum = getdigits(&str); str = skipwhite(str); fm->fmark.mark.col = getdigits(&str); -#ifdef FEAT_VIRTUALEDIT fm->fmark.mark.coladd = 0; -#endif fm->fmark.fnum = 0; str = skipwhite(str); vim_free(fm->fname); @@ -1641,9 +1635,7 @@ handle_viminfo_mark(garray_T *values, int force) { fm->fmark.mark.lnum = lnum; fm->fmark.mark.col = col; -#ifdef FEAT_VIRTUALEDIT fm->fmark.mark.coladd = 0; -#endif fm->fmark.fnum = 0; vim_free(fm->fname); if (vp[4].bv_allocated) @@ -2146,9 +2138,7 @@ copy_viminfo_marks( } vim_free(str); -#ifdef FEAT_VIRTUALEDIT pos.coladd = 0; -#endif while (!(eof = viminfo_readline(virp)) && line[0] == TAB) { if (load_marks) diff --git a/src/mbyte.c b/src/mbyte.c index faeebfd83f..aa10d5e32b 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -3994,9 +3994,7 @@ utf_find_illegal(void) convert_setup(&vimconv, p_enc, curbuf->b_p_fenc); } -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif for (;;) { p = ml_get_cursor(); @@ -4118,18 +4116,13 @@ mb_adjustpos(buf_T *buf, pos_T *lp) { char_u *p; - if (lp->col > 0 -#ifdef FEAT_VIRTUALEDIT - || lp->coladd > 1 -#endif - ) + if (lp->col > 0 || lp->coladd > 1) { p = ml_get_buf(buf, lp->lnum, FALSE); if (*p == NUL || (int)STRLEN(p) < lp->col) lp->col = 0; else lp->col -= (*mb_head_off)(p, p + lp->col); -#ifdef FEAT_VIRTUALEDIT /* Reset "coladd" when the cursor would be on the right half of a * double-wide character. */ if (lp->coladd == 1 @@ -4137,7 +4130,6 @@ mb_adjustpos(buf_T *buf, pos_T *lp) && vim_isprintc((*mb_ptr2char)(p + lp->col)) && ptr2cells(p + lp->col) > 1) lp->coladd = 0; -#endif } } diff --git a/src/memline.c b/src/memline.c index f99344bd4d..c62ea5f60c 100644 --- a/src/memline.c +++ b/src/memline.c @@ -5667,9 +5667,7 @@ goto_byte(long cnt) { curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = (colnr_T)boff; -# ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -# endif curwin->w_set_curswant = TRUE; } check_cursor(); diff --git a/src/menu.c b/src/menu.c index a9cbb05d02..085d0e79ca 100644 --- a/src/menu.c +++ b/src/menu.c @@ -2318,9 +2318,7 @@ execute_menu(exarg_T *eap, vimmenu_T *menu, int mode_idx) curwin->w_cursor.col = 1; tpos.lnum = eap->line2; tpos.col = MAXCOL; -#ifdef FEAT_VIRTUALEDIT tpos.coladd = 0; -#endif } /* Activate visual mode */ diff --git a/src/misc1.c b/src/misc1.c index 0c38c8af53..1db7496c07 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -622,9 +622,7 @@ get_number_indent(linenr_T lnum) { pos.lnum = lnum; pos.col = (colnr_T)(*regmatch.endp - ml_get(lnum)); -#ifdef FEAT_VIRTUALEDIT pos.coladd = 0; -#endif } vim_regfree(regmatch.regprog); } @@ -1708,9 +1706,7 @@ open_line( changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L); curwin->w_cursor.col = newcol; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif #if defined(FEAT_LISP) || defined(FEAT_CINDENT) /* @@ -1781,9 +1777,7 @@ open_line( /* Insert new stuff into line again */ curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif ins_bytes(p_extra); /* will call changed_bytes() */ vim_free(p_extra); next_line = NULL; @@ -2354,11 +2348,9 @@ ins_char_bytes(char_u *buf, int charlen) linenr_T lnum = curwin->w_cursor.lnum; int i; -#ifdef FEAT_VIRTUALEDIT /* Break tabs if needed. */ if (virtual_active() && curwin->w_cursor.coladd > 0) coladvance_force(getviscol()); -#endif col = curwin->w_cursor.col; oldp = ml_get(lnum); @@ -2499,10 +2491,8 @@ ins_str(char_u *s) colnr_T col; linenr_T lnum = curwin->w_cursor.lnum; -#ifdef FEAT_VIRTUALEDIT if (virtual_active() && curwin->w_cursor.coladd > 0) coladvance_force(getviscol()); -#endif col = curwin->w_cursor.col; oldp = ml_get(lnum); @@ -2637,15 +2627,10 @@ del_bytes( * unless "restart_edit" is set or 'virtualedit' contains "onemore". */ if (col > 0 && fixpos && restart_edit == 0 -#ifdef FEAT_VIRTUALEDIT - && (ve_flags & VE_ONEMORE) == 0 -#endif - ) + && (ve_flags & VE_ONEMORE) == 0) { --curwin->w_cursor.col; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif if (has_mbyte) curwin->w_cursor.col -= (*mb_head_off)(oldp, oldp + curwin->w_cursor.col); diff --git a/src/misc2.c b/src/misc2.c index 1f5f752690..ca8f56d384 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -16,7 +16,6 @@ static char_u *username = NULL; /* cached result of mch_get_user_name() */ static char_u *ff_expand_buffer = NULL; /* used for expanding filenames */ -#if defined(FEAT_VIRTUALEDIT) || defined(PROTO) static int coladvance2(pos_T *pos, int addspaces, int finetune, colnr_T wcol); /* @@ -67,7 +66,6 @@ coladvance_force(colnr_T wcol) } return rc; } -#endif /* * Get the screen position of character col with a coladd in the cursor line. @@ -80,9 +78,7 @@ getviscol2(colnr_T col, colnr_T coladd UNUSED) pos.lnum = curwin->w_cursor.lnum; pos.col = col; -#ifdef FEAT_VIRTUALEDIT pos.coladd = coladd; -#endif getvvcol(curwin, &pos, &x, NULL, NULL); return (int)x; } @@ -119,7 +115,6 @@ coladvance(colnr_T wcol) int getvpos(pos_T *pos, colnr_T wcol) { -#ifdef FEAT_VIRTUALEDIT return coladvance2(pos, FALSE, virtual_active(), wcol); } @@ -130,7 +125,6 @@ coladvance2( int finetune, /* change char offset for the exact column */ colnr_T wcol) /* column to move to */ { -#endif int idx; char_u *ptr; char_u *line; @@ -144,10 +138,7 @@ coladvance2( one_more = (State & INSERT) || restart_edit != NUL || (VIsual_active && *p_sel != 'o') -#ifdef FEAT_VIRTUALEDIT - || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL) -#endif - ; + || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL) ; line = ml_get_buf(curbuf, pos->lnum, FALSE); if (wcol >= MAXCOL) @@ -155,18 +146,15 @@ coladvance2( idx = (int)STRLEN(line) - 1 + one_more; col = wcol; -#ifdef FEAT_VIRTUALEDIT if ((addspaces || finetune) && !VIsual_active) { curwin->w_curswant = linetabsize(line) + one_more; if (curwin->w_curswant > 0) --curwin->w_curswant; } -#endif } else { -#ifdef FEAT_VIRTUALEDIT int width = curwin->w_width - win_col_off(curwin); if (finetune @@ -188,7 +176,6 @@ coladvance2( wcol = (csize / width + 1) * width - 1; } } -#endif ptr = line; while (col <= wcol && *ptr != NUL) @@ -219,7 +206,6 @@ coladvance2( col -= csize; } -#ifdef FEAT_VIRTUALEDIT if (virtual_active() && addspaces && ((col != wcol && col != wcol + 1) || csize > 1)) @@ -283,7 +269,6 @@ coladvance2( col += correct; } } -#endif } if (idx < 0) @@ -291,7 +276,6 @@ coladvance2( else pos->col = idx; -#ifdef FEAT_VIRTUALEDIT pos->coladd = 0; if (finetune) @@ -318,7 +302,6 @@ coladvance2( col += b; } } -#endif /* prevent from moving onto a trail byte */ if (has_mbyte) @@ -364,9 +347,7 @@ inc(pos_T *lp) return ((p[l] != NUL) ? 0 : 2); } lp->col++; -#ifdef FEAT_VIRTUALEDIT lp->coladd = 0; -#endif return ((p[1] != NUL) ? 0 : 2); } } @@ -374,9 +355,7 @@ inc(pos_T *lp) { lp->col = 0; lp->lnum++; -#ifdef FEAT_VIRTUALEDIT lp->coladd = 0; -#endif return 1; } return -1; @@ -412,9 +391,7 @@ dec(pos_T *lp) { char_u *p; -#ifdef FEAT_VIRTUALEDIT lp->coladd = 0; -#endif if (lp->col == MAXCOL) { /* past end of line */ @@ -574,10 +551,8 @@ check_cursor_col(void) check_cursor_col_win(win_T *win) { colnr_T len; -#ifdef FEAT_VIRTUALEDIT colnr_T oldcol = win->w_cursor.col; colnr_T oldcoladd = win->w_cursor.col + win->w_cursor.coladd; -#endif len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, FALSE)); if (len == 0) @@ -590,9 +565,7 @@ check_cursor_col_win(win_T *win) * - 'virtualedit' is set */ if ((State & INSERT) || restart_edit || (VIsual_active && *p_sel != 'o') -#ifdef FEAT_VIRTUALEDIT || (ve_flags & VE_ONEMORE) -#endif || virtual_active()) win->w_cursor.col = len; else @@ -606,7 +579,6 @@ check_cursor_col_win(win_T *win) else if (win->w_cursor.col < 0) win->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT /* If virtual editing is on, we can leave the cursor on the old position, * only we must set it to virtual. But don't do it when at the end of the * line. */ @@ -634,7 +606,6 @@ check_cursor_col_win(win_T *win) /* avoid weird number when there is a miscalculation or overflow */ win->w_cursor.coladd = 0; } -#endif } /* @@ -2172,7 +2143,7 @@ ga_add_string(garray_T *gap, char_u *p) #endif /* - * Concatenate a string to a growarray which contains characters. + * Concatenate a string to a growarray which contains bytes. * When "s" is NULL does not do anything. * Note: Does NOT copy the NUL at the end! */ diff --git a/src/move.c b/src/move.c index dff3bb09d7..404b2350fd 100644 --- a/src/move.c +++ b/src/move.c @@ -508,17 +508,12 @@ check_cursor_moved(win_T *wp) } else if (wp->w_cursor.col != wp->w_valid_cursor.col || wp->w_leftcol != wp->w_valid_leftcol -#ifdef FEAT_VIRTUALEDIT - || wp->w_cursor.coladd != wp->w_valid_cursor.coladd -#endif - ) + || wp->w_cursor.coladd != wp->w_valid_cursor.coladd) { wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL); wp->w_valid_cursor.col = wp->w_cursor.col; wp->w_valid_leftcol = wp->w_leftcol; -#ifdef FEAT_VIRTUALEDIT wp->w_valid_cursor.coladd = wp->w_cursor.coladd; -#endif } } @@ -2800,9 +2795,7 @@ do_check_cursorbind(void) { linenr_T line = curwin->w_cursor.lnum; colnr_T col = curwin->w_cursor.col; -# ifdef FEAT_VIRTUALEDIT colnr_T coladd = curwin->w_cursor.coladd; -# endif colnr_T curswant = curwin->w_curswant; int set_curswant = curwin->w_set_curswant; win_T *old_curwin = curwin; @@ -2829,9 +2822,7 @@ do_check_cursorbind(void) # endif curwin->w_cursor.lnum = line; curwin->w_cursor.col = col; -# ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = coladd; -# endif curwin->w_curswant = curswant; curwin->w_set_curswant = set_curswant; diff --git a/src/netbeans.c b/src/netbeans.c index b36d8680c9..ecc7625e9b 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -3344,9 +3344,7 @@ off2pos(buf_T *buf, long offset) pos.lnum = 0; pos.col = 0; -#ifdef FEAT_VIRTUALEDIT pos.coladd = 0; -#endif if (!(buf->b_ml.ml_flags & ML_EMPTY)) { @@ -3378,9 +3376,7 @@ get_off_or_lnum(buf_T *buf, char_u **argp) mypos.lnum = (linenr_T)off; ++*argp; mypos.col = strtol((char *)*argp, (char **)argp, 10); -#ifdef FEAT_VIRTUALEDIT mypos.coladd = 0; -#endif return &mypos; } return off2pos(buf, off); diff --git a/src/normal.c b/src/normal.c index 00bb9ce9c9..b953b7dc4c 100644 --- a/src/normal.c +++ b/src/normal.c @@ -1340,9 +1340,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) static colnr_T redo_VIsual_vcol; /* number of cols or end column */ static long redo_VIsual_count; /* count for Visual operator */ static int redo_VIsual_arg; /* extra argument */ -#ifdef FEAT_VIRTUALEDIT int include_line_break = FALSE; -#endif #if defined(FEAT_CLIPBOARD) /* @@ -1527,20 +1525,13 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) /* If 'selection' is "exclusive", backup one character for * charwise selections. */ else if (VIsual_mode == 'v') - { -# ifdef FEAT_VIRTUALEDIT - include_line_break = -# endif - unadjust_for_sel(); - } + include_line_break = unadjust_for_sel(); oap->start = VIsual; if (VIsual_mode == 'V') { oap->start.col = 0; -# ifdef FEAT_VIRTUALEDIT oap->start.coladd = 0; -# endif } } @@ -1590,10 +1581,8 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) check_pos(curwin->w_buffer, &oap->end); oap->line_count = oap->end.lnum - oap->start.lnum + 1; -#ifdef FEAT_VIRTUALEDIT /* Set "virtual_op" before resetting VIsual_active. */ virtual_op = virtual_active(); -#endif if (VIsual_active || redo_VIsual_busy) { @@ -1685,10 +1674,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) { oap->motion_type = MCHAR; if (VIsual_mode != Ctrl_V && *ml_get_pos(&(oap->end)) == NUL -#ifdef FEAT_VIRTUALEDIT - && (include_line_break || !virtual_op) -#endif - ) + && (include_line_break || !virtual_op)) { oap->inclusive = FALSE; /* Try to include the newline, unless it's an operator @@ -1699,9 +1685,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) { ++oap->end.lnum; oap->end.col = 0; -#ifdef FEAT_VIRTUALEDIT oap->end.coladd = 0; -#endif ++oap->line_count; } } @@ -1759,10 +1743,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) || (oap->op_type == OP_YANK && gchar_pos(&oap->end) == NUL)) && EQUAL_POS(oap->start, oap->end) -#ifdef FEAT_VIRTUALEDIT - && !(virtual_op && oap->start.coladd != oap->end.coladd) -#endif - ); + && !(virtual_op && oap->start.coladd != oap->end.coladd)); /* * For delete, change and yank, it's an error to operate on an * empty region, when 'E' included in 'cpoptions' (Vi compatible). @@ -2097,9 +2078,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) default: clearopbeep(oap); } -#ifdef FEAT_VIRTUALEDIT virtual_op = MAYBE; -#endif if (!gui_yank) { /* @@ -2198,9 +2177,7 @@ op_function(oparg_T *oap UNUSED) { #ifdef FEAT_EVAL typval_T argv[2]; -# ifdef FEAT_VIRTUALEDIT int save_virtual_op = virtual_op; -# endif if (*p_opfunc == NUL) emsg(_("E774: 'operatorfunc' is empty")); @@ -2222,17 +2199,13 @@ op_function(oparg_T *oap UNUSED) argv[0].vval.v_string = (char_u *)"char"; argv[1].v_type = VAR_UNKNOWN; -# ifdef FEAT_VIRTUALEDIT /* Reset virtual_op so that 'virtualedit' can be changed in the * function. */ virtual_op = MAYBE; -# endif (void)call_func_retnr(p_opfunc, 1, argv); -# ifdef FEAT_VIRTUALEDIT virtual_op = save_virtual_op; -# endif } #else emsg(_("E775: Eval feature not available")); @@ -3290,10 +3263,8 @@ end_visual_mode(void) #ifdef FEAT_EVAL curbuf->b_visual_mode_eval = VIsual_mode; #endif -#ifdef FEAT_VIRTUALEDIT if (!virtual_active()) curwin->w_cursor.coladd = 0; -#endif may_clear_cmdline(); adjust_cursor_eol(); @@ -5944,14 +5915,12 @@ nv_right(cmdarg_T *cap) cap->oap->inclusive = FALSE; past_line = (VIsual_active && *p_sel != 'o'); -#ifdef FEAT_VIRTUALEDIT /* * In virtual edit mode, there's no such thing as "past_line", as lines * are (theoretically) infinitely long. */ if (virtual_active()) past_line = 0; -#endif for (n = cap->count1; n > 0; --n) { @@ -5983,9 +5952,7 @@ nv_right(cmdarg_T *cap) { ++curwin->w_cursor.lnum; curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_set_curswant = TRUE; cap->oap->inclusive = FALSE; } @@ -6007,11 +5974,9 @@ nv_right(cmdarg_T *cap) else if (past_line) { curwin->w_set_curswant = TRUE; -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) oneright(); else -#endif { if (has_mbyte) curwin->w_cursor.col += @@ -6242,13 +6207,11 @@ nv_dollar(cmdarg_T *cap) { cap->oap->motion_type = MCHAR; cap->oap->inclusive = TRUE; -#ifdef FEAT_VIRTUALEDIT /* In virtual mode when off the edge of a line and an operator * is pending (whew!) keep the cursor where it is. * Otherwise, send it to the end of the line. */ if (!virtual_active() || gchar_cursor() != NUL || cap->oap->op_type == OP_NOP) -#endif curwin->w_curswant = MAXCOL; /* so we stay at the end */ if (cursor_down((long)(cap->count1 - 1), cap->oap->op_type == OP_NOP) == FAIL) @@ -6341,9 +6304,7 @@ normal_search( { if (i == 2) cap->oap->motion_type = MLINE; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif #ifdef FEAT_FOLDING if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped) foldOpenCursor(); @@ -6378,7 +6339,6 @@ nv_csearch(cmdarg_T *cap) else { curwin->w_set_curswant = TRUE; -#ifdef FEAT_VIRTUALEDIT /* Include a Tab for "tx" and for "dfx". */ if (gchar_cursor() == TAB && virtual_active() && cap->arg == FORWARD && (t_cmd || cap->oap->op_type != OP_NOP)) @@ -6390,7 +6350,6 @@ nv_csearch(cmdarg_T *cap) } else curwin->w_cursor.coladd = 0; -#endif adjust_for_sel(cap); #ifdef FEAT_FOLDING if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP) @@ -6406,7 +6365,7 @@ nv_csearch(cmdarg_T *cap) static void nv_brackets(cmdarg_T *cap) { - pos_T new_pos = INIT_POS_T(0, 0, 0); + pos_T new_pos = {0, 0, 0}; pos_T prev_pos; pos_T *pos = NULL; /* init for GCC */ pos_T old_pos; /* cursor position before command */ @@ -6418,9 +6377,7 @@ nv_brackets(cmdarg_T *cap) cap->oap->motion_type = MCHAR; cap->oap->inclusive = FALSE; old_pos = curwin->w_cursor; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; // TODO: don't do this for an error. -#endif #ifdef FEAT_SEARCHPATH /* @@ -6815,9 +6772,7 @@ nv_percent(cmdarg_T *cap) setpcmark(); curwin->w_cursor = *pos; curwin->w_set_curswant = TRUE; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif adjust_for_sel(cap); } } @@ -6849,9 +6804,7 @@ nv_brace(cmdarg_T *cap) { /* Don't leave the cursor on the NUL past end of line. */ adjust_cursor(cap->oap); -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif #ifdef FEAT_FOLDING if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP) foldOpenCursor(); @@ -6887,9 +6840,7 @@ nv_findpar(cmdarg_T *cap) clearopbeep(cap->oap); else { -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif #ifdef FEAT_FOLDING if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP) foldOpenCursor(); @@ -6991,7 +6942,6 @@ nv_replace(cmdarg_T *cap) return; } -#ifdef FEAT_VIRTUALEDIT /* Break tabs, etc. */ if (virtual_active()) { @@ -7006,7 +6956,6 @@ nv_replace(cmdarg_T *cap) else if (gchar_cursor() == TAB) coladvance_force(getviscol()); } -#endif /* Abort if not enough characters to replace. */ ptr = ml_get_cursor(); @@ -7172,11 +7121,8 @@ v_swap_corners(int cmdchar) ++curwin->w_curswant; coladvance(curwin->w_curswant); if (curwin->w_cursor.col == old_cursor.col -#ifdef FEAT_VIRTUALEDIT && (!virtual_active() - || curwin->w_cursor.coladd == old_cursor.coladd) -#endif - ) + || curwin->w_cursor.coladd == old_cursor.coladd)) { curwin->w_cursor.lnum = VIsual.lnum; if (old_cursor.lnum <= VIsual.lnum && *p_sel == 'e') @@ -7218,10 +7164,8 @@ nv_Replace(cmdarg_T *cap) emsg(_(e_modifiable)); else { -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) coladvance(getviscol()); -#endif invoke_edit(cap, FALSE, cap->arg ? 'V' : 'R', FALSE); } } @@ -7249,10 +7193,8 @@ nv_vreplace(cmdarg_T *cap) cap->extra_char = get_literal(); stuffcharReadbuff(cap->extra_char); stuffcharReadbuff(ESC); -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) coladvance(getviscol()); -#endif invoke_edit(cap, TRUE, 'v', FALSE); } } @@ -7524,11 +7466,9 @@ nv_gomark(cmdarg_T *cap) else nv_cursormark(cap, cap->arg, pos); -#ifdef FEAT_VIRTUALEDIT /* May need to clear the coladd that a mark includes. */ if (!virtual_active()) curwin->w_cursor.coladd = 0; -#endif check_cursor_col(); #ifdef FEAT_FOLDING if (cap->oap->op_type == OP_NOP @@ -7761,16 +7701,14 @@ n_start_visual_mode(int c) VIsual_mode = c; VIsual_active = TRUE; VIsual_reselect = TRUE; -#ifdef FEAT_VIRTUALEDIT - /* Corner case: the 0 position in a tab may change when going into - * virtualedit. Recalculate curwin->w_cursor to avoid bad hilighting. - */ + + // Corner case: the 0 position in a tab may change when going into + // virtualedit. Recalculate curwin->w_cursor to avoid bad hilighting. if (c == Ctrl_V && (ve_flags & VE_BLOCK) && gchar_cursor() == TAB) { validate_virtcol(); coladvance(curwin->w_virtcol); } -#endif VIsual = curwin->w_cursor; #ifdef FEAT_FOLDING @@ -8212,10 +8150,8 @@ nv_g_cmd(cmdarg_T *cap) i = (int)STRLEN(ml_get_curline()); if (curwin->w_cursor.col > (colnr_T)i) { -#ifdef FEAT_VIRTUALEDIT if (virtual_active()) curwin->w_cursor.coladd += curwin->w_cursor.col - i; -#endif curwin->w_cursor.col = i; } } @@ -8773,10 +8709,7 @@ adjust_cursor(oparg_T *oap) */ if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL && (!VIsual_active || *p_sel == 'o') -#ifdef FEAT_VIRTUALEDIT - && !virtual_active() && (ve_flags & VE_ONEMORE) == 0 -#endif - ) + && !virtual_active() && (ve_flags & VE_ONEMORE) == 0) { --curwin->w_cursor.col; /* prevent cursor from moving on the trail byte */ @@ -8837,11 +8770,9 @@ unadjust_for_sel(void) pp = &curwin->w_cursor; else pp = &VIsual; -#ifdef FEAT_VIRTUALEDIT if (pp->coladd > 0) --pp->coladd; else -#endif if (pp->col > 0) { --pp->col; @@ -9077,7 +9008,6 @@ nv_edit(cmdarg_T *cap) { case 'A': /* "A"ppend after the line */ curwin->w_set_curswant = TRUE; -#ifdef FEAT_VIRTUALEDIT if (ve_flags == VE_ALL) { int save_State = State; @@ -9089,7 +9019,6 @@ nv_edit(cmdarg_T *cap) State = save_State; } else -#endif curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor()); break; @@ -9108,7 +9037,6 @@ nv_edit(cmdarg_T *cap) /* FALLTHROUGH */ case 'a': /* "a"ppend is like "i"nsert on the next character. */ -#ifdef FEAT_VIRTUALEDIT /* increment coladd when in virtual space, increment the * column otherwise, also to append after an unprintable char */ if (virtual_active() @@ -9116,14 +9044,11 @@ nv_edit(cmdarg_T *cap) || *ml_get_cursor() == NUL || *ml_get_cursor() == TAB)) curwin->w_cursor.coladd++; - else -#endif - if (*ml_get_cursor() != NUL) + else if (*ml_get_cursor() != NUL) inc_cursor(); break; } -#ifdef FEAT_VIRTUALEDIT if (curwin->w_cursor.coladd && cap->cmdchar != 'A') { int save_State = State; @@ -9134,7 +9059,6 @@ nv_edit(cmdarg_T *cap) coladvance(getviscol()); State = save_State; } -#endif invoke_edit(cap, FALSE, cap->cmdchar, FALSE); } diff --git a/src/ops.c b/src/ops.c index e93119049a..dacbfd87cd 100644 --- a/src/ops.c +++ b/src/ops.c @@ -1802,12 +1802,10 @@ op_delete(oparg_T *oap) * It's an error to operate on an empty region, when 'E' included in * 'cpoptions' (Vi compatible). */ -#ifdef FEAT_VIRTUALEDIT if (virtual_op) /* Virtual editing: Nothing gets deleted, but we set the '[ and '] * marks as if it happened. */ goto setmarks; -#endif if (vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL) beep_flush(); return OK; @@ -1909,9 +1907,7 @@ op_delete(oparg_T *oap) if (lnum == curwin->w_cursor.lnum) { curwin->w_cursor.col = bd.textcol + bd.startspaces; -# ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -# endif } /* n == number of chars deleted @@ -1979,7 +1975,6 @@ op_delete(oparg_T *oap) } else { -#ifdef FEAT_VIRTUALEDIT if (virtual_op) { int endcol = 0; @@ -2016,7 +2011,6 @@ op_delete(oparg_T *oap) curwin->w_cursor = oap->start; } } -#endif if (oap->line_count == 1) /* delete characters within one line */ { @@ -2032,7 +2026,6 @@ op_delete(oparg_T *oap) n = oap->end.col - oap->start.col + 1 - !oap->inclusive; -#ifdef FEAT_VIRTUALEDIT if (virtual_op) { /* fix up things for virtualedit-delete: @@ -2053,7 +2046,6 @@ op_delete(oparg_T *oap) if (gchar_cursor() != NUL) curwin->w_cursor.coladd = 0; } -#endif (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE && !oap->is_VIsual); } @@ -2084,9 +2076,7 @@ op_delete(oparg_T *oap) msgmore(curbuf->b_ml.ml_line_count - old_lcount); -#ifdef FEAT_VIRTUALEDIT setmarks: -#endif if (oap->block_mode) { curbuf->b_op_end.lnum = oap->end.lnum; @@ -2183,7 +2173,6 @@ op_replace(oparg_T *oap, int c) * If we split a TAB, it may be replaced by several characters. * Thus the number of characters may increase! */ -#ifdef FEAT_VIRTUALEDIT /* If the range starts in virtual space, count the initial * coladd offset as part of "startspaces" */ if (virtual_op && bd.is_short && *bd.textstart == NUL) @@ -2196,15 +2185,12 @@ op_replace(oparg_T *oap, int c) n = bd.startspaces; } else -#endif /* allow for pre spaces */ n = (bd.startspaces ? bd.start_char_vcols - 1 : 0); /* allow for post spp */ n += (bd.endspaces -#ifdef FEAT_VIRTUALEDIT && !bd.is_oneChar -#endif && bd.end_char_vcols > 0) ? bd.end_char_vcols - 1 : 0; /* Figure out how many characters to replace. */ numc = oap->end_vcol - oap->start_vcol + 1; @@ -2311,7 +2297,6 @@ op_replace(oparg_T *oap, int c) } else { -#ifdef FEAT_VIRTUALEDIT if (n == TAB) { int end_vcol = 0; @@ -2327,11 +2312,9 @@ op_replace(oparg_T *oap, int c) if (curwin->w_cursor.lnum == oap->end.lnum) getvpos(&oap->end, end_vcol); } -#endif PBYTE(curwin->w_cursor, c); } } -#ifdef FEAT_VIRTUALEDIT else if (virtual_op && curwin->w_cursor.lnum == oap->end.lnum) { int virtcols = oap->end.coladd; @@ -2355,7 +2338,6 @@ op_replace(oparg_T *oap, int c) break; } } -#endif /* Advance to next character, stop at the end of the file. */ if (inc_cursor() == -1) @@ -2609,7 +2591,6 @@ op_insert(oparg_T *oap, long count1) if (oap->block_mode) { -#ifdef FEAT_VIRTUALEDIT /* When 'virtualedit' is used, need to insert the extra spaces before * doing block_prep(). When only "block" is used, virtual edit is * already disabled, but still need it when calling @@ -2627,7 +2608,6 @@ op_insert(oparg_T *oap, long count1) --curwin->w_cursor.col; ve_flags = old_ve_flags; } -#endif /* Get the info about the block before entering the text */ block_prep(oap, &bd, oap->start.lnum, TRUE); /* Get indent information */ @@ -2641,11 +2621,7 @@ op_insert(oparg_T *oap, long count1) if (oap->op_type == OP_APPEND) { - if (oap->block_mode -#ifdef FEAT_VIRTUALEDIT - && curwin->w_cursor.coladd == 0 -#endif - ) + if (oap->block_mode && curwin->w_cursor.coladd == 0) { /* Move the cursor to the character right of the block. */ curwin->w_set_curswant = TRUE; @@ -2715,45 +2691,23 @@ op_insert(oparg_T *oap, long count1) && !bd.is_MAX && !did_indent) { if (oap->op_type == OP_INSERT - && oap->start.col -#ifdef FEAT_VIRTUALEDIT - + oap->start.coladd -#endif + && oap->start.col + oap->start.coladd != curbuf->b_op_start_orig.col -#ifdef FEAT_VIRTUALEDIT - + curbuf->b_op_start_orig.coladd -#endif - ) + + curbuf->b_op_start_orig.coladd) { int t = getviscol2(curbuf->b_op_start_orig.col, -#ifdef FEAT_VIRTUALEDIT - curbuf->b_op_start_orig.coladd -#else - 0 -#endif - ); + curbuf->b_op_start_orig.coladd); oap->start.col = curbuf->b_op_start_orig.col; pre_textlen -= t - oap->start_vcol; oap->start_vcol = t; } else if (oap->op_type == OP_APPEND - && oap->end.col -#ifdef FEAT_VIRTUALEDIT - + oap->end.coladd -#endif + && oap->end.col + oap->end.coladd >= curbuf->b_op_start_orig.col -#ifdef FEAT_VIRTUALEDIT - + curbuf->b_op_start_orig.coladd -#endif - ) + + curbuf->b_op_start_orig.coladd) { int t = getviscol2(curbuf->b_op_start_orig.col, -#ifdef FEAT_VIRTUALEDIT - curbuf->b_op_start_orig.coladd -#else - 0 -#endif - ); + curbuf->b_op_start_orig.coladd); oap->start.col = curbuf->b_op_start_orig.col; /* reset pre_textlen to the value of OP_INSERT */ pre_textlen += bd.textlen; @@ -2865,12 +2819,10 @@ op_change(oparg_T *oap) /* skip blank lines too */ if (oap->block_mode) { -#ifdef FEAT_VIRTUALEDIT /* Add spaces before getting the current line length. */ if (virtual_op && (curwin->w_cursor.coladd > 0 || gchar_cursor() == NUL)) coladvance_force(getviscol()); -#endif firstline = ml_get(oap->start.lnum); pre_textlen = (long)STRLEN(firstline); pre_indent = (long)getwhitecols(firstline); @@ -2916,7 +2868,6 @@ op_change(oparg_T *oap) block_prep(oap, &bd, linenr, TRUE); if (!bd.is_short || virtual_op) { -#ifdef FEAT_VIRTUALEDIT pos_T vpos; /* If the block starts in virtual space, count the @@ -2928,22 +2879,16 @@ op_change(oparg_T *oap) } else vpos.coladd = 0; -#endif oldp = ml_get(linenr); newp = alloc_check((unsigned)(STRLEN(oldp) -#ifdef FEAT_VIRTUALEDIT - + vpos.coladd -#endif - + ins_len + 1)); + + vpos.coladd + ins_len + 1)); if (newp == NULL) continue; /* copy up to block start */ mch_memmove(newp, oldp, (size_t)bd.textcol); offset = bd.textcol; -#ifdef FEAT_VIRTUALEDIT vim_memset(newp + offset, ' ', (size_t)vpos.coladd); offset += vpos.coladd; -#endif mch_memmove(newp + offset, ins_text, (size_t)ins_len); offset += ins_len; oldp += bd.textcol; @@ -3148,10 +3093,9 @@ op_yank(oparg_T *oap, int deleting, int mess) case MCHAR: { colnr_T startcol = 0, endcol = MAXCOL; -#ifdef FEAT_VIRTUALEDIT int is_oneChar = FALSE; colnr_T cs, ce; -#endif + p = ml_get(lnum); bd.startspaces = 0; bd.endspaces = 0; @@ -3159,7 +3103,6 @@ op_yank(oparg_T *oap, int deleting, int mess) if (lnum == oap->start.lnum) { startcol = oap->start.col; -#ifdef FEAT_VIRTUALEDIT if (virtual_op) { getvcol(curwin, &oap->start, &cs, NULL, &ce); @@ -3172,13 +3115,11 @@ op_yank(oparg_T *oap, int deleting, int mess) startcol++; } } -#endif } if (lnum == oap->end.lnum) { endcol = oap->end.col; -#ifdef FEAT_VIRTUALEDIT if (virtual_op) { getvcol(curwin, &oap->end, &cs, NULL, &ce); @@ -3205,15 +3146,10 @@ op_yank(oparg_T *oap, int deleting, int mess) } } } -#endif } if (endcol == MAXCOL) endcol = (colnr_T)STRLEN(p); - if (startcol > endcol -#ifdef FEAT_VIRTUALEDIT - || is_oneChar -#endif - ) + if (startcol > endcol || is_oneChar) bd.textlen = 0; else { @@ -3661,7 +3597,6 @@ do_put( yanklen = (int)STRLEN(y_array[0]); -#ifdef FEAT_VIRTUALEDIT if (ve_flags == VE_ALL && y_type == MCHAR) { if (gchar_cursor() == TAB) @@ -3687,7 +3622,6 @@ do_put( else if (curwin->w_cursor.coladd > 0 || gchar_cursor() == NUL) coladvance_force(getviscol() + (dir == FORWARD)); } -#endif lnum = curwin->w_cursor.lnum; col = curwin->w_cursor.col; @@ -3702,27 +3636,22 @@ do_put( if (dir == FORWARD && c != NUL) { -#ifdef FEAT_VIRTUALEDIT if (ve_flags == VE_ALL) getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2); else -#endif getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); if (has_mbyte) /* move to start of next multi-byte character */ curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor()); else -#ifdef FEAT_VIRTUALEDIT if (c != TAB || ve_flags != VE_ALL) -#endif ++curwin->w_cursor.col; ++col; } else getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2); -#ifdef FEAT_VIRTUALEDIT col += curwin->w_cursor.coladd; if (ve_flags == VE_ALL && (curwin->w_cursor.coladd > 0 @@ -3741,7 +3670,6 @@ do_put( } } curwin->w_cursor.coladd = 0; -#endif bd.textcol = 0; for (i = 0; i < y_size; ++i) { @@ -3850,9 +3778,7 @@ do_put( /* adjust '] mark */ curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1; curbuf->b_op_end.col = bd.textcol + totlen - 1; -# ifdef FEAT_VIRTUALEDIT curbuf->b_op_end.coladd = 0; -# endif if (flags & PUT_CURSEND) { colnr_T len; @@ -4144,15 +4070,12 @@ adjust_cursor_eol(void) { if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL -#ifdef FEAT_VIRTUALEDIT && (ve_flags & VE_ONEMORE) == 0 -#endif && !(restart_edit || (State & INSERT))) { /* Put the cursor on the last character in the line. */ dec_cursor(); -#ifdef FEAT_VIRTUALEDIT if (ve_flags == VE_ALL) { colnr_T scol, ecol; @@ -4161,7 +4084,6 @@ adjust_cursor_eol(void) getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol); curwin->w_cursor.coladd = ecol - scol + 1; } -#endif } } @@ -4704,9 +4626,7 @@ do_join( (vim_strchr(p_cpo, CPO_JOINCOL) != NULL ? currsize : col); check_cursor_col(); -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_set_curswant = TRUE; theend: @@ -7394,13 +7314,9 @@ cursor_pos_info(dict_T *dict) switch (VIsual_mode) { case Ctrl_V: -#ifdef FEAT_VIRTUALEDIT virtual_op = virtual_active(); -#endif block_prep(&oparg, &bd, lnum, 0); -#ifdef FEAT_VIRTUALEDIT virtual_op = MAYBE; -#endif s = bd.textstart; len = (long)bd.textlen; break; diff --git a/src/option.c b/src/option.c index 4b39f83f64..dda5414e61 100644 --- a/src/option.c +++ b/src/option.c @@ -2939,13 +2939,8 @@ static struct vimoption options[] = SCTX_INIT}, {"virtualedit", "ve", P_STRING|P_ONECOMMA|P_NODUP|P_VI_DEF |P_VIM|P_CURSWANT, -#ifdef FEAT_VIRTUALEDIT (char_u *)&p_ve, PV_NONE, {(char_u *)"", (char_u *)""} -#else - (char_u *)NULL, PV_NONE, - {(char_u *)0L, (char_u *)0L} -#endif SCTX_INIT}, {"visualbell", "vb", P_BOOL|P_VI_DEF, (char_u *)&p_vb, PV_NONE, @@ -5526,9 +5521,7 @@ didset_options(void) #endif (void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE); (void)opt_strings_flags(p_tc, p_tc_values, &tc_flags, FALSE); -#ifdef FEAT_VIRTUALEDIT (void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE); -#endif #if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS)) (void)opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE); #endif @@ -7374,7 +7367,6 @@ did_set_string_option( } #endif -#ifdef FEAT_VIRTUALEDIT /* 'virtualedit' */ else if (varp == &p_ve) { @@ -7388,7 +7380,6 @@ did_set_string_option( coladvance(curwin->w_virtcol); } } -#endif #if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX) else if (varp == &p_csqf) diff --git a/src/option.h b/src/option.h index d648df7dcd..c282da3253 100644 --- a/src/option.h +++ b/src/option.h @@ -908,17 +908,15 @@ EXTERN char_u *p_vop; /* 'viewoptions' */ EXTERN unsigned vop_flags; /* uses SSOP_ flags */ #endif EXTERN int p_vb; /* 'visualbell' */ -#ifdef FEAT_VIRTUALEDIT EXTERN char_u *p_ve; /* 'virtualedit' */ EXTERN unsigned ve_flags; -# ifdef IN_OPTION_C +#ifdef IN_OPTION_C static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL}; -# endif -# define VE_BLOCK 5 /* includes "all" */ -# define VE_INSERT 6 /* includes "all" */ -# define VE_ALL 4 -# define VE_ONEMORE 8 #endif +#define VE_BLOCK 5 /* includes "all" */ +#define VE_INSERT 6 /* includes "all" */ +#define VE_ALL 4 +#define VE_ONEMORE 8 EXTERN long p_verbose; /* 'verbose' */ #ifdef IN_OPTION_C char_u *p_vfile = (char_u *)""; /* used before options are initialized */ diff --git a/src/screen.c b/src/screen.c index 9cdbf16b09..570910e29f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1622,14 +1622,14 @@ win_update(win_T *wp) if (VIsual_mode == Ctrl_V) { colnr_T fromc, toc; -#if defined(FEAT_VIRTUALEDIT) && defined(FEAT_LINEBREAK) +#if defined(FEAT_LINEBREAK) int save_ve_flags = ve_flags; if (curwin->w_p_lbr) ve_flags = VE_ALL; #endif getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc); -#if defined(FEAT_VIRTUALEDIT) && defined(FEAT_LINEBREAK) +#if defined(FEAT_LINEBREAK) ve_flags = save_ve_flags; #endif ++toc; @@ -3342,11 +3342,7 @@ win_line( } if (VIsual_mode != 'V' && lnum == bot->lnum) { - if (*p_sel == 'e' && bot->col == 0 -#ifdef FEAT_VIRTUALEDIT - && bot->coladd == 0 -#endif - ) + if (*p_sel == 'e' && bot->col == 0 && bot->coladd == 0) { fromcol = -10; tocol = MAXCOL; @@ -3545,9 +3541,7 @@ win_line( #ifdef FEAT_SYN_HL wp->w_p_cuc || draw_color_col || #endif -#ifdef FEAT_VIRTUALEDIT virtual_active() || -#endif (VIsual_active && wp->w_buffer == curwin->w_buffer))) { vcol = v; @@ -5033,14 +5027,12 @@ win_line( ) #endif { -#ifdef FEAT_VIRTUALEDIT /* In virtualedit, visual selections may extend * beyond end of line. */ if (area_highlighting && virtual_active() && tocol != MAXCOL && vcol < tocol) n_extra = 0; else -#endif { p_extra = at_end_str; n_extra = 1; @@ -5107,7 +5099,6 @@ win_line( } mb_utf8 = FALSE; /* don't draw as UTF-8 */ } -#ifdef FEAT_VIRTUALEDIT else if (VIsual_active && (VIsual_mode == Ctrl_V || VIsual_mode == 'v') @@ -5115,15 +5106,14 @@ win_line( && tocol != MAXCOL && vcol < tocol && ( -# ifdef FEAT_RIGHTLEFT +#ifdef FEAT_RIGHTLEFT wp->w_p_rl ? (col >= 0) : -# endif +#endif (col < wp->w_width))) { c = ' '; --ptr; /* put it back at the NUL */ } -#endif #if defined(LINE_ATTR) else if (( # ifdef FEAT_DIFF @@ -10866,9 +10856,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum) || wp->w_cursor.lnum != wp->w_ru_cursor.lnum || wp->w_cursor.col != wp->w_ru_cursor.col || wp->w_virtcol != wp->w_ru_virtcol -#ifdef FEAT_VIRTUALEDIT || wp->w_cursor.coladd != wp->w_ru_cursor.coladd -#endif || wp->w_topline != wp->w_ru_topline || wp->w_buffer->b_ml.ml_line_count != wp->w_ru_line_count #ifdef FEAT_DIFF diff --git a/src/search.c b/src/search.c index 0c2ce95614..a4b4c4177c 100644 --- a/src/search.c +++ b/src/search.c @@ -1029,11 +1029,9 @@ searchit( end_pos->col = endpos.col; } } -#ifdef FEAT_VIRTUALEDIT pos->coladd = 0; if (end_pos != NULL) end_pos->coladd = 0; -#endif found = 1; first_match = FALSE; @@ -1919,9 +1917,7 @@ findmatchlimit( #endif pos = curwin->w_cursor; -#ifdef FEAT_VIRTUALEDIT pos.coladd = 0; -#endif linep = ml_get(pos.lnum); cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL); @@ -3027,9 +3023,7 @@ fwd_word( int i; int last_line; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif cls_bigword = bigword; while (--count >= 0) { @@ -3094,9 +3088,7 @@ bck_word(long count, int bigword, int stop) { int sclass; /* starting class */ -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif cls_bigword = bigword; while (--count >= 0) { @@ -3163,9 +3155,7 @@ end_word( { int sclass; /* starting class */ -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif cls_bigword = bigword; while (--count >= 0) { @@ -3233,9 +3223,7 @@ bckend_word( int sclass; /* starting class */ int i; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif cls_bigword = bigword; while (--count >= 0) { diff --git a/src/spell.c b/src/spell.c index 59e73682b5..8aadb99531 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1652,9 +1652,7 @@ spell_move_to( found_one = TRUE; found_pos.lnum = lnum; found_pos.col = (int)(p - buf); -#ifdef FEAT_VIRTUALEDIT found_pos.coladd = 0; -#endif if (dir == FORWARD) { /* No need to search further. */ diff --git a/src/structs.h b/src/structs.h index e25ae17386..459103d3a4 100644 --- a/src/structs.h +++ b/src/structs.h @@ -21,30 +21,23 @@ typedef unsigned short short_u; #endif /* - * position in file or buffer + * Position in file or buffer. */ typedef struct { - linenr_T lnum; /* line number */ - colnr_T col; /* column number */ -#ifdef FEAT_VIRTUALEDIT - colnr_T coladd; -#endif + linenr_T lnum; // line number + colnr_T col; // column number + colnr_T coladd; // extra virtual column } pos_T; -#ifdef FEAT_VIRTUALEDIT -# define INIT_POS_T(l, c, ca) {l, c, ca} -#else -# define INIT_POS_T(l, c, ca) {l, c} -#endif /* * Same, but without coladd. */ typedef struct { - linenr_T lnum; /* line number */ - colnr_T col; /* column number */ + linenr_T lnum; // line number + colnr_T col; // column number } lpos_T; /* @@ -395,9 +388,7 @@ struct u_header u_entry_T *uh_entry; /* pointer to first entry */ u_entry_T *uh_getbot_entry; /* pointer to where ue_bot must be set */ pos_T uh_cursor; /* cursor position before saving */ -#ifdef FEAT_VIRTUALEDIT long uh_cursor_vcol; -#endif int uh_flags; /* see below */ pos_T uh_namedm[NMARKS]; /* marks before undo/after redo */ visualinfo_T uh_visual; /* Visual areas before undo/after redo */ diff --git a/src/tag.c b/src/tag.c index b70716f3e6..b1915e1e14 100644 --- a/src/tag.c +++ b/src/tag.c @@ -85,7 +85,7 @@ static char_u *tagmatchname = NULL; /* name of last used tag */ * Tag for preview window is remembered separately, to avoid messing up the * normal tagstack. */ -static taggy_T ptag_entry = {NULL, {INIT_POS_T(0, 0, 0), 0}, 0, 0}; +static taggy_T ptag_entry = {NULL, {{0, 0, 0}, 0}, 0, 0}; #endif /* diff --git a/src/ui.c b/src/ui.c index 63cc8bb61c..9150dafa6e 100644 --- a/src/ui.c +++ b/src/ui.c @@ -3184,9 +3184,7 @@ get_fpos_of_mouse(pos_T *mpos) if (mpos->col > 0) --mpos->col; -#ifdef FEAT_VIRTUALEDIT mpos->coladd = 0; -#endif return IN_BUFFER; } #endif diff --git a/src/undo.c b/src/undo.c index 911eed5c8e..6b6dd479b0 100644 --- a/src/undo.c +++ b/src/undo.c @@ -548,12 +548,10 @@ u_savecommon( uhp->uh_entry = NULL; uhp->uh_getbot_entry = NULL; uhp->uh_cursor = curwin->w_cursor; /* save cursor pos. for undo */ -#ifdef FEAT_VIRTUALEDIT if (virtual_active() && curwin->w_cursor.coladd > 0) uhp->uh_cursor_vcol = getviscol(); else uhp->uh_cursor_vcol = -1; -#endif /* save changed and buffer empty flag for undo */ uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) + @@ -1250,11 +1248,7 @@ serialize_uhp(bufinfo_T *bi, u_header_T *uhp) put_header_ptr(bi, uhp->uh_alt_prev.ptr); undo_write_bytes(bi, uhp->uh_seq, 4); serialize_pos(bi, uhp->uh_cursor); -#ifdef FEAT_VIRTUALEDIT undo_write_bytes(bi, (long_u)uhp->uh_cursor_vcol, 4); -#else - undo_write_bytes(bi, (long_u)0, 4); -#endif undo_write_bytes(bi, (long_u)uhp->uh_flags, 2); /* Assume NMARKS will stay the same. */ for (i = 0; i < NMARKS; ++i) @@ -1309,11 +1303,7 @@ unserialize_uhp(bufinfo_T *bi, char_u *file_name) return NULL; } unserialize_pos(bi, &uhp->uh_cursor); -#ifdef FEAT_VIRTUALEDIT uhp->uh_cursor_vcol = undo_read_4c(bi); -#else - (void)undo_read_4c(bi); -#endif uhp->uh_flags = undo_read_2c(bi); for (i = 0; i < NMARKS; ++i) unserialize_pos(bi, &uhp->uh_namedm[i]); @@ -1458,11 +1448,7 @@ serialize_pos(bufinfo_T *bi, pos_T pos) { undo_write_bytes(bi, (long_u)pos.lnum, 4); undo_write_bytes(bi, (long_u)pos.col, 4); -#ifdef FEAT_VIRTUALEDIT undo_write_bytes(bi, (long_u)pos.coladd, 4); -#else - undo_write_bytes(bi, (long_u)0, 4); -#endif } /* @@ -1477,13 +1463,9 @@ unserialize_pos(bufinfo_T *bi, pos_T *pos) pos->col = undo_read_4c(bi); if (pos->col < 0) pos->col = 0; -#ifdef FEAT_VIRTUALEDIT pos->coladd = undo_read_4c(bi); if (pos->coladd < 0) pos->coladd = 0; -#else - (void)undo_read_4c(bi); -#endif } /* @@ -2855,12 +2837,10 @@ u_undoredo(int undo) if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum) { curwin->w_cursor.col = curhead->uh_cursor.col; -#ifdef FEAT_VIRTUALEDIT if (virtual_active() && curhead->uh_cursor_vcol >= 0) coladvance((colnr_T)curhead->uh_cursor_vcol); else curwin->w_cursor.coladd = 0; -#endif } else beginline(BL_SOL | BL_FIX); @@ -2872,9 +2852,7 @@ u_undoredo(int undo) * check_cursor() will move the cursor to the last line. Move it to * the first column here. */ curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif } /* Make sure the cursor is on an existing line and column. */ diff --git a/src/userfunc.c b/src/userfunc.c index 66e07b1f41..aae3fd334f 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -3178,9 +3178,7 @@ ex_call(exarg_T *eap) } curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif } arg = startarg; if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, diff --git a/src/version.c b/src/version.c index af0adc2760..55105221ef 100644 --- a/src/version.c +++ b/src/version.c @@ -695,11 +695,7 @@ static char *(features[]) = "-vartabs", #endif "+vertsplit", -#ifdef FEAT_VIRTUALEDIT "+virtualedit", -#else - "-virtualedit", -#endif "+visual", "+visualextra", #ifdef FEAT_VIMINFO @@ -787,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 826, /**/ 825, /**/ diff --git a/src/vim.h b/src/vim.h index 5bd1b3c940..5a1a59be96 100644 --- a/src/vim.h +++ b/src/vim.h @@ -2136,12 +2136,6 @@ typedef enum { #include "globals.h" /* global variables and messages */ -#ifndef FEAT_VIRTUALEDIT -# define getvvcol(w, p, s, c, e) getvcol((w), (p), (s), (c), (e)) -# define virtual_active() FALSE -# define virtual_op FALSE -#endif - /* * If console dialog not supported, but GUI dialog is, use the GUI one. */ diff --git a/src/window.c b/src/window.c index 58a21e8cab..d89f3a8e6e 100644 --- a/src/window.c +++ b/src/window.c @@ -3439,9 +3439,7 @@ win_init_empty(win_T *wp) wp->w_lines_valid = 0; wp->w_cursor.lnum = 1; wp->w_curswant = wp->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT wp->w_cursor.coladd = 0; -#endif wp->w_pcmark.lnum = 1; /* pcmark not cleared but set to line 1 */ wp->w_pcmark.col = 0; wp->w_prev_pcmark.lnum = 0; @@ -4418,10 +4416,8 @@ win_enter_ext( curwin = wp; curbuf = wp->w_buffer; check_cursor(); -#ifdef FEAT_VIRTUALEDIT if (!virtual_active()) curwin->w_cursor.coladd = 0; -#endif changed_line_abv_curs(); /* assume cursor position needs updating */ if (curwin->w_localdir != NULL) From 8e59a1e127de38ef311f5064b41d201228703883 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 17:36:51 +0100 Subject: [PATCH 05/26] patch 8.1.0827: missing dependency in Makefile Problem: Missing dependency in Makefile. Solution: Add dependency from autocmd.o on auto/osdef.h --- src/Makefile | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 2c409f0a62..3f54184564 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3383,7 +3383,7 @@ objects/arabic.o: arabic.c vim.h protodef.h auto/config.h feature.h os_unix.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h farsi.h arabic.h objects/autocmd.o: autocmd.c vim.h protodef.h auto/config.h feature.h \ - os_unix.h os_mac.h ascii.h keymap.h term.h macros.h option.h beval.h \ + auto/osdef.h os_unix.h os_mac.h ascii.h keymap.h term.h macros.h option.h beval.h \ structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h proto.h globals.h \ farsi.h arabic.h objects/beval.o: beval.c vim.h protodef.h auto/config.h feature.h os_unix.h \ diff --git a/src/version.c b/src/version.c index 55105221ef..39a4f8f844 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 827, /**/ 826, /**/ From 2a953fcf107d24229fec8af820ee62c908caafbf Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 17:41:47 +0100 Subject: [PATCH 06/26] Updated runtime files. --- runtime/doc/autocmd.txt | 3 +- runtime/doc/os_vms.txt | 4 +- runtime/doc/spell.txt | 17 +- runtime/doc/tags | 6 + runtime/doc/term.txt | 10 +- runtime/doc/todo.txt | 53 +- runtime/filetype.vim | 2 +- runtime/ftplugin/man.vim | 6 +- runtime/ftplugin/mma.vim | 16 + runtime/spell/README.txt | 24 +- runtime/spell/de/de_19.diff | 8 +- runtime/spell/de/de_20.diff | 1067 ++++++++++++++++++----------------- runtime/spell/de/de_AT.diff | 1055 +++++++++++++++++----------------- runtime/spell/de/de_CH.diff | 1036 ++++++++++++++++++---------------- runtime/spell/de/de_DE.diff | 1067 ++++++++++++++++++----------------- runtime/spell/de/main.aap | 174 ++---- runtime/spell/fixdup.vim | 3 + 17 files changed, 2375 insertions(+), 2176 deletions(-) create mode 100644 runtime/ftplugin/mma.vim diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index b78cddfef1..087e31a1f5 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -1,4 +1,4 @@ -*autocmd.txt* For Vim version 8.1. Last change: 2019 Jan 11 +*autocmd.txt* For Vim version 8.1. Last change: 2019 Jan 19 VIM REFERENCE MANUAL by Bram Moolenaar @@ -311,6 +311,7 @@ Name triggered by ~ |FuncUndefined| a user function is used but it isn't defined |SpellFileMissing| a spell file is used but it can't be found |SourcePre| before sourcing a Vim script +|SourcePost| after sourcing a Vim script |SourceCmd| before sourcing a Vim script |Cmd-event| |VimResized| after the Vim window size changed diff --git a/runtime/doc/os_vms.txt b/runtime/doc/os_vms.txt index 54b07ac48d..2e2f852845 100644 --- a/runtime/doc/os_vms.txt +++ b/runtime/doc/os_vms.txt @@ -1,4 +1,4 @@ -*os_vms.txt* For Vim version 8.1. Last change: 2019 Jan 18 +*os_vms.txt* For Vim version 8.1. Last change: 2019 Jan 19 VIM REFERENCE MANUAL @@ -104,7 +104,7 @@ to set up GUI fonts etc. correctly. See :help xim from Vim command prompt. You may want to use GUI with GTK icons, then you have to download and install GTK for OpenVMS or at least runtime shareable images - LIBGTK from polarhome.com -Post 7.2 Vim uses GTK2+ while the last GTK on OpenVMS is 1.2.10, thefore +Post 7.2 Vim uses GTK2+ while the last GTK on OpenVMS is 1.2.10, therefore the GTK build is no longer available. For more advanced questions, please send your problem to Vim on VMS mailing diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt index 18db324b81..cee9e0127a 100644 --- a/runtime/doc/spell.txt +++ b/runtime/doc/spell.txt @@ -1,4 +1,4 @@ -*spell.txt* For Vim version 8.1. Last change: 2019 Jan 09 +*spell.txt* For Vim version 8.1. Last change: 2019 Jan 19 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1582,6 +1582,10 @@ CHECKCOMPOUNDTRIPLE (Hunspell) *spell-CHECKCOMPOUNDTRIPLE* Forbid three identical characters when compounding. Not supported. +CHECKSHARPS (Hunspell)) *spell-CHECKSHARPS* + SS letter pair in uppercased (German) words may be upper case + sharp s (ß). Not supported. + COMPLEXPREFIXES (Hunspell) *spell-COMPLEXPREFIXES* Enables using two prefixes. Not supported. @@ -1595,12 +1599,21 @@ COMPOUNDFIRST (Hunspell) *spell-COMPOUNDFIRST* Use COMPOUNDRULE instead. |spell-COMPOUNDRULE| COMPOUNDBEGIN (Hunspell) *spell-COMPOUNDBEGIN* + Words signed with COMPOUNDBEGIN may be first elements in + compound words. + Use COMPOUNDRULE instead. |spell-COMPOUNDRULE| + +COMPOUNDLAST (Hunspell) *spell-COMPOUNDLAST* + Words signed with COMPOUNDLAST may be last elements in + compound words. Use COMPOUNDRULE instead. |spell-COMPOUNDRULE| COMPOUNDEND (Hunspell) *spell-COMPOUNDEND* - Use COMPOUNDRULE instead. |spell-COMPOUNDRULE| + Probably the same as COMPOUNDLAST COMPOUNDMIDDLE (Hunspell) *spell-COMPOUNDMIDDLE* + Words signed with COMPOUNDMIDDLE may be middle elements in + compound words. Use COMPOUNDRULE instead. |spell-COMPOUNDRULE| COMPOUNDRULES (Hunspell) *spell-COMPOUNDRULES* diff --git a/runtime/doc/tags b/runtime/doc/tags index a090a24230..4cc2fa7b69 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -4592,7 +4592,10 @@ E892 eval.txt /*E892* E893 eval.txt /*E893* E894 eval.txt /*E894* E895 if_mzsch.txt /*E895* +E896 eval.txt /*E896* +E897 eval.txt /*E897* E898 channel.txt /*E898* +E899 eval.txt /*E899* E90 message.txt /*E90* E901 channel.txt /*E901* E902 channel.txt /*E902* @@ -4680,6 +4683,7 @@ E977 eval.txt /*E977* E978 eval.txt /*E978* E979 eval.txt /*E979* E98 diff.txt /*E98* +E980 eval.txt /*E980* E99 diff.txt /*E99* EX intro.txt /*EX* EXINIT starting.txt /*EXINIT* @@ -8562,6 +8566,7 @@ spell-CHECKCOMPOUNDDUP spell.txt /*spell-CHECKCOMPOUNDDUP* spell-CHECKCOMPOUNDPATTERN spell.txt /*spell-CHECKCOMPOUNDPATTERN* spell-CHECKCOMPOUNDREP spell.txt /*spell-CHECKCOMPOUNDREP* spell-CHECKCOMPOUNDTRIPLE spell.txt /*spell-CHECKCOMPOUNDTRIPLE* +spell-CHECKSHARPS spell.txt /*spell-CHECKSHARPS* spell-CIRCUMFIX spell.txt /*spell-CIRCUMFIX* spell-COMMON spell.txt /*spell-COMMON* spell-COMPLEXPREFIXES spell.txt /*spell-COMPLEXPREFIXES* @@ -8571,6 +8576,7 @@ spell-COMPOUNDEND spell.txt /*spell-COMPOUNDEND* spell-COMPOUNDFIRST spell.txt /*spell-COMPOUNDFIRST* spell-COMPOUNDFLAG spell.txt /*spell-COMPOUNDFLAG* spell-COMPOUNDFORBIDFLAG spell.txt /*spell-COMPOUNDFORBIDFLAG* +spell-COMPOUNDLAST spell.txt /*spell-COMPOUNDLAST* spell-COMPOUNDMIDDLE spell.txt /*spell-COMPOUNDMIDDLE* spell-COMPOUNDMIN spell.txt /*spell-COMPOUNDMIN* spell-COMPOUNDPERMITFLAG spell.txt /*spell-COMPOUNDPERMITFLAG* diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt index 4ade4a131c..024b7a7cd3 100644 --- a/runtime/doc/term.txt +++ b/runtime/doc/term.txt @@ -1,4 +1,4 @@ -*term.txt* For Vim version 8.1. Last change: 2017 Oct 14 +*term.txt* For Vim version 8.1. Last change: 2019 Jan 19 VIM REFERENCE MANUAL by Bram Moolenaar @@ -334,11 +334,15 @@ Added by Vim (there are no standard codes for these): t_EI end insert or replace mode (block cursor shape) *t_EI* *'t_EI'* |termcap-cursor-shape| t_RV request terminal version string (for xterm) *t_RV* *'t_RV'* - |xterm-8bit| |v:termresponse| |'ttymouse'| |xterm-codes| + The response is stored in |v:termresponse| + |xterm-8bit| |'ttymouse'| |xterm-codes| t_u7 request cursor position (for xterm) *t_u7* *'t_u7'* see |'ambiwidth'| + The response is stored in |v:termu7resp| t_RF request terminal foreground color *t_RF* *'t_RF'* + The response is stored in |v:termrfgresp| t_RB request terminal background color *t_RB* *'t_RB'* + The response is stored in |v:termrbgresp| t_8f set foreground color (R, G, B) *t_8f* *'t_8f'* |xterm-true-color| t_8b set background color (R, G, B) *t_8b* *'t_8b'* @@ -351,7 +355,9 @@ Added by Vim (there are no standard codes for these): t_EC set cursor color end *t_EC* *'t_EC'* t_SH set cursor shape *t_SH* *'t_SH'* t_RC request terminal cursor blinking *t_RC* *'t_RC'* + The response is stored in |v:termblinkresp| t_RS request terminal cursor style *t_RS* *'t_RS'* + The response is stored in |v:termstyleresp| t_ST save window title to stack *t_ST* *'t_ST'* t_RT restore window title from stack *t_RT* *'t_RT'* t_Si save icon text to stack *t_Si* *'t_Si'* diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 5437298880..95fdfeb924 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 8.1. Last change: 2019 Jan 17 +*todo.txt* For Vim version 8.1. Last change: 2019 Jan 26 VIM REFERENCE MANUAL by Bram Moolenaar @@ -38,15 +38,9 @@ browser use: https://github.com/vim/vim/issues/1234 *known-bugs* -------------------- Known bugs and current work ----------------------- -Blob: the string form can't be parsed back. Use 0z00112233.44556677 ? - -Make msg() and msg_attr() also use "char *" intead of "char_u *"? - -Feature to possibly graduate: FEAT_MBYTE - Integrate EBCDIC feature, use 'encoding' == "ebcdic" ? - Or drop EBCDIC? - 'incsearch' with :s: (#3321) +- Get E20 when using command history to get "'<,'>s/a/b" and no Visual area + was set. (#3837) - :s/foo using CTRL-G moves to another line, should not happen, or use the correct line (it uses the last but one line) (Lifepillar, Aug 18, #3345) - :s@pat/tern@ doesn't include "/" in the pattern. (Takahiro Yoshihara, #3637) @@ -109,18 +103,10 @@ Terminal emulator window: - When 'encoding' is not utf-8, or the job is using another encoding, setup conversions. -Patch with updates for VMS. (Zoltan Arpadffy, 2019 Jan 14) - -Update for German spell files: https://github.com/chrisbra/vim/compare/5e021c990f8817a50d3264782a5...3b27c92f297540761ebbd92d04fb3 -(Christian Brabandt, 2018 Nov 4) - Problem with Visual yank when 'linebreak' and 'showbreak' are set. Patch with tests, but it's not clear how it is supposed to work. (tommm, 2018 Nov 17) Asked about this, Dec 22. Christian will have a look. -Patch to deal with signs at the end of the buffer when lines are deleted. -(Yegappan Lakshmanan, #3798) - Key mapping times out when using a timer in Gvim. (Michael Henry, 2018 Sep 9, #3417) Another report, with reproduction steps. (#3799) @@ -130,13 +116,20 @@ Does not build with MinGW out of the box: - _stat64 is not defined, need to use "struct stat" in vim.h - WINVER conflict, should use 0x0600 by default? -Patch to remove flicker from popup menu. (Yasuhiro Matsumoto, 2013 Aug 15) -When redrawing for updating the popup menu, don't redraw the part when the new -popup menu will be displayed? - js_decode() does not handle infinity properly. (Dominique Pelle, 2019 Jan 10, #3788) +Patch to avoid skipping buffers when loading a session. (Jason Franklin, 2019 +Jan 20) + +Patch to update example of how to restore the cursor. (Ken Takata, 2019 Jan +21) + +Patch to fix problems with timer in GUI. (Ozaki Kiichi, #3817) +Should also fix #3824. +Change the order in which GUI handles events? Make it work like os_unix.c, +check timer on lower level, check for pending messages higher up. + Signs: - screen not redrawn correctly. (Dominique Pelle, 2019 Jan 14, #3803) - Use a sign group in the Termdebug plugin. @@ -146,9 +139,9 @@ Signs: Crash when mixing matchadd and substitute()? (Max Christian Pohle, 2018 May 13, #2910) Can't reproduce? -Merge checking for 'cursorline' and 'concealcursor', see neovim #9492. +Patch to recognize more systems with has(). (Ozaki Kiichi, #3855) -Patch to not call setActiveWindow. Yasuhiro Matsumoto, 2019 Jan 8, #3778) +Merge checking for 'cursorline' and 'concealcursor', see neovim #9492. Errors found with random data: heap-buffer-overflow in alist_add (#2472) @@ -190,6 +183,9 @@ Patch on #3690 to fix that "wincmd p" does not always behave properly. Patch: When using %v in 'errorformat', assume the number is the screen column not bytes, also handle multi-byte charactes. (Yegappan Lakshmanan, #3700) +Support setting the character displayed below the last line? Neovim uses +"eob:X" in 'fillchars'. + Make balloon_show() work outside of 'balloonexpr'? Users expect it to work: #2948. (related to #1512?) On Win32 it stops showing, because showState is already ShS_SHOWING. @@ -201,8 +197,6 @@ balloonexpr() on MS-Windows GUI doesn't handle accented chars? (nivaemail, 2018 Sep 14) Another request: #3811. -Patch to add FOR_ALL_FRAMES. (Yegappan, 2018 Dec 11, #3686) - Patch for MinGW build with static libraries. (Ken Takata, 2018 Dec 16) Patch to add new regexp classes :ident:, :keyword:, :fname:. @@ -244,9 +238,6 @@ punctiuation is repeated. (Smylers, 2018 Nov 17, #3621) Using CTRL-L during search only picks up the base character, not a combining character. (Rick, 2018 Dec 11, #3682) -":mksession" cannot handle a very long 'runtimepath'. (Timothy Madden, 21 Sep -2018, #3466) Patch from Christian, 2018 Oct 30 (with comments). - ml_get error: (Israel Chauca Fuentes, 2018 Oct 17, #3550). Patch to convert temp file name. (Yasuhiro Matsumoto, #3520) @@ -259,6 +250,9 @@ When 'sidescrolloff' is set, using "zl" to go to the end of the line, suddenly scrolls back. Should allow for this scrolling, like 'scrolloff' does when using CTRL-E. (Yee Cheng Chin, #3721) +Patch to add ":vsbuffer" - vertical split + :sbuffer. (Rob Pilling, 2019 Jan +17, #3816) Do we really need this? + Invalid memory access with old regexp engine. (Dominique Pelle, 2018 Sep 3, #3405) Introduced by 8.0.1517, which was fixing another memory access error. (Sep 8) @@ -967,6 +961,8 @@ sort() is not stable when using numeric/float sort (Nikolay Pavlov, 2016 Sep - When out_cb executes :sleep, the close_cb may be invoked. (Daniel Hahler, 2016 Dec 11, #1320) - Implement |job-term| ? +- Calling a function when receiving a "call" on a channel, using feedkeys() + does not work. It does work from a timer. (Qiming Zhao, #3852) - Channel test fails with Motif. Sometimes kills the X11 server. - When a message in the queue but there is no callback, drop it after a while? Add timestamp to queued messages and callbacks with ID, remove after a @@ -1829,6 +1825,7 @@ cleared. See test64. Patch to make "z=" work when 'spell' is off. Does this have nasty side effects? (Christian Brabandt, 2012 Aug 5, Update 2013 Aug 12) Would also need to do this for spellbadword() and spellsuggest(). +https://github.com/chrisbra/vim-mq-patches/blob/master/enable_spellchecking On 64 bit MS-Windows "long" is only 32 bits, but we sometimes need to store a 64 bits value. Change all number options to use nropt_T and define it to the diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 30ce129182..5a21a1dfb9 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1,7 +1,7 @@ " Vim support file to detect file types " " Maintainer: Bram Moolenaar -" Last Change: 2018 May 04 +" Last Change: 2019 Jan 18 " Listen very carefully, I will say this only once if exists("did_load_filetypes") diff --git a/runtime/ftplugin/man.vim b/runtime/ftplugin/man.vim index dc03211916..87773ed279 100644 --- a/runtime/ftplugin/man.vim +++ b/runtime/ftplugin/man.vim @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: man " Maintainer: SungHyun Nam -" Last Change: 2018 Jul 25 +" Last Change: 2019 Jan 22 " To make the ":Man" command available before editing a manual page, source " this script from your startup vimrc file. @@ -206,10 +206,10 @@ func GetPage(cmdmods, ...) let $MANWIDTH = '' endif " Remove blank lines from top and bottom. - while getline(1) =~ '^\s*$' + while line('$') > 1 && getline(1) =~ '^\s*$' silent keepj norm! ggdd endwhile - while getline('$') =~ '^\s*$' + while line('$') > 1 && getline('$') =~ '^\s*$' silent keepj norm! Gdd endwhile 1 diff --git a/runtime/ftplugin/mma.vim b/runtime/ftplugin/mma.vim new file mode 100644 index 0000000000..ce4cee18ae --- /dev/null +++ b/runtime/ftplugin/mma.vim @@ -0,0 +1,16 @@ +" Vim filetype plugin file +" Language: Mathematica +" Maintainer: Ian Ford +" Last Change: 22 January 2019 + +" Only do this when not done yet for this buffer +if exists("b:did_ftplugin") + finish +endif + +" Don't load another plugin for this buffer +let b:did_ftplugin = 1 + +let b:undo_ftplugin = "setlocal commentstring<" + +setlocal commentstring=\(*%s*\) diff --git a/runtime/spell/README.txt b/runtime/spell/README.txt index d427a3c152..9fc3fd1efb 100644 --- a/runtime/spell/README.txt +++ b/runtime/spell/README.txt @@ -17,10 +17,10 @@ ftp://ftp.gnu.org/gnu/aspell/dict/. Most go under the GPL or LGPL copyright. GENERATING .SPL FILES -This involves downloading the files from the OpenOffice.org server, applying a +This involves downloading the files from the github server, applying a patch and running Vim to generate the .spl file. To do this all in one go use the Aap program (www.a-a-p.org). It's simple to install, it only requires -Python. +Python (http://www.a-a-p.org/download.html) Before generating spell files, verify your system has the required locale support. Source the check_locales.vim script to find out. If something is @@ -29,7 +29,7 @@ missing, see LOCALE below. You can also do it manually: 1. Fetch the right spell file from: - http://ftp.services.openoffice.org/pub/OpenOffice.org/contrib/dictionaries + https://github.com/LibreOffice/dictionaries 2. Unzip the archive: unzip LL_RR.zip @@ -56,12 +56,11 @@ Now you understand why I prefer using the Aap recipe :-). MAINTAINING A LANGUAGE Every language should have a maintainer. His tasks are to track the changes -in the OpenOffice.org spell files and make updated patches. Words that -haven't been added/removed from the OpenOffice lists can also be handled by -the patches. +in the spell files and make updated patches. Words that haven't been +added/removed from the LibreOffice lists can also be handled by the patches. It is important to keep the version of the .dic and .aff files that you -started with. When OpenOffice brings out new versions of these files you can +started with. When LibreOffice brings out new versions of these files you can find out what changed and take over these changes in your patch. When there are very many changes you can do it the other way around: re-apply the changes for Vim to the new versions of the .dic and .aff files. @@ -79,20 +78,25 @@ This procedure should work well: aren't really words, they mess up the suggestions (English has this problem). You can use the "fixdup.vim" Vim script to find duplicate words. -3. Make the diff file. "aap diff" will do this for you. If a diff would be +3. Include needed parts from the aspell phonetic dictionary to the aff files. For + example add the relevant SAL lines to the .aff file (this is needed to make good + suggestions). The aspell dictionaries can be found here: + https://ftp.gnu.org/gnu/aspell/dict/0index.html + +4. Make the diff file. "aap diff" will do this for you. If a diff would be too big you might consider writing a Vim script to do systematic changes. Do check that someone else can reproduce building the spell file. Send the result to Bram for inclusion in the distribution. Bram will generate the .spl file and upload it to the ftp server (if he can't generate it you will have to send him the .spl file too). -4. When OpenOffice makes a new zip file available you need to update the +5. When OpenOffice makes a new zip file available you need to update the patch. "aap check" should do most of the work for you: if there are changes the .new.dic and .new.aff files will appear. You can now figure out the differences with .orig.dic and .orig.aff, adjust the .dic and .aff files and finally move the .new.dic to .orig.dic and .new.aff to .orig.aff. -5. Repeat step 4. regularly. +6. Repeat step 5. regularly. LOCALE diff --git a/runtime/spell/de/de_19.diff b/runtime/spell/de/de_19.diff index 8689840e3d..a2b9fa4408 100644 --- a/runtime/spell/de/de_19.diff +++ b/runtime/spell/de/de_19.diff @@ -1,5 +1,5 @@ -*** de_19.orig.aff Thu Aug 25 11:22:08 2005 ---- de_19.aff Thu Sep 29 11:43:46 2005 +*** de_19.orig.aff 2019-01-19 18:45:26.468520305 +0100 +--- de_19.aff 2019-01-19 18:45:26.472520278 +0100 *************** *** 3,4 **** --- 3,21 ---- @@ -501,8 +501,8 @@ + SAL ZURÜCK^^ ZURIK + SAL ZUVER^^ ZUFA # x + SAL Z Z -*** de_19.orig.dic Thu Aug 25 11:22:08 2005 ---- de_19.dic Sat Jan 7 12:32:09 2006 +*** de_19.orig.dic 2019-01-19 18:45:26.468520305 +0100 +--- de_19.dic 2019-01-19 18:45:26.476520252 +0100 *************** *** 76258,76259 **** zynismusfördernd/A diff --git a/runtime/spell/de/de_20.diff b/runtime/spell/de/de_20.diff index 73141b6216..bbac7a0b64 100644 --- a/runtime/spell/de/de_20.diff +++ b/runtime/spell/de/de_20.diff @@ -1,10 +1,9 @@ -*** de_20.orig.aff Sat Nov 26 19:59:52 2005 ---- de_20.aff Sat Nov 26 20:13:50 2005 +*** de_DE.orig.aff 2019-01-19 18:45:26.132522538 +0100 +--- de_DE.aff 2019-01-19 19:23:37.233297530 +0100 *************** -*** 2,3 **** ---- 2,21 ---- - TRY esianrtolcdugmphbyfvkwäüößáéêàâñESIANRTOLCDUGMPHBYFVKWÄÜÖ -+ +*** 15,16 **** +--- 15,46 ---- + + FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ + LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ + UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ @@ -22,512 +21,560 @@ + MAP yÿý + MAP sß + - # ++ COMPOUNDRULE xy?z ++ #COMPOUNDBEGIN x ++ #COMPOUNDMIDDLE y ++ #COMPOUNDEND z ++ ++ # Prefixes are allowed at the beginning of compounds, ++ # suffixes are allowed at the end of compounds by default: ++ # (prefix)?(root)+(affix)? ++ # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. ++ COMPOUNDPERMITFLAG c ++ ++ ONLYINCOMPOUND o ++ + PFX U Y 1 *************** -*** 28,31 **** - PFX V Y 1 -! PFX V 0 ver . -! - ---- 46,49 ---- - PFX V Y 1 -! PFX V 0 ver . +*** 536,553 **** + #LANG de_DE +! CHECKSHARPS ! +- COMPOUNDBEGIN x +- COMPOUNDMIDDLE y +- COMPOUNDEND z + FORBIDDENWORD d + +- # Prefixes are allowed at the beginning of compounds, +- # suffixes are allowed at the end of compounds by default: +- # (prefix)?(root)+(affix)? +- # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. +- COMPOUNDPERMITFLAG c +- +- ONLYINCOMPOUND o +- + # my PSEUDOROOT h(elper) flag +--- 566,571 ---- + #LANG de_DE +! # CHECKSHARPS + + FORBIDDENWORD d + + # my PSEUDOROOT h(elper) flag *************** -*** 235,237 **** - SFX F arzt ärztin arzt -! SFX F arzt Ärztinnen arzt - SFX F Arzt Ärztin Arzt ---- 253,255 ---- - SFX F arzt ärztin arzt -! SFX F arzt ärztinnen arzt - SFX F Arzt Ärztin Arzt +*** 571,573 **** + +! WORDCHARS ß-. + +--- 589,591 ---- + +! # WORDCHARS ß-. + *************** -*** 1410 **** ---- 1428,1904 ---- - REP ö öe -+ -+ # German phonetic transformation rules from Aspell -+ # Copyright (C) 2000 Björn Jacke, distributed under LGPL. -+ # Björn Jacke may be reached by email at bjoern.jacke@gmx.de -+ # Last changed 2000-01-07 -+ -+ SAL followup 1 -+ SAL collapse_result 1 -+ -+ SAL ÄER- E -+ SAL ÄU< EU -+ SAL Ä< E -+ SAL É E -+ SAL ÖER- Ö -+ SAL Ö Ö -+ SAL ÜBER^^ IPA -+ SAL ÜER- I -+ SAL Ü I -+ SAL ß Z -+ SAL ABELLE$ APL -+ SAL ABELL$ APL -+ SAL ABIENNE$ APIN -+ SAL ACEY$ AZI -+ SAL AEU< EU -+ SAL AE2 E -+ SAL AGNI-^ AKN -+ SAL AGNIE- ANI -+ SAL AGN(AEOU)-$ ANI -+ SAL AIA2 AIA -+ SAL AIE$ E -+ SAL AILL(EOU)- ALI -+ SAL AINE$ EN -+ SAL AIRE$ ER -+ SAL AIR- E -+ SAL AISE$ EZ -+ SAL AISSANCE$ EZANZ -+ SAL AISSE$ EZ -+ SAL AIX$ EX -+ SAL AJ(AÄEIOÖUÜ)-- A -+ SAL AKTIE AXIE -+ SAL ALO(IY)^ ALUI -+ SAL AMATEU(RS)- ANATÖ -+ SAL ANIELLE$ ANIL -+ SAL ANTI^^ ANTI -+ SAL ANVER^^ ANFA -+ SAL ATIA$ ATIA -+ SAL ATIA(NS)-- ATI -+ SAL ATI(AÄOÖUÜ)- AZI -+ SAL AUAU-- _ -+ SAL AUER< AUA -+ SAL AUF^^ AUF -+ SAL AULT$ U -+ SAL AUSSE$ UZ -+ SAL AUS(ST)-^ AUZ -+ SAL AUS^^ AUZ -+ SAL AUTO^^ AUTU -+ SAL AUX(IY)- AUX -+ SAL AUX U -+ SAL AU AU -+ SAL AVIER$ AFIE -+ SAL AYER--< EI -+ SAL AY(AÄEIOÖUÜ)-- A -+ SAL A(IJY)< EI -+ SAL A A -+ SAL BEA(BCMNRU)-^ PEA -+ SAL BEAT(AEIMORU)-^ PEAT -+ SAL BEIGE^$ PEZ -+ SAL BE(LMNRST)-^ PE -+ SAL BETTE$ PET -+ SAL BIC$ PIZ -+ SAL BOWL(EI)- PUL -+ SAL BP(AÄEIOÖRUÜY)- P -+ SAL BUDGET7 PIKE -+ SAL BUFFET7 PIFE -+ SAL BYLLE$ PILE -+ SAL BYLL$ PIL -+ SAL BYTE< PEIT -+ SAL B P -+ SAL CÄ- Z -+ SAL CÜ$ ZI -+ SAL CACH(EI)-^ KEZ -+ SAL CAE-- Z -+ SAL CA(IY)$ ZEI -+ SAL CCH Z -+ SAL CCE- X -+ SAL CE(EIJUY)-- Z -+ SAL CENT< ZENT -+ SAL CERST(EI)----^ KE -+ SAL CER$ ZA -+ SAL CE3 ZE -+ SAL CHAO(ST)- KAU -+ SAL CHAMPIO-^ ZENPI -+ SAL CHAR(AI)-^ KAR -+ SAL CHAU(CDFSVWXZ)- ZU -+ SAL CHE(CF)- ZE -+ SAL CHEM-^ KE -+ SAL CHEQUE< ZEK -+ SAL CHI(CFGPVW)- ZI -+ SAL CH(AEUY)-<^ Z -+ SAL CHK- _ -+ SAL CH(LOR)-<^ K -+ SAL CHST- X -+ SAL CH(SßXZ)3 X -+ SAL CH K -+ SAL CIER$ ZIE -+ SAL CYB-^ ZEI -+ SAL CY9^ ZI -+ SAL C(IJY)-3 Z -+ SAL CKST XT -+ SAL CK(SßXZ)3 X -+ SAL C(CK)- _ -+ SAL CLAUDET--- KLU -+ SAL CLAUDINE^$ KLUTIN -+ SAL COLE$ KUL -+ SAL COUCH KAUZ -+ SAL CQUES$ K -+ SAL CQUE K -+ SAL CREAT-^ KREA -+ SAL CST XT -+ SAL CS<^ Z -+ SAL C(SßX) X -+ SAL CT(SßXZ) X -+ SAL CZ< Z -+ SAL C< K -+ SAL D'H^ T -+ SAL D'S3$ Z -+ SAL DAVO(NR)-^$ TAFU -+ SAL DD(SZ)--< _ -+ SAL DEPOT7 TEPU -+ SAL DESIGN TIZEIN -+ SAL DE(LMNRST)-3^ TE -+ SAL DETTE$ TET -+ SAL DIC$ TIZ -+ SAL DJ(AEIOU)-^ I -+ SAL DS(CH)--< T -+ SAL DST ZT -+ SAL DT- _ -+ SAL DUIS-^ TI -+ SAL DURCH^^ TURK -+ SAL DZS(CH)-- T -+ SAL D(SßZ) Z -+ SAL D T -+ SAL EAULT$ U -+ SAL EAUX$ U -+ SAL EAU U -+ SAL EAV IF -+ SAL EA(AÄEIOÖÜY)-3 EA -+ SAL EA3$ EA -+ SAL EA3 I -+ SAL EBEN^^ EPN -+ SAL EE9 E -+ SAL EIEI-- _ -+ SAL EIH-- E -+ SAL EILLE$ EI -+ SAL EI EI -+ SAL EJ$ EI -+ SAL EL-^ E -+ SAL EL(DKL)--1 E -+ SAL EL(MNT)--1$ E -+ SAL ELYNE$ ELINE -+ SAL ELYN$ ELIN -+ SAL EL(AÄEIOÖUÜY)-1 EL -+ SAL EL-1 L -+ SAL EM-^ E -+ SAL EM(DFKMPQT)--1 E -+ SAL EM(AÄEIOÖUÜY)--1 E -+ SAL EM-1 N -+ SAL EN-^ E -+ SAL EN(CDGKQT)--1 E -+ SAL ENZ(AEIOUY)--1 EN -+ SAL EN(AÄEINOÖUÜY)-1 EN -+ SAL EN-<1 N -+ SAL ERH(AÄEIOÖUÜ)-^ ER -+ SAL ER-^ E -+ SAL ER(AÄEIOÖUÜY)-1 A -+ SAL ER1$ A -+ SAL ER<1 A -+ SAL ETI(AÄOÖÜU)- EZI -+ SAL EUEU-- _ -+ SAL EUILLE$ Ö -+ SAL EUR$ ÖR -+ SAL EUX Ö -+ SAL EUYS$ EUZ -+ SAL EU EU -+ SAL EYER< EIA -+ SAL EY< EI -+ SAL E E -+ SAL FANS--^$ FE -+ SAL FAN-^$ FE -+ SAL FAULT- FUL -+ SAL FEE(DL)- FI -+ SAL FEHLER FELA -+ SAL FE(LMNRST)-3^ FE -+ SAL FOND7 FUN -+ SAL FRAIN$ FRA -+ SAL FRISEU(RS)- FRIZÖ # x -+ SAL F F -+ SAL G'S$ X -+ SAL GAGS^$ KEX -+ SAL GAG^$ KEK -+ SAL GD KT -+ SAL GEGEN^^ KEKN -+ SAL GE(LMNRST)-3^ KE -+ SAL GETTE$ KET -+ SAL G(CK)- _ -+ SAL GG- _ -+ SAL GI(AO)-^ I -+ SAL GION$ KIUN -+ SAL GIUS-^ IU -+ SAL GMBH^$ GMPH -+ SAL GNAC$ NIAK -+ SAL GNON$ NIUN -+ SAL GN$ N -+ SAL GONCAL-^ KUNZA -+ SAL GS(CH)-- K -+ SAL GST XT -+ SAL G(SßXZ) X -+ SAL GUCK- KU -+ SAL GUI-^ K -+ SAL G K -+ SAL HEAD- E -+ SAL HE(LMNRST)-3^ E -+ SAL HE(LMN)-1 E -+ SAL HEUR1$ ÖR -+ SAL H^ _ -+ SAL IEC$ IZ -+ SAL IEI-3 _ -+ SAL IELL3 IEL -+ SAL IENNE$ IN -+ SAL IERRE$ IER -+ SAL IETTE$ IT -+ SAL IEU IÖ -+ SAL IE<4 I -+ SAL IGHT3$ EIT -+ SAL IGNI(EO)- INI -+ SAL IGN(AEOU)-$ INI -+ SAL IJ(AOU)- I -+ SAL IJ$ I -+ SAL IJ< EI -+ SAL IKOLE$ IKUL -+ SAL ILLAN(STZ)-- ILIA -+ SAL ILLAR(DT)-- ILIA -+ SAL INVER- INFE -+ SAL ITI(AÄOÖUÜ)- IZI -+ SAL IVIER$ IFIE -+ SAL I I -+ SAL JAVIE---<^ ZA -+ SAL JEAN^$ IA -+ SAL JEAN-^ IA -+ SAL JER-^ IE -+ SAL JE(LMNST)- IE -+ SAL JOR(GK)^$ IÖRK -+ SAL J I -+ SAL KC(ÄEIJ)- X -+ SAL KE(LMNRST)-3^ KE -+ SAL KH<^ K -+ SAL KIC$ KIZ -+ SAL KLE(LMNRST)-3^ KLE -+ SAL KOTELE-^ KUTL -+ SAL KREAT-^ KREA -+ SAL KST XT -+ SAL K(SßXZ) X -+ SAL KTI(AIOU)-3 XI -+ SAL KT(SßXZ) X -+ SAL K K -+ SAL LARVE- LARF -+ SAL LEAND-^ LEAN -+ SAL LEL- LE -+ SAL LE(MNRST)-3^ LE -+ SAL LETTE$ LET -+ SAL LFGNAG- LFKAN -+ SAL LIC$ LIZ -+ SAL LIVE^$ LEIF -+ SAL LUI(GS)-- LU -+ SAL L L -+ SAL MASSEU(RS)- NAZÖ -+ SAL MAURICE NURIZ -+ SAL MBH^$ MPH -+ SAL MB(SßZ)- N -+ SAL MC9^ NK -+ SAL MEMOIR-^ NENUA -+ SAL ME(LMNRST)-3^ NE -+ SAL MIGUEL NIKL -+ SAL MIKE^$ NEIK -+ SAL MN N -+ SAL MPJUTE- NPUT -+ SAL MP(SßZ)- N -+ SAL MP(BDJLMNPQRTVW)- NP -+ SAL M N -+ SAL NACH^^ NAK -+ SAL NADINE NATIN -+ SAL NAIV-- NA -+ SAL NAISE$ NEZE -+ SAL NCOISE$ ZUA -+ SAL NCOIS$ ZUA -+ SAL NEBEN^^ NEPN -+ SAL NE(LMNRST)-3^ NE -+ SAL NEN-3 NE -+ SAL NETTE$ NET -+ SAL NG(BDFJLMNPQRTVW)- NK -+ SAL NICHTS^^ NIX -+ SAL NICHT^^ NIKT -+ SAL NINE$ NIN -+ SAL NON^^ NUN -+ SAL NOT^^ NUT -+ SAL NTI(AIOU)-3 NZI -+ SAL NTIEL--3 NZI -+ SAL NYLON NEILUN -+ SAL ND(SßZ)$ NZ -+ SAL NT(SßZ)$ NZ -+ SAL ND'S$ NZ -+ SAL NT'S$ NZ -+ SAL NSTS$ NZ -+ SAL N N -+ SAL OBER^^ UPA -+ SAL OE2 Ö -+ SAL OGNIE- UNI -+ SAL OGN(AEOU)-$ UNI -+ SAL OIE$ Ö -+ SAL OIR$ UAR -+ SAL OIX UA -+ SAL OI<3 EU -+ SAL OJ(AÄEIOÖUÜ)-- U -+ SAL OKAY^$ UKE -+ SAL OLYN$ ULIN -+ SAL OTI(AÄOÖUÜ)- UZI -+ SAL OUI^ FI -+ SAL OUILLE$ ULIE -+ SAL OU(DT)-^ AU -+ SAL OUSE$ AUZ -+ SAL OUT- AU -+ SAL OU U -+ SAL OWS$ UZ -+ SAL OY(AÄEIOÖUÜ)-- U -+ SAL O(JY)< EU -+ SAL O U -+ SAL PATIEN--^ PAZI -+ SAL PENSIO-^ PANZI -+ SAL PE(LMNRST)-3^ PE -+ SAL PFER-^ FE -+ SAL P(FH)< F -+ SAL POLY^^ PULI -+ SAL PORTRAIT7 PURTRE -+ SAL PP(FH)--< P -+ SAL PP- _ -+ SAL PRIX^$ PRI -+ SAL P(SßZ)^ Z -+ SAL PTI(AÄOÖUÜ)-3 PZI -+ SAL PIC^$ PIK -+ SAL P P -+ SAL QUE(LMNRST)-3 KFE -+ SAL QUE$ K -+ SAL QUI(NS)$ KI -+ SAL QU KF -+ SAL Q< K -+ SAL RCH RK -+ SAL RECHERCH^ REZAZ -+ SAL RER$ RA -+ SAL RE(MNR)-4 RE -+ SAL RETTE$ RET -+ SAL RH<^ R -+ SAL RJA(MN)-- RI -+ SAL RTI(AÄOÖUÜ)-3 RZI -+ SAL RY(KN)-$ RI -+ SAL R R -+ SAL SAFE^$ ZEIF -+ SAL SAUCE-^ ZUZ -+ SAL SCHSCH---7 _ -+ SAL SCHTSCH Z -+ SAL SC(HZ)< Z -+ SAL SC ZK -+ SAL SELBSTST--7^^ ZELP -+ SAL SELBST7^^ ZELPZT -+ SAL SERVICE7^ ZÖRFIZ -+ SAL SE(LMNRST)-3^ ZE -+ SAL SETTE$ ZET -+ SAL SHP-^ Z -+ SAL SHST ZT -+ SAL SHTSH Z -+ SAL SHT Z -+ SAL SH3 Z -+ SAL SIEGLI-^ ZIKL -+ SAL SIGLI-^ ZIKL -+ SAL SIGHT ZEIT -+ SAL SIGN ZEIN -+ SAL SKI(NPZ)- ZKI -+ SAL SKI<^ ZI -+ SAL SOUND- ZAUN -+ SAL STAATS^^ ZTAZ -+ SAL STADT^^ ZTAT -+ SAL START^^ ZTART -+ SAL STAURANT7 ZTURAN -+ SAL STEAK- ZTE -+ SAL STRAF^^ ZTRAF -+ SAL ST'S$ Z -+ SAL STST-- _ -+ SAL STS(ACEHIOUÄÜÖ)-- ZT -+ SAL ST(SZ) Z -+ SAL STYN(AE)-$ ZTIN -+ SAL ST ZT -+ SAL SZE(NPT)-^ ZE -+ SAL SZI(ELN)-^ ZI -+ SAL SZCZ< Z -+ SAL SZT< ZT -+ SAL SZ<3 Z -+ SAL S Z -+ SAL T'S3$ Z -+ SAL TCH Z -+ SAL TEAT-^ TEA -+ SAL TE(LMNRST)-3^ TE -+ SAL TH< T -+ SAL TIC$ TIZ -+ SAL TOAS-^ TU -+ SAL TOILET- TULE -+ SAL TOIN- TUA -+ SAL TRAINI- TREN -+ SAL TSCH Z -+ SAL TSH Z -+ SAL TST ZT -+ SAL T(Sß) Z -+ SAL TT(SZ)--< _ -+ SAL TT9 T -+ SAL TZ- _ -+ SAL T T -+ SAL UEBER^^ IPA -+ SAL UE2 I -+ SAL UIE$ I -+ SAL UM^^ UN -+ SAL UNTERE-- UNTE -+ SAL UNTER^^ UNTA -+ SAL UNVER^^ UNFA -+ SAL UN^^ UN -+ SAL UTI(AÄOÖUÜ)- UZI -+ SAL U U -+ SAL VACL-^ FAZ -+ SAL VAC$ FAZ -+ SAL VEDD-^ FE -+ SAL VEREIN FAEIN -+ SAL VERSEN^ FAZN -+ SAL VER^^ FA -+ SAL VER FA -+ SAL VET(HT)-^ FET -+ SAL VETTE$ FET -+ SAL VIC$ FIZ -+ SAL VIEL FIL -+ SAL VIEW FIU -+ SAL VOR^^ FUR -+ SAL VY9^ FI -+ SAL V< F -+ SAL WE(LMNRST)-3^ FE -+ SAL WIC$ FIZ -+ SAL WIEDER^^ FITA -+ SAL WY9^ FI -+ SAL W F -+ SAL XE(LMNRST)-3^ XE -+ SAL X<^ Z -+ SAL X(CSZ) X -+ SAL XTS(CH)-- XT -+ SAL XT(SZ) Z -+ SAL X X -+ SAL YE(LMNRST)-3^ IE -+ SAL YE-3 I -+ SAL YOR(GK)^$ IÖRK -+ SAL Y(AOU)-<7 I -+ SAL YVES^$ IF -+ SAL YVONNE^$ IFUN -+ SAL Y I -+ SAL ZC(AOU)- ZK -+ SAL ZE(LMNRST)-3^ ZE -+ SAL ZH< Z -+ SAL ZS(CHT)-- _ -+ SAL ZS Z -+ SAL ZUERST ZUERZT -+ SAL ZURÜCK^^ ZURIK -+ SAL ZUVER^^ ZUFA # x -+ SAL Z Z -*** de_20.orig.dic Sat Nov 26 19:59:53 2005 ---- de_20.dic Mon Jan 2 20:19:18 2006 -*************** -*** 1,3 **** - 314626 -- 23394 - A-Bombe/N ---- 1,2 ---- +*** 725,729 **** + # So enabling this is the lesser evil. No perfect solution found so far... +! BREAK 2 +! BREAK - +! BREAK . +! +--- 743,1241 ---- + # So enabling this is the lesser evil. No perfect solution found so far... +! # BREAK 2 +! # BREAK - +! # BREAK . +! +! # German phonetic transformation rules for use with Aspell +! # Copyright (C) 2000 Björn Jacke +! # +! # This library is free software; you can redistribute it and/or +! # modify it under the terms of the GNU Lesser General Public +! # License version 2.1 as published by the Free Software Foundation; +! # +! # This library is distributed in the hope that it will be useful, +! # but WITHOUT ANY WARRANTY; without even the implied warranty of +! # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +! # Lesser General Public License for more details. +! # +! # You should have received a copy of the GNU Lesser General Public +! # License along with this library; if not, write to the Free Software +! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +! # +! # Björn Jacke may be reached by email at bjoern.jacke@gmx.de +! # +! # Changelog: +! # +! # 2000-01-05 Björn Jacke +! # Initial Release +! # 2000-01-07 Kevin Atkinson +! # Converted from header to data file. +! SAL followup 1 +! SAL collapse_result 1 +! +! SAL ÄER- E +! SAL ÄU< EU +! SAL Ä< E +! SAL É E +! SAL ÖER- Ö +! SAL Ö Ö +! SAL ÜBER^^ IPA +! SAL ÜER- I +! SAL Ü I +! SAL ß Z +! SAL ABELLE$ APL +! SAL ABELL$ APL +! SAL ABIENNE$ APIN +! SAL ACEY$ AZI +! SAL AEU< EU +! SAL AE2 E +! SAL AGNI-^ AKN +! SAL AGNIE- ANI +! SAL AGN(AEOU)-$ ANI +! SAL AIA2 AIA +! SAL AIE$ E +! SAL AILL(EOU)- ALI +! SAL AINE$ EN +! SAL AIRE$ ER +! SAL AIR- E +! SAL AISE$ EZ +! SAL AISSANCE$ EZANZ +! SAL AISSE$ EZ +! SAL AIX$ EX +! SAL AJ(AÄEIOÖUÜ)-- A +! SAL AKTIE AXIE +! SAL ALO(IY)^ ALUI +! SAL AMATEU(RS)- ANATÖ +! SAL ANIELLE$ ANIL +! SAL ANTI^^ ANTI +! SAL ANVER^^ ANFA +! SAL ATIA$ ATIA +! SAL ATIA(NS)-- ATI +! SAL ATI(AÄOÖUÜ)- AZI +! SAL AUAU-- _ +! SAL AUER< AUA +! SAL AUF^^ AUF +! SAL AULT$ U +! SAL AUSSE$ UZ +! SAL AUS(ST)-^ AUZ +! SAL AUS^^ AUZ +! SAL AUTO^^ AUTU +! SAL AUX(IY)- AUX +! SAL AUX U +! SAL AU AU +! SAL AVIER$ AFIE +! SAL AYER--< EI +! SAL AY(AÄEIOÖUÜ)-- A +! SAL A(IJY)< EI +! SAL A A +! SAL BEA(BCMNRU)-^ PEA +! SAL BEAT(AEIMORU)-^ PEAT +! SAL BEIGE^$ PEZ +! SAL BE(LMNRST)-^ PE +! SAL BETTE$ PET +! SAL BIC$ PIZ +! SAL BOWL(EI)- PUL +! SAL BP(AÄEIOÖRUÜY)- P +! SAL BUDGET7 PIKE +! SAL BUFFET7 PIFE +! SAL BYLLE$ PILE +! SAL BYLL$ PIL +! SAL BYTE< PEIT +! SAL B P +! SAL CÄ- Z +! SAL CÜ$ ZI +! SAL CACH(EI)-^ KEZ +! SAL CAE-- Z +! SAL CA(IY)$ ZEI +! SAL CCH Z +! SAL CCE- X +! SAL CE(EIJUY)-- Z +! SAL CENT< ZENT +! SAL CERST(EI)----^ KE +! SAL CER$ ZA +! SAL CE3 ZE +! SAL CHAO(ST)- KAU +! SAL CHAMPIO-^ ZENPI +! SAL CHAR(AI)-^ KAR +! SAL CHAU(CDFSVWXZ)- ZU +! SAL CHE(CF)- ZE +! SAL CHEM-^ KE +! SAL CHEQUE< ZEK +! SAL CHI(CFGPVW)- ZI +! SAL CH(AEUY)-<^ Z +! SAL CHK- _ +! SAL CH(LOR)-<^ K +! SAL CHST- X +! SAL CH(SßXZ)3 X +! SAL CH K +! SAL CIER$ ZIE +! SAL CYB-^ ZEI +! SAL CY9^ ZI +! SAL C(IJY)-3 Z +! SAL CKST XT +! SAL CK(SßXZ)3 X +! SAL C(CK)- _ +! SAL CLAUDET--- KLU +! SAL CLAUDINE^$ KLUTIN +! SAL COLE$ KUL +! SAL COUCH KAUZ +! SAL CQUES$ K +! SAL CQUE K +! SAL CREAT-^ KREA +! SAL CST XT +! SAL CS<^ Z +! SAL C(SßX) X +! SAL CT(SßXZ) X +! SAL CZ< Z +! SAL C< K +! SAL D'H^ T +! SAL D'S3$ Z +! SAL DAVO(NR)-^$ TAFU +! SAL DD(SZ)--< _ +! SAL DEPOT7 TEPU +! SAL DESIGN TIZEIN +! SAL DE(LMNRST)-3^ TE +! SAL DETTE$ TET +! SAL DIC$ TIZ +! SAL DJ(AEIOU)-^ I +! SAL DS(CH)--< T +! SAL DST ZT +! SAL DT- _ +! SAL DUIS-^ TI +! SAL DURCH^^ TURK +! SAL DZS(CH)-- T +! SAL D(SßZ) Z +! SAL D T +! SAL EAULT$ U +! SAL EAUX$ U +! SAL EAU U +! SAL EAV IF +! SAL EA(AÄEIOÖÜY)-3 EA +! SAL EA3$ EA +! SAL EA3 I +! SAL EBEN^^ EPN +! SAL EE9 E +! SAL EIEI-- _ +! SAL EIH-- E +! SAL EILLE$ EI +! SAL EI EI +! SAL EJ$ EI +! SAL EL-^ E +! SAL EL(DKL)--1 E +! SAL EL(MNT)--1$ E +! SAL ELYNE$ ELINE +! SAL ELYN$ ELIN +! SAL EL(AÄEIOÖUÜY)-1 EL +! SAL EL-1 L +! SAL EM-^ E +! SAL EM(DFKMPQT)--1 E +! SAL EM(AÄEIOÖUÜY)--1 E +! SAL EM-1 N +! SAL EN-^ E +! SAL EN(CDGKQT)--1 E +! SAL ENZ(AEIOUY)--1 EN +! SAL EN(AÄEINOÖUÜY)-1 EN +! SAL EN-<1 N +! SAL ERH(AÄEIOÖUÜ)-^ ER +! SAL ER-^ E +! SAL ER(AÄEIOÖUÜY)-1 A +! SAL ER1$ A +! SAL ER<1 A +! SAL ETI(AÄOÖÜU)- EZI +! SAL EUEU-- _ +! SAL EUILLE$ Ö +! SAL EUR$ ÖR +! SAL EUX Ö +! SAL EUYS$ EUZ +! SAL EU EU +! SAL EYER< EIA +! SAL EY< EI +! SAL E E +! SAL FANS--^$ FE +! SAL FAN-^$ FE +! SAL FAULT- FUL +! SAL FEE(DL)- FI +! SAL FEHLER FELA +! SAL FE(LMNRST)-3^ FE +! SAL FOND7 FUN +! SAL FRAIN$ FRA +! SAL FRISEU(RS)- FRIZÖ # x +! SAL F F +! SAL G'S$ X +! SAL GAGS^$ KEX +! SAL GAG^$ KEK +! SAL GD KT +! SAL GEGEN^^ KEKN +! SAL GE(LMNRST)-3^ KE +! SAL GETTE$ KET +! SAL G(CK)- _ +! SAL GG- _ +! SAL GI(AO)-^ I +! SAL GION$ KIUN +! SAL GIUS-^ IU +! SAL GMBH^$ GMPH +! SAL GNAC$ NIAK +! SAL GNON$ NIUN +! SAL GN$ N +! SAL GONCAL-^ KUNZA +! SAL GS(CH)-- K +! SAL GST XT +! SAL G(SßXZ) X +! SAL GUCK- KU +! SAL GUI-^ K +! SAL G K +! SAL HEAD- E +! SAL HE(LMNRST)-3^ E +! SAL HE(LMN)-1 E +! SAL HEUR1$ ÖR +! SAL H^ _ +! SAL IEC$ IZ +! SAL IEI-3 _ +! SAL IELL3 IEL +! SAL IENNE$ IN +! SAL IERRE$ IER +! SAL IETTE$ IT +! SAL IEU IÖ +! SAL IE<4 I +! SAL IGHT3$ EIT +! SAL IGNI(EO)- INI +! SAL IGN(AEOU)-$ INI +! SAL IJ(AOU)- I +! SAL IJ$ I +! SAL IJ< EI +! SAL IKOLE$ IKUL +! SAL ILLAN(STZ)-- ILIA +! SAL ILLAR(DT)-- ILIA +! SAL INVER- INFE +! SAL ITI(AÄOÖUÜ)- IZI +! SAL IVIER$ IFIE +! SAL I I +! SAL JAVIE---<^ ZA +! SAL JEAN^$ IA +! SAL JEAN-^ IA +! SAL JER-^ IE +! SAL JE(LMNST)- IE +! SAL JOR(GK)^$ IÖRK +! SAL J I +! SAL KC(ÄEIJ)- X +! SAL KE(LMNRST)-3^ KE +! SAL KH<^ K +! SAL KIC$ KIZ +! SAL KLE(LMNRST)-3^ KLE +! SAL KOTELE-^ KUTL +! SAL KREAT-^ KREA +! SAL KST XT +! SAL K(SßXZ) X +! SAL KTI(AIOU)-3 XI +! SAL KT(SßXZ) X +! SAL K K +! SAL LARVE- LARF +! SAL LEAND-^ LEAN +! SAL LEL- LE +! SAL LE(MNRST)-3^ LE +! SAL LETTE$ LET +! SAL LFGNAG- LFKAN +! SAL LIC$ LIZ +! SAL LIVE^$ LEIF +! SAL LUI(GS)-- LU +! SAL L L +! SAL MASSEU(RS)- NAZÖ +! SAL MAURICE NURIZ +! SAL MBH^$ MPH +! SAL MB(SßZ)- N +! SAL MC9^ NK +! SAL MEMOIR-^ NENUA +! SAL ME(LMNRST)-3^ NE +! SAL MIGUEL NIKL +! SAL MIKE^$ NEIK +! SAL MN N +! SAL MPJUTE- NPUT +! SAL MP(SßZ)- N +! SAL MP(BDJLMNPQRTVW)- NP +! SAL M N +! SAL NACH^^ NAK +! SAL NADINE NATIN +! SAL NAIV-- NA +! SAL NAISE$ NEZE +! SAL NCOISE$ ZUA +! SAL NCOIS$ ZUA +! SAL NEBEN^^ NEPN +! SAL NE(LMNRST)-3^ NE +! SAL NEN-3 NE +! SAL NETTE$ NET +! SAL NG(BDFJLMNPQRTVW)- NK +! SAL NICHTS^^ NIX +! SAL NICHT^^ NIKT +! SAL NINE$ NIN +! SAL NON^^ NUN +! SAL NOT^^ NUT +! SAL NTI(AIOU)-3 NZI +! SAL NTIEL--3 NZI +! SAL NYLON NEILUN +! SAL ND(SßZ)$ NZ +! SAL NT(SßZ)$ NZ +! SAL ND'S$ NZ +! SAL NT'S$ NZ +! SAL NSTS$ NZ +! SAL N N +! SAL OBER^^ UPA +! SAL OE2 Ö +! SAL OGNIE- UNI +! SAL OGN(AEOU)-$ UNI +! SAL OIE$ Ö +! SAL OIR$ UAR +! SAL OIX UA +! SAL OI<3 EU +! SAL OJ(AÄEIOÖUÜ)-- U +! SAL OKAY^$ UKE +! SAL OLYN$ ULIN +! SAL OTI(AÄOÖUÜ)- UZI +! SAL OUI^ FI +! SAL OUILLE$ ULIE +! SAL OU(DT)-^ AU +! SAL OUSE$ AUZ +! SAL OUT- AU +! SAL OU U +! SAL OWS$ UZ +! SAL OY(AÄEIOÖUÜ)-- U +! SAL O(JY)< EU +! SAL O U +! SAL PATIEN--^ PAZI +! SAL PENSIO-^ PANZI +! SAL PE(LMNRST)-3^ PE +! SAL PFER-^ FE +! SAL P(FH)< F +! SAL POLY^^ PULI +! SAL PORTRAIT7 PURTRE +! SAL PP(FH)--< P +! SAL PP- _ +! SAL PRIX^$ PRI +! SAL P(SßZ)^ Z +! SAL PTI(AÄOÖUÜ)-3 PZI +! SAL PIC^$ PIK +! SAL P P +! SAL QUE(LMNRST)-3 KFE +! SAL QUE$ K +! SAL QUI(NS)$ KI +! SAL QU KF +! SAL Q< K +! SAL RCH RK +! SAL RECHERCH^ REZAZ +! SAL RER$ RA +! SAL RE(MNR)-4 RE +! SAL RETTE$ RET +! SAL RH<^ R +! SAL RJA(MN)-- RI +! SAL RTI(AÄOÖUÜ)-3 RZI +! SAL RY(KN)-$ RI +! SAL R R +! SAL SAFE^$ ZEIF +! SAL SAUCE-^ ZUZ +! SAL SCHSCH---7 _ +! SAL SCHTSCH Z +! SAL SC(HZ)< Z +! SAL SC ZK +! SAL SELBSTST--7^^ ZELP +! SAL SELBST7^^ ZELPZT +! SAL SERVICE7^ ZÖRFIZ +! SAL SE(LMNRST)-3^ ZE +! SAL SETTE$ ZET +! SAL SHP-^ Z +! SAL SHST ZT +! SAL SHTSH Z +! SAL SHT Z +! SAL SH3 Z +! SAL SIEGLI-^ ZIKL +! SAL SIGLI-^ ZIKL +! SAL SIGHT ZEIT +! SAL SIGN ZEIN +! SAL SKI(NPZ)- ZKI +! SAL SKI<^ ZI +! SAL SOUND- ZAUN +! SAL STAATS^^ ZTAZ +! SAL STADT^^ ZTAT +! SAL START^^ ZTART +! SAL STAURANT7 ZTURAN +! SAL STEAK- ZTE +! SAL STRAF^^ ZTRAF +! SAL ST'S$ Z +! SAL STST-- _ +! SAL STS(ACEHIOUÄÜÖ)-- ZT +! SAL ST(SZ) Z +! SAL STYN(AE)-$ ZTIN +! SAL ST ZT +! SAL SZE(NPT)-^ ZE +! SAL SZI(ELN)-^ ZI +! SAL SZCZ< Z +! SAL SZT< ZT +! SAL SZ<3 Z +! SAL S Z +! SAL T'S3$ Z +! SAL TCH Z +! SAL TEAT-^ TEA +! SAL TE(LMNRST)-3^ TE +! SAL TH< T +! SAL TIC$ TIZ +! SAL TOAS-^ TU +! SAL TOILET- TULE +! SAL TOIN- TUA +! SAL TRAINI- TREN +! SAL TSCH Z +! SAL TSH Z +! SAL TST ZT +! SAL T(Sß) Z +! SAL TT(SZ)--< _ +! SAL TT9 T +! SAL TZ- _ +! SAL T T +! SAL UEBER^^ IPA +! SAL UE2 I +! SAL UIE$ I +! SAL UM^^ UN +! SAL UNTERE-- UNTE +! SAL UNTER^^ UNTA +! SAL UNVER^^ UNFA +! SAL UN^^ UN +! SAL UTI(AÄOÖUÜ)- UZI +! SAL U U +! SAL VACL-^ FAZ +! SAL VAC$ FAZ +! SAL VEDD-^ FE +! SAL VEREIN FAEIN +! SAL VERSEN^ FAZN +! SAL VER^^ FA +! SAL VER FA +! SAL VET(HT)-^ FET +! SAL VETTE$ FET +! SAL VIC$ FIZ +! SAL VIEL FIL +! SAL VIEW FIU +! SAL VOR^^ FUR +! SAL VY9^ FI +! SAL V< F +! SAL WE(LMNRST)-3^ FE +! SAL WIC$ FIZ +! SAL WIEDER^^ FITA +! SAL WY9^ FI +! SAL W F +! SAL XE(LMNRST)-3^ XE +! SAL X<^ Z +! SAL X(CSZ) X +! SAL XTS(CH)-- XT +! SAL XT(SZ) Z +! SAL X X +! SAL YE(LMNRST)-3^ IE +! SAL YE-3 I +! SAL YOR(GK)^$ IÖRK +! SAL Y(AOU)-<7 I +! SAL YVES^$ IF +! SAL YVONNE^$ IFUN +! SAL Y I +! SAL ZC(AOU)- ZK +! SAL ZE(LMNRST)-3^ ZE +! SAL ZH< Z +! SAL ZS(CHT)-- _ +! SAL ZS Z +! SAL ZUERST ZUERZT +! SAL ZURÜCK^^ ZURIK +! SAL ZUVER^^ ZUFA # x +! SAL Z Z diff --git a/runtime/spell/de/de_AT.diff b/runtime/spell/de/de_AT.diff index 9097c6835f..42494fe385 100644 --- a/runtime/spell/de/de_AT.diff +++ b/runtime/spell/de/de_AT.diff @@ -1,8 +1,8 @@ -*** de_AT.orig.aff Sat Nov 26 19:59:53 2005 ---- de_AT.aff Sat Nov 26 20:19:21 2005 +*** de_AT.orig.aff 2019-01-19 19:16:46.616026157 +0100 +--- de_AT.aff 2019-01-19 19:24:24.524983269 +0100 *************** -*** 3,4 **** ---- 3,21 ---- +*** 15,16 **** +--- 15,47 ---- + FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ + LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ @@ -21,504 +21,553 @@ + MAP yÿý + MAP sß + ++ COMPOUNDRULE xy?z ++ #COMPOUNDBEGIN x ++ #COMPOUNDMIDDLE y ++ #COMPOUNDEND z ++ ++ # Prefixes are allowed at the beginning of compounds, ++ # suffixes are allowed at the end of compounds by default: ++ # (prefix)?(root)+(affix)? ++ # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. ++ COMPOUNDPERMITFLAG c ++ ++ ONLYINCOMPOUND o ++ ++ + PFX U Y 1 +*************** +*** 538,553 **** + +- +- COMPOUNDBEGIN x +- COMPOUNDMIDDLE y +- COMPOUNDEND z + FORBIDDENWORD d + +- # Prefixes are allowed at the beginning of compounds, +- # suffixes are allowed at the end of compounds by default: +- # (prefix)?(root)+(affix)? +- # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. +- COMPOUNDPERMITFLAG c +- +- ONLYINCOMPOUND o +- + # my PSEUDOROOT h(elper) flag +--- 569,572 ---- +*************** +*** 571,573 **** + +! WORDCHARS ß-. + +--- 590,592 ---- + +! # WORDCHARS ß-. *************** -*** 501 **** ---- 518,994 ---- - -+ -+ # German phonetic transformation rules from Aspell -+ # Copyright (C) 2000 Björn Jacke, distributed under LGPL. -+ # Björn Jacke may be reached by email at bjoern.jacke@gmx.de -+ # Last changed 2000-01-07 -+ -+ SAL followup 1 -+ SAL collapse_result 1 -+ -+ SAL ÄER- E -+ SAL ÄU< EU -+ SAL Ä< E -+ SAL É E -+ SAL ÖER- Ö -+ SAL Ö Ö -+ SAL ÜBER^^ IPA -+ SAL ÜER- I -+ SAL Ü I -+ SAL ß Z -+ SAL ABELLE$ APL -+ SAL ABELL$ APL -+ SAL ABIENNE$ APIN -+ SAL ACEY$ AZI -+ SAL AEU< EU -+ SAL AE2 E -+ SAL AGNI-^ AKN -+ SAL AGNIE- ANI -+ SAL AGN(AEOU)-$ ANI -+ SAL AIA2 AIA -+ SAL AIE$ E -+ SAL AILL(EOU)- ALI -+ SAL AINE$ EN -+ SAL AIRE$ ER -+ SAL AIR- E -+ SAL AISE$ EZ -+ SAL AISSANCE$ EZANZ -+ SAL AISSE$ EZ -+ SAL AIX$ EX -+ SAL AJ(AÄEIOÖUÜ)-- A -+ SAL AKTIE AXIE -+ SAL ALO(IY)^ ALUI -+ SAL AMATEU(RS)- ANATÖ -+ SAL ANIELLE$ ANIL -+ SAL ANTI^^ ANTI -+ SAL ANVER^^ ANFA -+ SAL ATIA$ ATIA -+ SAL ATIA(NS)-- ATI -+ SAL ATI(AÄOÖUÜ)- AZI -+ SAL AUAU-- _ -+ SAL AUER< AUA -+ SAL AUF^^ AUF -+ SAL AULT$ U -+ SAL AUSSE$ UZ -+ SAL AUS(ST)-^ AUZ -+ SAL AUS^^ AUZ -+ SAL AUTO^^ AUTU -+ SAL AUX(IY)- AUX -+ SAL AUX U -+ SAL AU AU -+ SAL AVIER$ AFIE -+ SAL AYER--< EI -+ SAL AY(AÄEIOÖUÜ)-- A -+ SAL A(IJY)< EI -+ SAL A A -+ SAL BEA(BCMNRU)-^ PEA -+ SAL BEAT(AEIMORU)-^ PEAT -+ SAL BEIGE^$ PEZ -+ SAL BE(LMNRST)-^ PE -+ SAL BETTE$ PET -+ SAL BIC$ PIZ -+ SAL BOWL(EI)- PUL -+ SAL BP(AÄEIOÖRUÜY)- P -+ SAL BUDGET7 PIKE -+ SAL BUFFET7 PIFE -+ SAL BYLLE$ PILE -+ SAL BYLL$ PIL -+ SAL BYTE< PEIT -+ SAL B P -+ SAL CÄ- Z -+ SAL CÜ$ ZI -+ SAL CACH(EI)-^ KEZ -+ SAL CAE-- Z -+ SAL CA(IY)$ ZEI -+ SAL CCH Z -+ SAL CCE- X -+ SAL CE(EIJUY)-- Z -+ SAL CENT< ZENT -+ SAL CERST(EI)----^ KE -+ SAL CER$ ZA -+ SAL CE3 ZE -+ SAL CHAO(ST)- KAU -+ SAL CHAMPIO-^ ZENPI -+ SAL CHAR(AI)-^ KAR -+ SAL CHAU(CDFSVWXZ)- ZU -+ SAL CHE(CF)- ZE -+ SAL CHEM-^ KE -+ SAL CHEQUE< ZEK -+ SAL CHI(CFGPVW)- ZI -+ SAL CH(AEUY)-<^ Z -+ SAL CHK- _ -+ SAL CH(LOR)-<^ K -+ SAL CHST- X -+ SAL CH(SßXZ)3 X -+ SAL CH K -+ SAL CIER$ ZIE -+ SAL CYB-^ ZEI -+ SAL CY9^ ZI -+ SAL C(IJY)-3 Z -+ SAL CKST XT -+ SAL CK(SßXZ)3 X -+ SAL C(CK)- _ -+ SAL CLAUDET--- KLU -+ SAL CLAUDINE^$ KLUTIN -+ SAL COLE$ KUL -+ SAL COUCH KAUZ -+ SAL CQUES$ K -+ SAL CQUE K -+ SAL CREAT-^ KREA -+ SAL CST XT -+ SAL CS<^ Z -+ SAL C(SßX) X -+ SAL CT(SßXZ) X -+ SAL CZ< Z -+ SAL C< K -+ SAL D'H^ T -+ SAL D'S3$ Z -+ SAL DAVO(NR)-^$ TAFU -+ SAL DD(SZ)--< _ -+ SAL DEPOT7 TEPU -+ SAL DESIGN TIZEIN -+ SAL DE(LMNRST)-3^ TE -+ SAL DETTE$ TET -+ SAL DIC$ TIZ -+ SAL DJ(AEIOU)-^ I -+ SAL DS(CH)--< T -+ SAL DST ZT -+ SAL DT- _ -+ SAL DUIS-^ TI -+ SAL DURCH^^ TURK -+ SAL DZS(CH)-- T -+ SAL D(SßZ) Z -+ SAL D T -+ SAL EAULT$ U -+ SAL EAUX$ U -+ SAL EAU U -+ SAL EAV IF -+ SAL EA(AÄEIOÖÜY)-3 EA -+ SAL EA3$ EA -+ SAL EA3 I -+ SAL EBEN^^ EPN -+ SAL EE9 E -+ SAL EIEI-- _ -+ SAL EIH-- E -+ SAL EILLE$ EI -+ SAL EI EI -+ SAL EJ$ EI -+ SAL EL-^ E -+ SAL EL(DKL)--1 E -+ SAL EL(MNT)--1$ E -+ SAL ELYNE$ ELINE -+ SAL ELYN$ ELIN -+ SAL EL(AÄEIOÖUÜY)-1 EL -+ SAL EL-1 L -+ SAL EM-^ E -+ SAL EM(DFKMPQT)--1 E -+ SAL EM(AÄEIOÖUÜY)--1 E -+ SAL EM-1 N -+ SAL EN-^ E -+ SAL EN(CDGKQT)--1 E -+ SAL ENZ(AEIOUY)--1 EN -+ SAL EN(AÄEINOÖUÜY)-1 EN -+ SAL EN-<1 N -+ SAL ERH(AÄEIOÖUÜ)-^ ER -+ SAL ER-^ E -+ SAL ER(AÄEIOÖUÜY)-1 A -+ SAL ER1$ A -+ SAL ER<1 A -+ SAL ETI(AÄOÖÜU)- EZI -+ SAL EUEU-- _ -+ SAL EUILLE$ Ö -+ SAL EUR$ ÖR -+ SAL EUX Ö -+ SAL EUYS$ EUZ -+ SAL EU EU -+ SAL EYER< EIA -+ SAL EY< EI -+ SAL E E -+ SAL FANS--^$ FE -+ SAL FAN-^$ FE -+ SAL FAULT- FUL -+ SAL FEE(DL)- FI -+ SAL FEHLER FELA -+ SAL FE(LMNRST)-3^ FE -+ SAL FOND7 FUN -+ SAL FRAIN$ FRA -+ SAL FRISEU(RS)- FRIZÖ # x -+ SAL F F -+ SAL G'S$ X -+ SAL GAGS^$ KEX -+ SAL GAG^$ KEK -+ SAL GD KT -+ SAL GEGEN^^ KEKN -+ SAL GE(LMNRST)-3^ KE -+ SAL GETTE$ KET -+ SAL G(CK)- _ -+ SAL GG- _ -+ SAL GI(AO)-^ I -+ SAL GION$ KIUN -+ SAL GIUS-^ IU -+ SAL GMBH^$ GMPH -+ SAL GNAC$ NIAK -+ SAL GNON$ NIUN -+ SAL GN$ N -+ SAL GONCAL-^ KUNZA -+ SAL GS(CH)-- K -+ SAL GST XT -+ SAL G(SßXZ) X -+ SAL GUCK- KU -+ SAL GUI-^ K -+ SAL G K -+ SAL HEAD- E -+ SAL HE(LMNRST)-3^ E -+ SAL HE(LMN)-1 E -+ SAL HEUR1$ ÖR -+ SAL H^ _ -+ SAL IEC$ IZ -+ SAL IEI-3 _ -+ SAL IELL3 IEL -+ SAL IENNE$ IN -+ SAL IERRE$ IER -+ SAL IETTE$ IT -+ SAL IEU IÖ -+ SAL IE<4 I -+ SAL IGHT3$ EIT -+ SAL IGNI(EO)- INI -+ SAL IGN(AEOU)-$ INI -+ SAL IJ(AOU)- I -+ SAL IJ$ I -+ SAL IJ< EI -+ SAL IKOLE$ IKUL -+ SAL ILLAN(STZ)-- ILIA -+ SAL ILLAR(DT)-- ILIA -+ SAL INVER- INFE -+ SAL ITI(AÄOÖUÜ)- IZI -+ SAL IVIER$ IFIE -+ SAL I I -+ SAL JAVIE---<^ ZA -+ SAL JEAN^$ IA -+ SAL JEAN-^ IA -+ SAL JER-^ IE -+ SAL JE(LMNST)- IE -+ SAL JOR(GK)^$ IÖRK -+ SAL J I -+ SAL KC(ÄEIJ)- X -+ SAL KE(LMNRST)-3^ KE -+ SAL KH<^ K -+ SAL KIC$ KIZ -+ SAL KLE(LMNRST)-3^ KLE -+ SAL KOTELE-^ KUTL -+ SAL KREAT-^ KREA -+ SAL KST XT -+ SAL K(SßXZ) X -+ SAL KTI(AIOU)-3 XI -+ SAL KT(SßXZ) X -+ SAL K K -+ SAL LARVE- LARF -+ SAL LEAND-^ LEAN -+ SAL LEL- LE -+ SAL LE(MNRST)-3^ LE -+ SAL LETTE$ LET -+ SAL LFGNAG- LFKAN -+ SAL LIC$ LIZ -+ SAL LIVE^$ LEIF -+ SAL LUI(GS)-- LU -+ SAL L L -+ SAL MASSEU(RS)- NAZÖ -+ SAL MAURICE NURIZ -+ SAL MBH^$ MPH -+ SAL MB(SßZ)- N -+ SAL MC9^ NK -+ SAL MEMOIR-^ NENUA -+ SAL ME(LMNRST)-3^ NE -+ SAL MIGUEL NIKL -+ SAL MIKE^$ NEIK -+ SAL MN N -+ SAL MPJUTE- NPUT -+ SAL MP(SßZ)- N -+ SAL MP(BDJLMNPQRTVW)- NP -+ SAL M N -+ SAL NACH^^ NAK -+ SAL NADINE NATIN -+ SAL NAIV-- NA -+ SAL NAISE$ NEZE -+ SAL NCOISE$ ZUA -+ SAL NCOIS$ ZUA -+ SAL NEBEN^^ NEPN -+ SAL NE(LMNRST)-3^ NE -+ SAL NEN-3 NE -+ SAL NETTE$ NET -+ SAL NG(BDFJLMNPQRTVW)- NK -+ SAL NICHTS^^ NIX -+ SAL NICHT^^ NIKT -+ SAL NINE$ NIN -+ SAL NON^^ NUN -+ SAL NOT^^ NUT -+ SAL NTI(AIOU)-3 NZI -+ SAL NTIEL--3 NZI -+ SAL NYLON NEILUN -+ SAL ND(SßZ)$ NZ -+ SAL NT(SßZ)$ NZ -+ SAL ND'S$ NZ -+ SAL NT'S$ NZ -+ SAL NSTS$ NZ -+ SAL N N -+ SAL OBER^^ UPA -+ SAL OE2 Ö -+ SAL OGNIE- UNI -+ SAL OGN(AEOU)-$ UNI -+ SAL OIE$ Ö -+ SAL OIR$ UAR -+ SAL OIX UA -+ SAL OI<3 EU -+ SAL OJ(AÄEIOÖUÜ)-- U -+ SAL OKAY^$ UKE -+ SAL OLYN$ ULIN -+ SAL OTI(AÄOÖUÜ)- UZI -+ SAL OUI^ FI -+ SAL OUILLE$ ULIE -+ SAL OU(DT)-^ AU -+ SAL OUSE$ AUZ -+ SAL OUT- AU -+ SAL OU U -+ SAL OWS$ UZ -+ SAL OY(AÄEIOÖUÜ)-- U -+ SAL O(JY)< EU -+ SAL O U -+ SAL PATIEN--^ PAZI -+ SAL PENSIO-^ PANZI -+ SAL PE(LMNRST)-3^ PE -+ SAL PFER-^ FE -+ SAL P(FH)< F -+ SAL POLY^^ PULI -+ SAL PORTRAIT7 PURTRE -+ SAL PP(FH)--< P -+ SAL PP- _ -+ SAL PRIX^$ PRI -+ SAL P(SßZ)^ Z -+ SAL PTI(AÄOÖUÜ)-3 PZI -+ SAL PIC^$ PIK -+ SAL P P -+ SAL QUE(LMNRST)-3 KFE -+ SAL QUE$ K -+ SAL QUI(NS)$ KI -+ SAL QU KF -+ SAL Q< K -+ SAL RCH RK -+ SAL RECHERCH^ REZAZ -+ SAL RER$ RA -+ SAL RE(MNR)-4 RE -+ SAL RETTE$ RET -+ SAL RH<^ R -+ SAL RJA(MN)-- RI -+ SAL RTI(AÄOÖUÜ)-3 RZI -+ SAL RY(KN)-$ RI -+ SAL R R -+ SAL SAFE^$ ZEIF -+ SAL SAUCE-^ ZUZ -+ SAL SCHSCH---7 _ -+ SAL SCHTSCH Z -+ SAL SC(HZ)< Z -+ SAL SC ZK -+ SAL SELBSTST--7^^ ZELP -+ SAL SELBST7^^ ZELPZT -+ SAL SERVICE7^ ZÖRFIZ -+ SAL SE(LMNRST)-3^ ZE -+ SAL SETTE$ ZET -+ SAL SHP-^ Z -+ SAL SHST ZT -+ SAL SHTSH Z -+ SAL SHT Z -+ SAL SH3 Z -+ SAL SIEGLI-^ ZIKL -+ SAL SIGLI-^ ZIKL -+ SAL SIGHT ZEIT -+ SAL SIGN ZEIN -+ SAL SKI(NPZ)- ZKI -+ SAL SKI<^ ZI -+ SAL SOUND- ZAUN -+ SAL STAATS^^ ZTAZ -+ SAL STADT^^ ZTAT -+ SAL START^^ ZTART -+ SAL STAURANT7 ZTURAN -+ SAL STEAK- ZTE -+ SAL STRAF^^ ZTRAF -+ SAL ST'S$ Z -+ SAL STST-- _ -+ SAL STS(ACEHIOUÄÜÖ)-- ZT -+ SAL ST(SZ) Z -+ SAL STYN(AE)-$ ZTIN -+ SAL ST ZT -+ SAL SZE(NPT)-^ ZE -+ SAL SZI(ELN)-^ ZI -+ SAL SZCZ< Z -+ SAL SZT< ZT -+ SAL SZ<3 Z -+ SAL S Z -+ SAL T'S3$ Z -+ SAL TCH Z -+ SAL TEAT-^ TEA -+ SAL TE(LMNRST)-3^ TE -+ SAL TH< T -+ SAL TIC$ TIZ -+ SAL TOAS-^ TU -+ SAL TOILET- TULE -+ SAL TOIN- TUA -+ SAL TRAINI- TREN -+ SAL TSCH Z -+ SAL TSH Z -+ SAL TST ZT -+ SAL T(Sß) Z -+ SAL TT(SZ)--< _ -+ SAL TT9 T -+ SAL TZ- _ -+ SAL T T -+ SAL UEBER^^ IPA -+ SAL UE2 I -+ SAL UIE$ I -+ SAL UM^^ UN -+ SAL UNTERE-- UNTE -+ SAL UNTER^^ UNTA -+ SAL UNVER^^ UNFA -+ SAL UN^^ UN -+ SAL UTI(AÄOÖUÜ)- UZI -+ SAL U U -+ SAL VACL-^ FAZ -+ SAL VAC$ FAZ -+ SAL VEDD-^ FE -+ SAL VEREIN FAEIN -+ SAL VERSEN^ FAZN -+ SAL VER^^ FA -+ SAL VER FA -+ SAL VET(HT)-^ FET -+ SAL VETTE$ FET -+ SAL VIC$ FIZ -+ SAL VIEL FIL -+ SAL VIEW FIU -+ SAL VOR^^ FUR -+ SAL VY9^ FI -+ SAL V< F -+ SAL WE(LMNRST)-3^ FE -+ SAL WIC$ FIZ -+ SAL WIEDER^^ FITA -+ SAL WY9^ FI -+ SAL W F -+ SAL XE(LMNRST)-3^ XE -+ SAL X<^ Z -+ SAL X(CSZ) X -+ SAL XTS(CH)-- XT -+ SAL XT(SZ) Z -+ SAL X X -+ SAL YE(LMNRST)-3^ IE -+ SAL YE-3 I -+ SAL YOR(GK)^$ IÖRK -+ SAL Y(AOU)-<7 I -+ SAL YVES^$ IF -+ SAL YVONNE^$ IFUN -+ SAL Y I -+ SAL ZC(AOU)- ZK -+ SAL ZE(LMNRST)-3^ ZE -+ SAL ZH< Z -+ SAL ZS(CHT)-- _ -+ SAL ZS Z -+ SAL ZUERST ZUERZT -+ SAL ZURÜCK^^ ZURIK -+ SAL ZUVER^^ ZUFA # x -+ SAL Z Z -*** de_AT.orig.dic Sat Nov 26 19:59:54 2005 ---- de_AT.dic Sat Nov 26 20:21:22 2005 -*************** -*** 18,20 **** - Fleischbänke/N -- Fleischbank - Fleischhauer/NS ---- 18,19 ---- -*************** -*** 19748,19750 **** - Geschwulstherde -- Geselchte/N - Gesellenbrief ---- 19747,19748 ---- -*************** -*** 21437,21439 **** - HTML -- Häfen - Häftling/EPS ---- 21435,21436 ---- +*** 725,729 **** + # So enabling this is the lesser evil. No perfect solution found so far... +! BREAK 2 +! BREAK - +! BREAK . +! +--- 744,1242 ---- + # So enabling this is the lesser evil. No perfect solution found so far... +! # BREAK 2 +! # BREAK - +! # BREAK . +! +! # German phonetic transformation rules for use with Aspell +! # Copyright (C) 2000 Björn Jacke +! # +! # This library is free software; you can redistribute it and/or +! # modify it under the terms of the GNU Lesser General Public +! # License version 2.1 as published by the Free Software Foundation; +! # +! # This library is distributed in the hope that it will be useful, +! # but WITHOUT ANY WARRANTY; without even the implied warranty of +! # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +! # Lesser General Public License for more details. +! # +! # You should have received a copy of the GNU Lesser General Public +! # License along with this library; if not, write to the Free Software +! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +! # +! # Björn Jacke may be reached by email at bjoern.jacke@gmx.de +! # +! # Changelog: +! # +! # 2000-01-05 Björn Jacke +! # Initial Release +! # 2000-01-07 Kevin Atkinson +! # Converted from header to data file. +! SAL followup 1 +! SAL collapse_result 1 +! +! SAL ÄER- E +! SAL ÄU< EU +! SAL Ä< E +! SAL É E +! SAL ÖER- Ö +! SAL Ö Ö +! SAL ÜBER^^ IPA +! SAL ÜER- I +! SAL Ü I +! SAL ß Z +! SAL ABELLE$ APL +! SAL ABELL$ APL +! SAL ABIENNE$ APIN +! SAL ACEY$ AZI +! SAL AEU< EU +! SAL AE2 E +! SAL AGNI-^ AKN +! SAL AGNIE- ANI +! SAL AGN(AEOU)-$ ANI +! SAL AIA2 AIA +! SAL AIE$ E +! SAL AILL(EOU)- ALI +! SAL AINE$ EN +! SAL AIRE$ ER +! SAL AIR- E +! SAL AISE$ EZ +! SAL AISSANCE$ EZANZ +! SAL AISSE$ EZ +! SAL AIX$ EX +! SAL AJ(AÄEIOÖUÜ)-- A +! SAL AKTIE AXIE +! SAL ALO(IY)^ ALUI +! SAL AMATEU(RS)- ANATÖ +! SAL ANIELLE$ ANIL +! SAL ANTI^^ ANTI +! SAL ANVER^^ ANFA +! SAL ATIA$ ATIA +! SAL ATIA(NS)-- ATI +! SAL ATI(AÄOÖUÜ)- AZI +! SAL AUAU-- _ +! SAL AUER< AUA +! SAL AUF^^ AUF +! SAL AULT$ U +! SAL AUSSE$ UZ +! SAL AUS(ST)-^ AUZ +! SAL AUS^^ AUZ +! SAL AUTO^^ AUTU +! SAL AUX(IY)- AUX +! SAL AUX U +! SAL AU AU +! SAL AVIER$ AFIE +! SAL AYER--< EI +! SAL AY(AÄEIOÖUÜ)-- A +! SAL A(IJY)< EI +! SAL A A +! SAL BEA(BCMNRU)-^ PEA +! SAL BEAT(AEIMORU)-^ PEAT +! SAL BEIGE^$ PEZ +! SAL BE(LMNRST)-^ PE +! SAL BETTE$ PET +! SAL BIC$ PIZ +! SAL BOWL(EI)- PUL +! SAL BP(AÄEIOÖRUÜY)- P +! SAL BUDGET7 PIKE +! SAL BUFFET7 PIFE +! SAL BYLLE$ PILE +! SAL BYLL$ PIL +! SAL BYTE< PEIT +! SAL B P +! SAL CÄ- Z +! SAL CÜ$ ZI +! SAL CACH(EI)-^ KEZ +! SAL CAE-- Z +! SAL CA(IY)$ ZEI +! SAL CCH Z +! SAL CCE- X +! SAL CE(EIJUY)-- Z +! SAL CENT< ZENT +! SAL CERST(EI)----^ KE +! SAL CER$ ZA +! SAL CE3 ZE +! SAL CHAO(ST)- KAU +! SAL CHAMPIO-^ ZENPI +! SAL CHAR(AI)-^ KAR +! SAL CHAU(CDFSVWXZ)- ZU +! SAL CHE(CF)- ZE +! SAL CHEM-^ KE +! SAL CHEQUE< ZEK +! SAL CHI(CFGPVW)- ZI +! SAL CH(AEUY)-<^ Z +! SAL CHK- _ +! SAL CH(LOR)-<^ K +! SAL CHST- X +! SAL CH(SßXZ)3 X +! SAL CH K +! SAL CIER$ ZIE +! SAL CYB-^ ZEI +! SAL CY9^ ZI +! SAL C(IJY)-3 Z +! SAL CKST XT +! SAL CK(SßXZ)3 X +! SAL C(CK)- _ +! SAL CLAUDET--- KLU +! SAL CLAUDINE^$ KLUTIN +! SAL COLE$ KUL +! SAL COUCH KAUZ +! SAL CQUES$ K +! SAL CQUE K +! SAL CREAT-^ KREA +! SAL CST XT +! SAL CS<^ Z +! SAL C(SßX) X +! SAL CT(SßXZ) X +! SAL CZ< Z +! SAL C< K +! SAL D'H^ T +! SAL D'S3$ Z +! SAL DAVO(NR)-^$ TAFU +! SAL DD(SZ)--< _ +! SAL DEPOT7 TEPU +! SAL DESIGN TIZEIN +! SAL DE(LMNRST)-3^ TE +! SAL DETTE$ TET +! SAL DIC$ TIZ +! SAL DJ(AEIOU)-^ I +! SAL DS(CH)--< T +! SAL DST ZT +! SAL DT- _ +! SAL DUIS-^ TI +! SAL DURCH^^ TURK +! SAL DZS(CH)-- T +! SAL D(SßZ) Z +! SAL D T +! SAL EAULT$ U +! SAL EAUX$ U +! SAL EAU U +! SAL EAV IF +! SAL EA(AÄEIOÖÜY)-3 EA +! SAL EA3$ EA +! SAL EA3 I +! SAL EBEN^^ EPN +! SAL EE9 E +! SAL EIEI-- _ +! SAL EIH-- E +! SAL EILLE$ EI +! SAL EI EI +! SAL EJ$ EI +! SAL EL-^ E +! SAL EL(DKL)--1 E +! SAL EL(MNT)--1$ E +! SAL ELYNE$ ELINE +! SAL ELYN$ ELIN +! SAL EL(AÄEIOÖUÜY)-1 EL +! SAL EL-1 L +! SAL EM-^ E +! SAL EM(DFKMPQT)--1 E +! SAL EM(AÄEIOÖUÜY)--1 E +! SAL EM-1 N +! SAL EN-^ E +! SAL EN(CDGKQT)--1 E +! SAL ENZ(AEIOUY)--1 EN +! SAL EN(AÄEINOÖUÜY)-1 EN +! SAL EN-<1 N +! SAL ERH(AÄEIOÖUÜ)-^ ER +! SAL ER-^ E +! SAL ER(AÄEIOÖUÜY)-1 A +! SAL ER1$ A +! SAL ER<1 A +! SAL ETI(AÄOÖÜU)- EZI +! SAL EUEU-- _ +! SAL EUILLE$ Ö +! SAL EUR$ ÖR +! SAL EUX Ö +! SAL EUYS$ EUZ +! SAL EU EU +! SAL EYER< EIA +! SAL EY< EI +! SAL E E +! SAL FANS--^$ FE +! SAL FAN-^$ FE +! SAL FAULT- FUL +! SAL FEE(DL)- FI +! SAL FEHLER FELA +! SAL FE(LMNRST)-3^ FE +! SAL FOND7 FUN +! SAL FRAIN$ FRA +! SAL FRISEU(RS)- FRIZÖ # x +! SAL F F +! SAL G'S$ X +! SAL GAGS^$ KEX +! SAL GAG^$ KEK +! SAL GD KT +! SAL GEGEN^^ KEKN +! SAL GE(LMNRST)-3^ KE +! SAL GETTE$ KET +! SAL G(CK)- _ +! SAL GG- _ +! SAL GI(AO)-^ I +! SAL GION$ KIUN +! SAL GIUS-^ IU +! SAL GMBH^$ GMPH +! SAL GNAC$ NIAK +! SAL GNON$ NIUN +! SAL GN$ N +! SAL GONCAL-^ KUNZA +! SAL GS(CH)-- K +! SAL GST XT +! SAL G(SßXZ) X +! SAL GUCK- KU +! SAL GUI-^ K +! SAL G K +! SAL HEAD- E +! SAL HE(LMNRST)-3^ E +! SAL HE(LMN)-1 E +! SAL HEUR1$ ÖR +! SAL H^ _ +! SAL IEC$ IZ +! SAL IEI-3 _ +! SAL IELL3 IEL +! SAL IENNE$ IN +! SAL IERRE$ IER +! SAL IETTE$ IT +! SAL IEU IÖ +! SAL IE<4 I +! SAL IGHT3$ EIT +! SAL IGNI(EO)- INI +! SAL IGN(AEOU)-$ INI +! SAL IJ(AOU)- I +! SAL IJ$ I +! SAL IJ< EI +! SAL IKOLE$ IKUL +! SAL ILLAN(STZ)-- ILIA +! SAL ILLAR(DT)-- ILIA +! SAL INVER- INFE +! SAL ITI(AÄOÖUÜ)- IZI +! SAL IVIER$ IFIE +! SAL I I +! SAL JAVIE---<^ ZA +! SAL JEAN^$ IA +! SAL JEAN-^ IA +! SAL JER-^ IE +! SAL JE(LMNST)- IE +! SAL JOR(GK)^$ IÖRK +! SAL J I +! SAL KC(ÄEIJ)- X +! SAL KE(LMNRST)-3^ KE +! SAL KH<^ K +! SAL KIC$ KIZ +! SAL KLE(LMNRST)-3^ KLE +! SAL KOTELE-^ KUTL +! SAL KREAT-^ KREA +! SAL KST XT +! SAL K(SßXZ) X +! SAL KTI(AIOU)-3 XI +! SAL KT(SßXZ) X +! SAL K K +! SAL LARVE- LARF +! SAL LEAND-^ LEAN +! SAL LEL- LE +! SAL LE(MNRST)-3^ LE +! SAL LETTE$ LET +! SAL LFGNAG- LFKAN +! SAL LIC$ LIZ +! SAL LIVE^$ LEIF +! SAL LUI(GS)-- LU +! SAL L L +! SAL MASSEU(RS)- NAZÖ +! SAL MAURICE NURIZ +! SAL MBH^$ MPH +! SAL MB(SßZ)- N +! SAL MC9^ NK +! SAL MEMOIR-^ NENUA +! SAL ME(LMNRST)-3^ NE +! SAL MIGUEL NIKL +! SAL MIKE^$ NEIK +! SAL MN N +! SAL MPJUTE- NPUT +! SAL MP(SßZ)- N +! SAL MP(BDJLMNPQRTVW)- NP +! SAL M N +! SAL NACH^^ NAK +! SAL NADINE NATIN +! SAL NAIV-- NA +! SAL NAISE$ NEZE +! SAL NCOISE$ ZUA +! SAL NCOIS$ ZUA +! SAL NEBEN^^ NEPN +! SAL NE(LMNRST)-3^ NE +! SAL NEN-3 NE +! SAL NETTE$ NET +! SAL NG(BDFJLMNPQRTVW)- NK +! SAL NICHTS^^ NIX +! SAL NICHT^^ NIKT +! SAL NINE$ NIN +! SAL NON^^ NUN +! SAL NOT^^ NUT +! SAL NTI(AIOU)-3 NZI +! SAL NTIEL--3 NZI +! SAL NYLON NEILUN +! SAL ND(SßZ)$ NZ +! SAL NT(SßZ)$ NZ +! SAL ND'S$ NZ +! SAL NT'S$ NZ +! SAL NSTS$ NZ +! SAL N N +! SAL OBER^^ UPA +! SAL OE2 Ö +! SAL OGNIE- UNI +! SAL OGN(AEOU)-$ UNI +! SAL OIE$ Ö +! SAL OIR$ UAR +! SAL OIX UA +! SAL OI<3 EU +! SAL OJ(AÄEIOÖUÜ)-- U +! SAL OKAY^$ UKE +! SAL OLYN$ ULIN +! SAL OTI(AÄOÖUÜ)- UZI +! SAL OUI^ FI +! SAL OUILLE$ ULIE +! SAL OU(DT)-^ AU +! SAL OUSE$ AUZ +! SAL OUT- AU +! SAL OU U +! SAL OWS$ UZ +! SAL OY(AÄEIOÖUÜ)-- U +! SAL O(JY)< EU +! SAL O U +! SAL PATIEN--^ PAZI +! SAL PENSIO-^ PANZI +! SAL PE(LMNRST)-3^ PE +! SAL PFER-^ FE +! SAL P(FH)< F +! SAL POLY^^ PULI +! SAL PORTRAIT7 PURTRE +! SAL PP(FH)--< P +! SAL PP- _ +! SAL PRIX^$ PRI +! SAL P(SßZ)^ Z +! SAL PTI(AÄOÖUÜ)-3 PZI +! SAL PIC^$ PIK +! SAL P P +! SAL QUE(LMNRST)-3 KFE +! SAL QUE$ K +! SAL QUI(NS)$ KI +! SAL QU KF +! SAL Q< K +! SAL RCH RK +! SAL RECHERCH^ REZAZ +! SAL RER$ RA +! SAL RE(MNR)-4 RE +! SAL RETTE$ RET +! SAL RH<^ R +! SAL RJA(MN)-- RI +! SAL RTI(AÄOÖUÜ)-3 RZI +! SAL RY(KN)-$ RI +! SAL R R +! SAL SAFE^$ ZEIF +! SAL SAUCE-^ ZUZ +! SAL SCHSCH---7 _ +! SAL SCHTSCH Z +! SAL SC(HZ)< Z +! SAL SC ZK +! SAL SELBSTST--7^^ ZELP +! SAL SELBST7^^ ZELPZT +! SAL SERVICE7^ ZÖRFIZ +! SAL SE(LMNRST)-3^ ZE +! SAL SETTE$ ZET +! SAL SHP-^ Z +! SAL SHST ZT +! SAL SHTSH Z +! SAL SHT Z +! SAL SH3 Z +! SAL SIEGLI-^ ZIKL +! SAL SIGLI-^ ZIKL +! SAL SIGHT ZEIT +! SAL SIGN ZEIN +! SAL SKI(NPZ)- ZKI +! SAL SKI<^ ZI +! SAL SOUND- ZAUN +! SAL STAATS^^ ZTAZ +! SAL STADT^^ ZTAT +! SAL START^^ ZTART +! SAL STAURANT7 ZTURAN +! SAL STEAK- ZTE +! SAL STRAF^^ ZTRAF +! SAL ST'S$ Z +! SAL STST-- _ +! SAL STS(ACEHIOUÄÜÖ)-- ZT +! SAL ST(SZ) Z +! SAL STYN(AE)-$ ZTIN +! SAL ST ZT +! SAL SZE(NPT)-^ ZE +! SAL SZI(ELN)-^ ZI +! SAL SZCZ< Z +! SAL SZT< ZT +! SAL SZ<3 Z +! SAL S Z +! SAL T'S3$ Z +! SAL TCH Z +! SAL TEAT-^ TEA +! SAL TE(LMNRST)-3^ TE +! SAL TH< T +! SAL TIC$ TIZ +! SAL TOAS-^ TU +! SAL TOILET- TULE +! SAL TOIN- TUA +! SAL TRAINI- TREN +! SAL TSCH Z +! SAL TSH Z +! SAL TST ZT +! SAL T(Sß) Z +! SAL TT(SZ)--< _ +! SAL TT9 T +! SAL TZ- _ +! SAL T T +! SAL UEBER^^ IPA +! SAL UE2 I +! SAL UIE$ I +! SAL UM^^ UN +! SAL UNTERE-- UNTE +! SAL UNTER^^ UNTA +! SAL UNVER^^ UNFA +! SAL UN^^ UN +! SAL UTI(AÄOÖUÜ)- UZI +! SAL U U +! SAL VACL-^ FAZ +! SAL VAC$ FAZ +! SAL VEDD-^ FE +! SAL VEREIN FAEIN +! SAL VERSEN^ FAZN +! SAL VER^^ FA +! SAL VER FA +! SAL VET(HT)-^ FET +! SAL VETTE$ FET +! SAL VIC$ FIZ +! SAL VIEL FIL +! SAL VIEW FIU +! SAL VOR^^ FUR +! SAL VY9^ FI +! SAL V< F +! SAL WE(LMNRST)-3^ FE +! SAL WIC$ FIZ +! SAL WIEDER^^ FITA +! SAL WY9^ FI +! SAL W F +! SAL XE(LMNRST)-3^ XE +! SAL X<^ Z +! SAL X(CSZ) X +! SAL XTS(CH)-- XT +! SAL XT(SZ) Z +! SAL X X +! SAL YE(LMNRST)-3^ IE +! SAL YE-3 I +! SAL YOR(GK)^$ IÖRK +! SAL Y(AOU)-<7 I +! SAL YVES^$ IF +! SAL YVONNE^$ IFUN +! SAL Y I +! SAL ZC(AOU)- ZK +! SAL ZE(LMNRST)-3^ ZE +! SAL ZH< Z +! SAL ZS(CHT)-- _ +! SAL ZS Z +! SAL ZUERST ZUERZT +! SAL ZURÜCK^^ ZURIK +! SAL ZUVER^^ ZUFA # x +! SAL Z Z diff --git a/runtime/spell/de/de_CH.diff b/runtime/spell/de/de_CH.diff index d5e1d9d750..2bf25a2cb2 100644 --- a/runtime/spell/de/de_CH.diff +++ b/runtime/spell/de/de_CH.diff @@ -1,8 +1,8 @@ -*** de_CH.orig.aff Sat Nov 26 19:38:16 2005 ---- de_CH.aff Sat Nov 26 19:38:08 2005 +*** de_CH.orig.aff 2019-01-19 18:45:30.400494173 +0100 +--- de_CH.aff 2019-01-19 19:24:48.064826847 +0100 *************** -*** 3,4 **** ---- 3,21 ---- +*** 15,16 **** +--- 15,48 ---- + FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ + LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ @@ -21,484 +21,554 @@ + MAP yÿý + MAP sß + ++ ++ COMPOUNDRULE xy?z ++ #COMPOUNDBEGIN x ++ #COMPOUNDMIDDLE y ++ #COMPOUNDEND z ++ ++ # Prefixes are allowed at the beginning of compounds, ++ # suffixes are allowed at the end of compounds by default: ++ # (prefix)?(root)+(affix)? ++ # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. ++ COMPOUNDPERMITFLAG c ++ ++ ONLYINCOMPOUND o ++ ++ + PFX U Y 1 +*************** +*** 538,553 **** + +- +- COMPOUNDBEGIN x +- COMPOUNDMIDDLE y +- COMPOUNDEND z + FORBIDDENWORD d + +- # Prefixes are allowed at the beginning of compounds, +- # suffixes are allowed at the end of compounds by default: +- # (prefix)?(root)+(affix)? +- # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. +- COMPOUNDPERMITFLAG c +- +- ONLYINCOMPOUND o +- + # my PSEUDOROOT h(elper) flag +--- 570,573 ---- +*************** +*** 571,573 **** + +! WORDCHARS ß-. + +--- 591,593 ---- + +! # WORDCHARS ß-. *************** -*** 503 **** ---- 520,996 ---- - REP eh e -+ -+ # German phonetic transformation rules from Aspell -+ # Copyright (C) 2000 Björn Jacke, distributed under LGPL. -+ # Björn Jacke may be reached by email at bjoern.jacke@gmx.de -+ # Last changed 2000-01-07 -+ -+ SAL followup 1 -+ SAL collapse_result 1 -+ -+ SAL ÄER- E -+ SAL ÄU< EU -+ SAL Ä< E -+ SAL É E -+ SAL ÖER- Ö -+ SAL Ö Ö -+ SAL ÜBER^^ IPA -+ SAL ÜER- I -+ SAL Ü I -+ SAL ß Z -+ SAL ABELLE$ APL -+ SAL ABELL$ APL -+ SAL ABIENNE$ APIN -+ SAL ACEY$ AZI -+ SAL AEU< EU -+ SAL AE2 E -+ SAL AGNI-^ AKN -+ SAL AGNIE- ANI -+ SAL AGN(AEOU)-$ ANI -+ SAL AIA2 AIA -+ SAL AIE$ E -+ SAL AILL(EOU)- ALI -+ SAL AINE$ EN -+ SAL AIRE$ ER -+ SAL AIR- E -+ SAL AISE$ EZ -+ SAL AISSANCE$ EZANZ -+ SAL AISSE$ EZ -+ SAL AIX$ EX -+ SAL AJ(AÄEIOÖUÜ)-- A -+ SAL AKTIE AXIE -+ SAL ALO(IY)^ ALUI -+ SAL AMATEU(RS)- ANATÖ -+ SAL ANIELLE$ ANIL -+ SAL ANTI^^ ANTI -+ SAL ANVER^^ ANFA -+ SAL ATIA$ ATIA -+ SAL ATIA(NS)-- ATI -+ SAL ATI(AÄOÖUÜ)- AZI -+ SAL AUAU-- _ -+ SAL AUER< AUA -+ SAL AUF^^ AUF -+ SAL AULT$ U -+ SAL AUSSE$ UZ -+ SAL AUS(ST)-^ AUZ -+ SAL AUS^^ AUZ -+ SAL AUTO^^ AUTU -+ SAL AUX(IY)- AUX -+ SAL AUX U -+ SAL AU AU -+ SAL AVIER$ AFIE -+ SAL AYER--< EI -+ SAL AY(AÄEIOÖUÜ)-- A -+ SAL A(IJY)< EI -+ SAL A A -+ SAL BEA(BCMNRU)-^ PEA -+ SAL BEAT(AEIMORU)-^ PEAT -+ SAL BEIGE^$ PEZ -+ SAL BE(LMNRST)-^ PE -+ SAL BETTE$ PET -+ SAL BIC$ PIZ -+ SAL BOWL(EI)- PUL -+ SAL BP(AÄEIOÖRUÜY)- P -+ SAL BUDGET7 PIKE -+ SAL BUFFET7 PIFE -+ SAL BYLLE$ PILE -+ SAL BYLL$ PIL -+ SAL BYTE< PEIT -+ SAL B P -+ SAL CÄ- Z -+ SAL CÜ$ ZI -+ SAL CACH(EI)-^ KEZ -+ SAL CAE-- Z -+ SAL CA(IY)$ ZEI -+ SAL CCH Z -+ SAL CCE- X -+ SAL CE(EIJUY)-- Z -+ SAL CENT< ZENT -+ SAL CERST(EI)----^ KE -+ SAL CER$ ZA -+ SAL CE3 ZE -+ SAL CHAO(ST)- KAU -+ SAL CHAMPIO-^ ZENPI -+ SAL CHAR(AI)-^ KAR -+ SAL CHAU(CDFSVWXZ)- ZU -+ SAL CHE(CF)- ZE -+ SAL CHEM-^ KE -+ SAL CHEQUE< ZEK -+ SAL CHI(CFGPVW)- ZI -+ SAL CH(AEUY)-<^ Z -+ SAL CHK- _ -+ SAL CH(LOR)-<^ K -+ SAL CHST- X -+ SAL CH(SßXZ)3 X -+ SAL CH K -+ SAL CIER$ ZIE -+ SAL CYB-^ ZEI -+ SAL CY9^ ZI -+ SAL C(IJY)-3 Z -+ SAL CKST XT -+ SAL CK(SßXZ)3 X -+ SAL C(CK)- _ -+ SAL CLAUDET--- KLU -+ SAL CLAUDINE^$ KLUTIN -+ SAL COLE$ KUL -+ SAL COUCH KAUZ -+ SAL CQUES$ K -+ SAL CQUE K -+ SAL CREAT-^ KREA -+ SAL CST XT -+ SAL CS<^ Z -+ SAL C(SßX) X -+ SAL CT(SßXZ) X -+ SAL CZ< Z -+ SAL C< K -+ SAL D'H^ T -+ SAL D'S3$ Z -+ SAL DAVO(NR)-^$ TAFU -+ SAL DD(SZ)--< _ -+ SAL DEPOT7 TEPU -+ SAL DESIGN TIZEIN -+ SAL DE(LMNRST)-3^ TE -+ SAL DETTE$ TET -+ SAL DIC$ TIZ -+ SAL DJ(AEIOU)-^ I -+ SAL DS(CH)--< T -+ SAL DST ZT -+ SAL DT- _ -+ SAL DUIS-^ TI -+ SAL DURCH^^ TURK -+ SAL DZS(CH)-- T -+ SAL D(SßZ) Z -+ SAL D T -+ SAL EAULT$ U -+ SAL EAUX$ U -+ SAL EAU U -+ SAL EAV IF -+ SAL EA(AÄEIOÖÜY)-3 EA -+ SAL EA3$ EA -+ SAL EA3 I -+ SAL EBEN^^ EPN -+ SAL EE9 E -+ SAL EIEI-- _ -+ SAL EIH-- E -+ SAL EILLE$ EI -+ SAL EI EI -+ SAL EJ$ EI -+ SAL EL-^ E -+ SAL EL(DKL)--1 E -+ SAL EL(MNT)--1$ E -+ SAL ELYNE$ ELINE -+ SAL ELYN$ ELIN -+ SAL EL(AÄEIOÖUÜY)-1 EL -+ SAL EL-1 L -+ SAL EM-^ E -+ SAL EM(DFKMPQT)--1 E -+ SAL EM(AÄEIOÖUÜY)--1 E -+ SAL EM-1 N -+ SAL EN-^ E -+ SAL EN(CDGKQT)--1 E -+ SAL ENZ(AEIOUY)--1 EN -+ SAL EN(AÄEINOÖUÜY)-1 EN -+ SAL EN-<1 N -+ SAL ERH(AÄEIOÖUÜ)-^ ER -+ SAL ER-^ E -+ SAL ER(AÄEIOÖUÜY)-1 A -+ SAL ER1$ A -+ SAL ER<1 A -+ SAL ETI(AÄOÖÜU)- EZI -+ SAL EUEU-- _ -+ SAL EUILLE$ Ö -+ SAL EUR$ ÖR -+ SAL EUX Ö -+ SAL EUYS$ EUZ -+ SAL EU EU -+ SAL EYER< EIA -+ SAL EY< EI -+ SAL E E -+ SAL FANS--^$ FE -+ SAL FAN-^$ FE -+ SAL FAULT- FUL -+ SAL FEE(DL)- FI -+ SAL FEHLER FELA -+ SAL FE(LMNRST)-3^ FE -+ SAL FOND7 FUN -+ SAL FRAIN$ FRA -+ SAL FRISEU(RS)- FRIZÖ # x -+ SAL F F -+ SAL G'S$ X -+ SAL GAGS^$ KEX -+ SAL GAG^$ KEK -+ SAL GD KT -+ SAL GEGEN^^ KEKN -+ SAL GE(LMNRST)-3^ KE -+ SAL GETTE$ KET -+ SAL G(CK)- _ -+ SAL GG- _ -+ SAL GI(AO)-^ I -+ SAL GION$ KIUN -+ SAL GIUS-^ IU -+ SAL GMBH^$ GMPH -+ SAL GNAC$ NIAK -+ SAL GNON$ NIUN -+ SAL GN$ N -+ SAL GONCAL-^ KUNZA -+ SAL GS(CH)-- K -+ SAL GST XT -+ SAL G(SßXZ) X -+ SAL GUCK- KU -+ SAL GUI-^ K -+ SAL G K -+ SAL HEAD- E -+ SAL HE(LMNRST)-3^ E -+ SAL HE(LMN)-1 E -+ SAL HEUR1$ ÖR -+ SAL H^ _ -+ SAL IEC$ IZ -+ SAL IEI-3 _ -+ SAL IELL3 IEL -+ SAL IENNE$ IN -+ SAL IERRE$ IER -+ SAL IETTE$ IT -+ SAL IEU IÖ -+ SAL IE<4 I -+ SAL IGHT3$ EIT -+ SAL IGNI(EO)- INI -+ SAL IGN(AEOU)-$ INI -+ SAL IJ(AOU)- I -+ SAL IJ$ I -+ SAL IJ< EI -+ SAL IKOLE$ IKUL -+ SAL ILLAN(STZ)-- ILIA -+ SAL ILLAR(DT)-- ILIA -+ SAL INVER- INFE -+ SAL ITI(AÄOÖUÜ)- IZI -+ SAL IVIER$ IFIE -+ SAL I I -+ SAL JAVIE---<^ ZA -+ SAL JEAN^$ IA -+ SAL JEAN-^ IA -+ SAL JER-^ IE -+ SAL JE(LMNST)- IE -+ SAL JOR(GK)^$ IÖRK -+ SAL J I -+ SAL KC(ÄEIJ)- X -+ SAL KE(LMNRST)-3^ KE -+ SAL KH<^ K -+ SAL KIC$ KIZ -+ SAL KLE(LMNRST)-3^ KLE -+ SAL KOTELE-^ KUTL -+ SAL KREAT-^ KREA -+ SAL KST XT -+ SAL K(SßXZ) X -+ SAL KTI(AIOU)-3 XI -+ SAL KT(SßXZ) X -+ SAL K K -+ SAL LARVE- LARF -+ SAL LEAND-^ LEAN -+ SAL LEL- LE -+ SAL LE(MNRST)-3^ LE -+ SAL LETTE$ LET -+ SAL LFGNAG- LFKAN -+ SAL LIC$ LIZ -+ SAL LIVE^$ LEIF -+ SAL LUI(GS)-- LU -+ SAL L L -+ SAL MASSEU(RS)- NAZÖ -+ SAL MAURICE NURIZ -+ SAL MBH^$ MPH -+ SAL MB(SßZ)- N -+ SAL MC9^ NK -+ SAL MEMOIR-^ NENUA -+ SAL ME(LMNRST)-3^ NE -+ SAL MIGUEL NIKL -+ SAL MIKE^$ NEIK -+ SAL MN N -+ SAL MPJUTE- NPUT -+ SAL MP(SßZ)- N -+ SAL MP(BDJLMNPQRTVW)- NP -+ SAL M N -+ SAL NACH^^ NAK -+ SAL NADINE NATIN -+ SAL NAIV-- NA -+ SAL NAISE$ NEZE -+ SAL NCOISE$ ZUA -+ SAL NCOIS$ ZUA -+ SAL NEBEN^^ NEPN -+ SAL NE(LMNRST)-3^ NE -+ SAL NEN-3 NE -+ SAL NETTE$ NET -+ SAL NG(BDFJLMNPQRTVW)- NK -+ SAL NICHTS^^ NIX -+ SAL NICHT^^ NIKT -+ SAL NINE$ NIN -+ SAL NON^^ NUN -+ SAL NOT^^ NUT -+ SAL NTI(AIOU)-3 NZI -+ SAL NTIEL--3 NZI -+ SAL NYLON NEILUN -+ SAL ND(SßZ)$ NZ -+ SAL NT(SßZ)$ NZ -+ SAL ND'S$ NZ -+ SAL NT'S$ NZ -+ SAL NSTS$ NZ -+ SAL N N -+ SAL OBER^^ UPA -+ SAL OE2 Ö -+ SAL OGNIE- UNI -+ SAL OGN(AEOU)-$ UNI -+ SAL OIE$ Ö -+ SAL OIR$ UAR -+ SAL OIX UA -+ SAL OI<3 EU -+ SAL OJ(AÄEIOÖUÜ)-- U -+ SAL OKAY^$ UKE -+ SAL OLYN$ ULIN -+ SAL OTI(AÄOÖUÜ)- UZI -+ SAL OUI^ FI -+ SAL OUILLE$ ULIE -+ SAL OU(DT)-^ AU -+ SAL OUSE$ AUZ -+ SAL OUT- AU -+ SAL OU U -+ SAL OWS$ UZ -+ SAL OY(AÄEIOÖUÜ)-- U -+ SAL O(JY)< EU -+ SAL O U -+ SAL PATIEN--^ PAZI -+ SAL PENSIO-^ PANZI -+ SAL PE(LMNRST)-3^ PE -+ SAL PFER-^ FE -+ SAL P(FH)< F -+ SAL POLY^^ PULI -+ SAL PORTRAIT7 PURTRE -+ SAL PP(FH)--< P -+ SAL PP- _ -+ SAL PRIX^$ PRI -+ SAL P(SßZ)^ Z -+ SAL PTI(AÄOÖUÜ)-3 PZI -+ SAL PIC^$ PIK -+ SAL P P -+ SAL QUE(LMNRST)-3 KFE -+ SAL QUE$ K -+ SAL QUI(NS)$ KI -+ SAL QU KF -+ SAL Q< K -+ SAL RCH RK -+ SAL RECHERCH^ REZAZ -+ SAL RER$ RA -+ SAL RE(MNR)-4 RE -+ SAL RETTE$ RET -+ SAL RH<^ R -+ SAL RJA(MN)-- RI -+ SAL RTI(AÄOÖUÜ)-3 RZI -+ SAL RY(KN)-$ RI -+ SAL R R -+ SAL SAFE^$ ZEIF -+ SAL SAUCE-^ ZUZ -+ SAL SCHSCH---7 _ -+ SAL SCHTSCH Z -+ SAL SC(HZ)< Z -+ SAL SC ZK -+ SAL SELBSTST--7^^ ZELP -+ SAL SELBST7^^ ZELPZT -+ SAL SERVICE7^ ZÖRFIZ -+ SAL SE(LMNRST)-3^ ZE -+ SAL SETTE$ ZET -+ SAL SHP-^ Z -+ SAL SHST ZT -+ SAL SHTSH Z -+ SAL SHT Z -+ SAL SH3 Z -+ SAL SIEGLI-^ ZIKL -+ SAL SIGLI-^ ZIKL -+ SAL SIGHT ZEIT -+ SAL SIGN ZEIN -+ SAL SKI(NPZ)- ZKI -+ SAL SKI<^ ZI -+ SAL SOUND- ZAUN -+ SAL STAATS^^ ZTAZ -+ SAL STADT^^ ZTAT -+ SAL START^^ ZTART -+ SAL STAURANT7 ZTURAN -+ SAL STEAK- ZTE -+ SAL STRAF^^ ZTRAF -+ SAL ST'S$ Z -+ SAL STST-- _ -+ SAL STS(ACEHIOUÄÜÖ)-- ZT -+ SAL ST(SZ) Z -+ SAL STYN(AE)-$ ZTIN -+ SAL ST ZT -+ SAL SZE(NPT)-^ ZE -+ SAL SZI(ELN)-^ ZI -+ SAL SZCZ< Z -+ SAL SZT< ZT -+ SAL SZ<3 Z -+ SAL S Z -+ SAL T'S3$ Z -+ SAL TCH Z -+ SAL TEAT-^ TEA -+ SAL TE(LMNRST)-3^ TE -+ SAL TH< T -+ SAL TIC$ TIZ -+ SAL TOAS-^ TU -+ SAL TOILET- TULE -+ SAL TOIN- TUA -+ SAL TRAINI- TREN -+ SAL TSCH Z -+ SAL TSH Z -+ SAL TST ZT -+ SAL T(Sß) Z -+ SAL TT(SZ)--< _ -+ SAL TT9 T -+ SAL TZ- _ -+ SAL T T -+ SAL UEBER^^ IPA -+ SAL UE2 I -+ SAL UIE$ I -+ SAL UM^^ UN -+ SAL UNTERE-- UNTE -+ SAL UNTER^^ UNTA -+ SAL UNVER^^ UNFA -+ SAL UN^^ UN -+ SAL UTI(AÄOÖUÜ)- UZI -+ SAL U U -+ SAL VACL-^ FAZ -+ SAL VAC$ FAZ -+ SAL VEDD-^ FE -+ SAL VEREIN FAEIN -+ SAL VERSEN^ FAZN -+ SAL VER^^ FA -+ SAL VER FA -+ SAL VET(HT)-^ FET -+ SAL VETTE$ FET -+ SAL VIC$ FIZ -+ SAL VIEL FIL -+ SAL VIEW FIU -+ SAL VOR^^ FUR -+ SAL VY9^ FI -+ SAL V< F -+ SAL WE(LMNRST)-3^ FE -+ SAL WIC$ FIZ -+ SAL WIEDER^^ FITA -+ SAL WY9^ FI -+ SAL W F -+ SAL XE(LMNRST)-3^ XE -+ SAL X<^ Z -+ SAL X(CSZ) X -+ SAL XTS(CH)-- XT -+ SAL XT(SZ) Z -+ SAL X X -+ SAL YE(LMNRST)-3^ IE -+ SAL YE-3 I -+ SAL YOR(GK)^$ IÖRK -+ SAL Y(AOU)-<7 I -+ SAL YVES^$ IF -+ SAL YVONNE^$ IFUN -+ SAL Y I -+ SAL ZC(AOU)- ZK -+ SAL ZE(LMNRST)-3^ ZE -+ SAL ZH< Z -+ SAL ZS(CHT)-- _ -+ SAL ZS Z -+ SAL ZUERST ZUERZT -+ SAL ZURÜCK^^ ZURIK -+ SAL ZUVER^^ ZUFA # x -+ SAL Z Z +*** 725,729 **** + # So enabling this is the lesser evil. No perfect solution found so far... +! BREAK 2 +! BREAK - +! BREAK . +! +--- 745,1243 ---- + # So enabling this is the lesser evil. No perfect solution found so far... +! # BREAK 2 +! # BREAK - +! # BREAK . +! +! # German phonetic transformation rules for use with Aspell +! # Copyright (C) 2000 Björn Jacke +! # +! # This library is free software; you can redistribute it and/or +! # modify it under the terms of the GNU Lesser General Public +! # License version 2.1 as published by the Free Software Foundation; +! # +! # This library is distributed in the hope that it will be useful, +! # but WITHOUT ANY WARRANTY; without even the implied warranty of +! # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +! # Lesser General Public License for more details. +! # +! # You should have received a copy of the GNU Lesser General Public +! # License along with this library; if not, write to the Free Software +! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +! # +! # Björn Jacke may be reached by email at bjoern.jacke@gmx.de +! # +! # Changelog: +! # +! # 2000-01-05 Björn Jacke +! # Initial Release +! # 2000-01-07 Kevin Atkinson +! # Converted from header to data file. +! SAL followup 1 +! SAL collapse_result 1 +! +! SAL ÄER- E +! SAL ÄU< EU +! SAL Ä< E +! SAL É E +! SAL ÖER- Ö +! SAL Ö Ö +! SAL ÜBER^^ IPA +! SAL ÜER- I +! SAL Ü I +! SAL ß Z +! SAL ABELLE$ APL +! SAL ABELL$ APL +! SAL ABIENNE$ APIN +! SAL ACEY$ AZI +! SAL AEU< EU +! SAL AE2 E +! SAL AGNI-^ AKN +! SAL AGNIE- ANI +! SAL AGN(AEOU)-$ ANI +! SAL AIA2 AIA +! SAL AIE$ E +! SAL AILL(EOU)- ALI +! SAL AINE$ EN +! SAL AIRE$ ER +! SAL AIR- E +! SAL AISE$ EZ +! SAL AISSANCE$ EZANZ +! SAL AISSE$ EZ +! SAL AIX$ EX +! SAL AJ(AÄEIOÖUÜ)-- A +! SAL AKTIE AXIE +! SAL ALO(IY)^ ALUI +! SAL AMATEU(RS)- ANATÖ +! SAL ANIELLE$ ANIL +! SAL ANTI^^ ANTI +! SAL ANVER^^ ANFA +! SAL ATIA$ ATIA +! SAL ATIA(NS)-- ATI +! SAL ATI(AÄOÖUÜ)- AZI +! SAL AUAU-- _ +! SAL AUER< AUA +! SAL AUF^^ AUF +! SAL AULT$ U +! SAL AUSSE$ UZ +! SAL AUS(ST)-^ AUZ +! SAL AUS^^ AUZ +! SAL AUTO^^ AUTU +! SAL AUX(IY)- AUX +! SAL AUX U +! SAL AU AU +! SAL AVIER$ AFIE +! SAL AYER--< EI +! SAL AY(AÄEIOÖUÜ)-- A +! SAL A(IJY)< EI +! SAL A A +! SAL BEA(BCMNRU)-^ PEA +! SAL BEAT(AEIMORU)-^ PEAT +! SAL BEIGE^$ PEZ +! SAL BE(LMNRST)-^ PE +! SAL BETTE$ PET +! SAL BIC$ PIZ +! SAL BOWL(EI)- PUL +! SAL BP(AÄEIOÖRUÜY)- P +! SAL BUDGET7 PIKE +! SAL BUFFET7 PIFE +! SAL BYLLE$ PILE +! SAL BYLL$ PIL +! SAL BYTE< PEIT +! SAL B P +! SAL CÄ- Z +! SAL CÜ$ ZI +! SAL CACH(EI)-^ KEZ +! SAL CAE-- Z +! SAL CA(IY)$ ZEI +! SAL CCH Z +! SAL CCE- X +! SAL CE(EIJUY)-- Z +! SAL CENT< ZENT +! SAL CERST(EI)----^ KE +! SAL CER$ ZA +! SAL CE3 ZE +! SAL CHAO(ST)- KAU +! SAL CHAMPIO-^ ZENPI +! SAL CHAR(AI)-^ KAR +! SAL CHAU(CDFSVWXZ)- ZU +! SAL CHE(CF)- ZE +! SAL CHEM-^ KE +! SAL CHEQUE< ZEK +! SAL CHI(CFGPVW)- ZI +! SAL CH(AEUY)-<^ Z +! SAL CHK- _ +! SAL CH(LOR)-<^ K +! SAL CHST- X +! SAL CH(SßXZ)3 X +! SAL CH K +! SAL CIER$ ZIE +! SAL CYB-^ ZEI +! SAL CY9^ ZI +! SAL C(IJY)-3 Z +! SAL CKST XT +! SAL CK(SßXZ)3 X +! SAL C(CK)- _ +! SAL CLAUDET--- KLU +! SAL CLAUDINE^$ KLUTIN +! SAL COLE$ KUL +! SAL COUCH KAUZ +! SAL CQUES$ K +! SAL CQUE K +! SAL CREAT-^ KREA +! SAL CST XT +! SAL CS<^ Z +! SAL C(SßX) X +! SAL CT(SßXZ) X +! SAL CZ< Z +! SAL C< K +! SAL D'H^ T +! SAL D'S3$ Z +! SAL DAVO(NR)-^$ TAFU +! SAL DD(SZ)--< _ +! SAL DEPOT7 TEPU +! SAL DESIGN TIZEIN +! SAL DE(LMNRST)-3^ TE +! SAL DETTE$ TET +! SAL DIC$ TIZ +! SAL DJ(AEIOU)-^ I +! SAL DS(CH)--< T +! SAL DST ZT +! SAL DT- _ +! SAL DUIS-^ TI +! SAL DURCH^^ TURK +! SAL DZS(CH)-- T +! SAL D(SßZ) Z +! SAL D T +! SAL EAULT$ U +! SAL EAUX$ U +! SAL EAU U +! SAL EAV IF +! SAL EA(AÄEIOÖÜY)-3 EA +! SAL EA3$ EA +! SAL EA3 I +! SAL EBEN^^ EPN +! SAL EE9 E +! SAL EIEI-- _ +! SAL EIH-- E +! SAL EILLE$ EI +! SAL EI EI +! SAL EJ$ EI +! SAL EL-^ E +! SAL EL(DKL)--1 E +! SAL EL(MNT)--1$ E +! SAL ELYNE$ ELINE +! SAL ELYN$ ELIN +! SAL EL(AÄEIOÖUÜY)-1 EL +! SAL EL-1 L +! SAL EM-^ E +! SAL EM(DFKMPQT)--1 E +! SAL EM(AÄEIOÖUÜY)--1 E +! SAL EM-1 N +! SAL EN-^ E +! SAL EN(CDGKQT)--1 E +! SAL ENZ(AEIOUY)--1 EN +! SAL EN(AÄEINOÖUÜY)-1 EN +! SAL EN-<1 N +! SAL ERH(AÄEIOÖUÜ)-^ ER +! SAL ER-^ E +! SAL ER(AÄEIOÖUÜY)-1 A +! SAL ER1$ A +! SAL ER<1 A +! SAL ETI(AÄOÖÜU)- EZI +! SAL EUEU-- _ +! SAL EUILLE$ Ö +! SAL EUR$ ÖR +! SAL EUX Ö +! SAL EUYS$ EUZ +! SAL EU EU +! SAL EYER< EIA +! SAL EY< EI +! SAL E E +! SAL FANS--^$ FE +! SAL FAN-^$ FE +! SAL FAULT- FUL +! SAL FEE(DL)- FI +! SAL FEHLER FELA +! SAL FE(LMNRST)-3^ FE +! SAL FOND7 FUN +! SAL FRAIN$ FRA +! SAL FRISEU(RS)- FRIZÖ # x +! SAL F F +! SAL G'S$ X +! SAL GAGS^$ KEX +! SAL GAG^$ KEK +! SAL GD KT +! SAL GEGEN^^ KEKN +! SAL GE(LMNRST)-3^ KE +! SAL GETTE$ KET +! SAL G(CK)- _ +! SAL GG- _ +! SAL GI(AO)-^ I +! SAL GION$ KIUN +! SAL GIUS-^ IU +! SAL GMBH^$ GMPH +! SAL GNAC$ NIAK +! SAL GNON$ NIUN +! SAL GN$ N +! SAL GONCAL-^ KUNZA +! SAL GS(CH)-- K +! SAL GST XT +! SAL G(SßXZ) X +! SAL GUCK- KU +! SAL GUI-^ K +! SAL G K +! SAL HEAD- E +! SAL HE(LMNRST)-3^ E +! SAL HE(LMN)-1 E +! SAL HEUR1$ ÖR +! SAL H^ _ +! SAL IEC$ IZ +! SAL IEI-3 _ +! SAL IELL3 IEL +! SAL IENNE$ IN +! SAL IERRE$ IER +! SAL IETTE$ IT +! SAL IEU IÖ +! SAL IE<4 I +! SAL IGHT3$ EIT +! SAL IGNI(EO)- INI +! SAL IGN(AEOU)-$ INI +! SAL IJ(AOU)- I +! SAL IJ$ I +! SAL IJ< EI +! SAL IKOLE$ IKUL +! SAL ILLAN(STZ)-- ILIA +! SAL ILLAR(DT)-- ILIA +! SAL INVER- INFE +! SAL ITI(AÄOÖUÜ)- IZI +! SAL IVIER$ IFIE +! SAL I I +! SAL JAVIE---<^ ZA +! SAL JEAN^$ IA +! SAL JEAN-^ IA +! SAL JER-^ IE +! SAL JE(LMNST)- IE +! SAL JOR(GK)^$ IÖRK +! SAL J I +! SAL KC(ÄEIJ)- X +! SAL KE(LMNRST)-3^ KE +! SAL KH<^ K +! SAL KIC$ KIZ +! SAL KLE(LMNRST)-3^ KLE +! SAL KOTELE-^ KUTL +! SAL KREAT-^ KREA +! SAL KST XT +! SAL K(SßXZ) X +! SAL KTI(AIOU)-3 XI +! SAL KT(SßXZ) X +! SAL K K +! SAL LARVE- LARF +! SAL LEAND-^ LEAN +! SAL LEL- LE +! SAL LE(MNRST)-3^ LE +! SAL LETTE$ LET +! SAL LFGNAG- LFKAN +! SAL LIC$ LIZ +! SAL LIVE^$ LEIF +! SAL LUI(GS)-- LU +! SAL L L +! SAL MASSEU(RS)- NAZÖ +! SAL MAURICE NURIZ +! SAL MBH^$ MPH +! SAL MB(SßZ)- N +! SAL MC9^ NK +! SAL MEMOIR-^ NENUA +! SAL ME(LMNRST)-3^ NE +! SAL MIGUEL NIKL +! SAL MIKE^$ NEIK +! SAL MN N +! SAL MPJUTE- NPUT +! SAL MP(SßZ)- N +! SAL MP(BDJLMNPQRTVW)- NP +! SAL M N +! SAL NACH^^ NAK +! SAL NADINE NATIN +! SAL NAIV-- NA +! SAL NAISE$ NEZE +! SAL NCOISE$ ZUA +! SAL NCOIS$ ZUA +! SAL NEBEN^^ NEPN +! SAL NE(LMNRST)-3^ NE +! SAL NEN-3 NE +! SAL NETTE$ NET +! SAL NG(BDFJLMNPQRTVW)- NK +! SAL NICHTS^^ NIX +! SAL NICHT^^ NIKT +! SAL NINE$ NIN +! SAL NON^^ NUN +! SAL NOT^^ NUT +! SAL NTI(AIOU)-3 NZI +! SAL NTIEL--3 NZI +! SAL NYLON NEILUN +! SAL ND(SßZ)$ NZ +! SAL NT(SßZ)$ NZ +! SAL ND'S$ NZ +! SAL NT'S$ NZ +! SAL NSTS$ NZ +! SAL N N +! SAL OBER^^ UPA +! SAL OE2 Ö +! SAL OGNIE- UNI +! SAL OGN(AEOU)-$ UNI +! SAL OIE$ Ö +! SAL OIR$ UAR +! SAL OIX UA +! SAL OI<3 EU +! SAL OJ(AÄEIOÖUÜ)-- U +! SAL OKAY^$ UKE +! SAL OLYN$ ULIN +! SAL OTI(AÄOÖUÜ)- UZI +! SAL OUI^ FI +! SAL OUILLE$ ULIE +! SAL OU(DT)-^ AU +! SAL OUSE$ AUZ +! SAL OUT- AU +! SAL OU U +! SAL OWS$ UZ +! SAL OY(AÄEIOÖUÜ)-- U +! SAL O(JY)< EU +! SAL O U +! SAL PATIEN--^ PAZI +! SAL PENSIO-^ PANZI +! SAL PE(LMNRST)-3^ PE +! SAL PFER-^ FE +! SAL P(FH)< F +! SAL POLY^^ PULI +! SAL PORTRAIT7 PURTRE +! SAL PP(FH)--< P +! SAL PP- _ +! SAL PRIX^$ PRI +! SAL P(SßZ)^ Z +! SAL PTI(AÄOÖUÜ)-3 PZI +! SAL PIC^$ PIK +! SAL P P +! SAL QUE(LMNRST)-3 KFE +! SAL QUE$ K +! SAL QUI(NS)$ KI +! SAL QU KF +! SAL Q< K +! SAL RCH RK +! SAL RECHERCH^ REZAZ +! SAL RER$ RA +! SAL RE(MNR)-4 RE +! SAL RETTE$ RET +! SAL RH<^ R +! SAL RJA(MN)-- RI +! SAL RTI(AÄOÖUÜ)-3 RZI +! SAL RY(KN)-$ RI +! SAL R R +! SAL SAFE^$ ZEIF +! SAL SAUCE-^ ZUZ +! SAL SCHSCH---7 _ +! SAL SCHTSCH Z +! SAL SC(HZ)< Z +! SAL SC ZK +! SAL SELBSTST--7^^ ZELP +! SAL SELBST7^^ ZELPZT +! SAL SERVICE7^ ZÖRFIZ +! SAL SE(LMNRST)-3^ ZE +! SAL SETTE$ ZET +! SAL SHP-^ Z +! SAL SHST ZT +! SAL SHTSH Z +! SAL SHT Z +! SAL SH3 Z +! SAL SIEGLI-^ ZIKL +! SAL SIGLI-^ ZIKL +! SAL SIGHT ZEIT +! SAL SIGN ZEIN +! SAL SKI(NPZ)- ZKI +! SAL SKI<^ ZI +! SAL SOUND- ZAUN +! SAL STAATS^^ ZTAZ +! SAL STADT^^ ZTAT +! SAL START^^ ZTART +! SAL STAURANT7 ZTURAN +! SAL STEAK- ZTE +! SAL STRAF^^ ZTRAF +! SAL ST'S$ Z +! SAL STST-- _ +! SAL STS(ACEHIOUÄÜÖ)-- ZT +! SAL ST(SZ) Z +! SAL STYN(AE)-$ ZTIN +! SAL ST ZT +! SAL SZE(NPT)-^ ZE +! SAL SZI(ELN)-^ ZI +! SAL SZCZ< Z +! SAL SZT< ZT +! SAL SZ<3 Z +! SAL S Z +! SAL T'S3$ Z +! SAL TCH Z +! SAL TEAT-^ TEA +! SAL TE(LMNRST)-3^ TE +! SAL TH< T +! SAL TIC$ TIZ +! SAL TOAS-^ TU +! SAL TOILET- TULE +! SAL TOIN- TUA +! SAL TRAINI- TREN +! SAL TSCH Z +! SAL TSH Z +! SAL TST ZT +! SAL T(Sß) Z +! SAL TT(SZ)--< _ +! SAL TT9 T +! SAL TZ- _ +! SAL T T +! SAL UEBER^^ IPA +! SAL UE2 I +! SAL UIE$ I +! SAL UM^^ UN +! SAL UNTERE-- UNTE +! SAL UNTER^^ UNTA +! SAL UNVER^^ UNFA +! SAL UN^^ UN +! SAL UTI(AÄOÖUÜ)- UZI +! SAL U U +! SAL VACL-^ FAZ +! SAL VAC$ FAZ +! SAL VEDD-^ FE +! SAL VEREIN FAEIN +! SAL VERSEN^ FAZN +! SAL VER^^ FA +! SAL VER FA +! SAL VET(HT)-^ FET +! SAL VETTE$ FET +! SAL VIC$ FIZ +! SAL VIEL FIL +! SAL VIEW FIU +! SAL VOR^^ FUR +! SAL VY9^ FI +! SAL V< F +! SAL WE(LMNRST)-3^ FE +! SAL WIC$ FIZ +! SAL WIEDER^^ FITA +! SAL WY9^ FI +! SAL W F +! SAL XE(LMNRST)-3^ XE +! SAL X<^ Z +! SAL X(CSZ) X +! SAL XTS(CH)-- XT +! SAL XT(SZ) Z +! SAL X X +! SAL YE(LMNRST)-3^ IE +! SAL YE-3 I +! SAL YOR(GK)^$ IÖRK +! SAL Y(AOU)-<7 I +! SAL YVES^$ IF +! SAL YVONNE^$ IFUN +! SAL Y I +! SAL ZC(AOU)- ZK +! SAL ZE(LMNRST)-3^ ZE +! SAL ZH< Z +! SAL ZS(CHT)-- _ +! SAL ZS Z +! SAL ZUERST ZUERZT +! SAL ZURÜCK^^ ZURIK +! SAL ZUVER^^ ZUFA # x +! SAL Z Z diff --git a/runtime/spell/de/de_DE.diff b/runtime/spell/de/de_DE.diff index 24e76ef0b4..bbac7a0b64 100644 --- a/runtime/spell/de/de_DE.diff +++ b/runtime/spell/de/de_DE.diff @@ -1,10 +1,9 @@ -*** de_DE.orig.aff Sat Nov 26 19:59:50 2005 ---- de_DE.aff Sat Nov 26 20:25:08 2005 +*** de_DE.orig.aff 2019-01-19 18:45:26.132522538 +0100 +--- de_DE.aff 2019-01-19 19:23:37.233297530 +0100 *************** -*** 2,3 **** ---- 2,21 ---- - TRY esianrtolcdugmphbyfvkwäüößáéêàâñESIANRTOLCDUGMPHBYFVKWÄÜÖ -+ +*** 15,16 **** +--- 15,46 ---- + + FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ + LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ + UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ @@ -22,512 +21,560 @@ + MAP yÿý + MAP sß + - # ++ COMPOUNDRULE xy?z ++ #COMPOUNDBEGIN x ++ #COMPOUNDMIDDLE y ++ #COMPOUNDEND z ++ ++ # Prefixes are allowed at the beginning of compounds, ++ # suffixes are allowed at the end of compounds by default: ++ # (prefix)?(root)+(affix)? ++ # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. ++ COMPOUNDPERMITFLAG c ++ ++ ONLYINCOMPOUND o ++ + PFX U Y 1 *************** -*** 28,31 **** - PFX V Y 1 -! PFX V 0 ver . -! - ---- 46,49 ---- - PFX V Y 1 -! PFX V 0 ver . +*** 536,553 **** + #LANG de_DE +! CHECKSHARPS ! +- COMPOUNDBEGIN x +- COMPOUNDMIDDLE y +- COMPOUNDEND z + FORBIDDENWORD d + +- # Prefixes are allowed at the beginning of compounds, +- # suffixes are allowed at the end of compounds by default: +- # (prefix)?(root)+(affix)? +- # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. +- COMPOUNDPERMITFLAG c +- +- ONLYINCOMPOUND o +- + # my PSEUDOROOT h(elper) flag +--- 566,571 ---- + #LANG de_DE +! # CHECKSHARPS + + FORBIDDENWORD d + + # my PSEUDOROOT h(elper) flag *************** -*** 235,237 **** - SFX F arzt ärztin arzt -! SFX F arzt Ärztinnen arzt - SFX F Arzt Ärztin Arzt ---- 253,255 ---- - SFX F arzt ärztin arzt -! SFX F arzt ärztinnen arzt - SFX F Arzt Ärztin Arzt +*** 571,573 **** + +! WORDCHARS ß-. + +--- 589,591 ---- + +! # WORDCHARS ß-. + *************** -*** 1410 **** ---- 1428,1904 ---- - REP ö öe -+ -+ # German phonetic transformation rules from Aspell -+ # Copyright (C) 2000 Björn Jacke, distributed under LGPL. -+ # Björn Jacke may be reached by email at bjoern.jacke@gmx.de -+ # Last changed 2000-01-07 -+ -+ SAL followup 1 -+ SAL collapse_result 1 -+ -+ SAL ÄER- E -+ SAL ÄU< EU -+ SAL Ä< E -+ SAL É E -+ SAL ÖER- Ö -+ SAL Ö Ö -+ SAL ÜBER^^ IPA -+ SAL ÜER- I -+ SAL Ü I -+ SAL ß Z -+ SAL ABELLE$ APL -+ SAL ABELL$ APL -+ SAL ABIENNE$ APIN -+ SAL ACEY$ AZI -+ SAL AEU< EU -+ SAL AE2 E -+ SAL AGNI-^ AKN -+ SAL AGNIE- ANI -+ SAL AGN(AEOU)-$ ANI -+ SAL AIA2 AIA -+ SAL AIE$ E -+ SAL AILL(EOU)- ALI -+ SAL AINE$ EN -+ SAL AIRE$ ER -+ SAL AIR- E -+ SAL AISE$ EZ -+ SAL AISSANCE$ EZANZ -+ SAL AISSE$ EZ -+ SAL AIX$ EX -+ SAL AJ(AÄEIOÖUÜ)-- A -+ SAL AKTIE AXIE -+ SAL ALO(IY)^ ALUI -+ SAL AMATEU(RS)- ANATÖ -+ SAL ANIELLE$ ANIL -+ SAL ANTI^^ ANTI -+ SAL ANVER^^ ANFA -+ SAL ATIA$ ATIA -+ SAL ATIA(NS)-- ATI -+ SAL ATI(AÄOÖUÜ)- AZI -+ SAL AUAU-- _ -+ SAL AUER< AUA -+ SAL AUF^^ AUF -+ SAL AULT$ U -+ SAL AUSSE$ UZ -+ SAL AUS(ST)-^ AUZ -+ SAL AUS^^ AUZ -+ SAL AUTO^^ AUTU -+ SAL AUX(IY)- AUX -+ SAL AUX U -+ SAL AU AU -+ SAL AVIER$ AFIE -+ SAL AYER--< EI -+ SAL AY(AÄEIOÖUÜ)-- A -+ SAL A(IJY)< EI -+ SAL A A -+ SAL BEA(BCMNRU)-^ PEA -+ SAL BEAT(AEIMORU)-^ PEAT -+ SAL BEIGE^$ PEZ -+ SAL BE(LMNRST)-^ PE -+ SAL BETTE$ PET -+ SAL BIC$ PIZ -+ SAL BOWL(EI)- PUL -+ SAL BP(AÄEIOÖRUÜY)- P -+ SAL BUDGET7 PIKE -+ SAL BUFFET7 PIFE -+ SAL BYLLE$ PILE -+ SAL BYLL$ PIL -+ SAL BYTE< PEIT -+ SAL B P -+ SAL CÄ- Z -+ SAL CÜ$ ZI -+ SAL CACH(EI)-^ KEZ -+ SAL CAE-- Z -+ SAL CA(IY)$ ZEI -+ SAL CCH Z -+ SAL CCE- X -+ SAL CE(EIJUY)-- Z -+ SAL CENT< ZENT -+ SAL CERST(EI)----^ KE -+ SAL CER$ ZA -+ SAL CE3 ZE -+ SAL CHAO(ST)- KAU -+ SAL CHAMPIO-^ ZENPI -+ SAL CHAR(AI)-^ KAR -+ SAL CHAU(CDFSVWXZ)- ZU -+ SAL CHE(CF)- ZE -+ SAL CHEM-^ KE -+ SAL CHEQUE< ZEK -+ SAL CHI(CFGPVW)- ZI -+ SAL CH(AEUY)-<^ Z -+ SAL CHK- _ -+ SAL CH(LOR)-<^ K -+ SAL CHST- X -+ SAL CH(SßXZ)3 X -+ SAL CH K -+ SAL CIER$ ZIE -+ SAL CYB-^ ZEI -+ SAL CY9^ ZI -+ SAL C(IJY)-3 Z -+ SAL CKST XT -+ SAL CK(SßXZ)3 X -+ SAL C(CK)- _ -+ SAL CLAUDET--- KLU -+ SAL CLAUDINE^$ KLUTIN -+ SAL COLE$ KUL -+ SAL COUCH KAUZ -+ SAL CQUES$ K -+ SAL CQUE K -+ SAL CREAT-^ KREA -+ SAL CST XT -+ SAL CS<^ Z -+ SAL C(SßX) X -+ SAL CT(SßXZ) X -+ SAL CZ< Z -+ SAL C< K -+ SAL D'H^ T -+ SAL D'S3$ Z -+ SAL DAVO(NR)-^$ TAFU -+ SAL DD(SZ)--< _ -+ SAL DEPOT7 TEPU -+ SAL DESIGN TIZEIN -+ SAL DE(LMNRST)-3^ TE -+ SAL DETTE$ TET -+ SAL DIC$ TIZ -+ SAL DJ(AEIOU)-^ I -+ SAL DS(CH)--< T -+ SAL DST ZT -+ SAL DT- _ -+ SAL DUIS-^ TI -+ SAL DURCH^^ TURK -+ SAL DZS(CH)-- T -+ SAL D(SßZ) Z -+ SAL D T -+ SAL EAULT$ U -+ SAL EAUX$ U -+ SAL EAU U -+ SAL EAV IF -+ SAL EA(AÄEIOÖÜY)-3 EA -+ SAL EA3$ EA -+ SAL EA3 I -+ SAL EBEN^^ EPN -+ SAL EE9 E -+ SAL EIEI-- _ -+ SAL EIH-- E -+ SAL EILLE$ EI -+ SAL EI EI -+ SAL EJ$ EI -+ SAL EL-^ E -+ SAL EL(DKL)--1 E -+ SAL EL(MNT)--1$ E -+ SAL ELYNE$ ELINE -+ SAL ELYN$ ELIN -+ SAL EL(AÄEIOÖUÜY)-1 EL -+ SAL EL-1 L -+ SAL EM-^ E -+ SAL EM(DFKMPQT)--1 E -+ SAL EM(AÄEIOÖUÜY)--1 E -+ SAL EM-1 N -+ SAL EN-^ E -+ SAL EN(CDGKQT)--1 E -+ SAL ENZ(AEIOUY)--1 EN -+ SAL EN(AÄEINOÖUÜY)-1 EN -+ SAL EN-<1 N -+ SAL ERH(AÄEIOÖUÜ)-^ ER -+ SAL ER-^ E -+ SAL ER(AÄEIOÖUÜY)-1 A -+ SAL ER1$ A -+ SAL ER<1 A -+ SAL ETI(AÄOÖÜU)- EZI -+ SAL EUEU-- _ -+ SAL EUILLE$ Ö -+ SAL EUR$ ÖR -+ SAL EUX Ö -+ SAL EUYS$ EUZ -+ SAL EU EU -+ SAL EYER< EIA -+ SAL EY< EI -+ SAL E E -+ SAL FANS--^$ FE -+ SAL FAN-^$ FE -+ SAL FAULT- FUL -+ SAL FEE(DL)- FI -+ SAL FEHLER FELA -+ SAL FE(LMNRST)-3^ FE -+ SAL FOND7 FUN -+ SAL FRAIN$ FRA -+ SAL FRISEU(RS)- FRIZÖ # x -+ SAL F F -+ SAL G'S$ X -+ SAL GAGS^$ KEX -+ SAL GAG^$ KEK -+ SAL GD KT -+ SAL GEGEN^^ KEKN -+ SAL GE(LMNRST)-3^ KE -+ SAL GETTE$ KET -+ SAL G(CK)- _ -+ SAL GG- _ -+ SAL GI(AO)-^ I -+ SAL GION$ KIUN -+ SAL GIUS-^ IU -+ SAL GMBH^$ GMPH -+ SAL GNAC$ NIAK -+ SAL GNON$ NIUN -+ SAL GN$ N -+ SAL GONCAL-^ KUNZA -+ SAL GS(CH)-- K -+ SAL GST XT -+ SAL G(SßXZ) X -+ SAL GUCK- KU -+ SAL GUI-^ K -+ SAL G K -+ SAL HEAD- E -+ SAL HE(LMNRST)-3^ E -+ SAL HE(LMN)-1 E -+ SAL HEUR1$ ÖR -+ SAL H^ _ -+ SAL IEC$ IZ -+ SAL IEI-3 _ -+ SAL IELL3 IEL -+ SAL IENNE$ IN -+ SAL IERRE$ IER -+ SAL IETTE$ IT -+ SAL IEU IÖ -+ SAL IE<4 I -+ SAL IGHT3$ EIT -+ SAL IGNI(EO)- INI -+ SAL IGN(AEOU)-$ INI -+ SAL IJ(AOU)- I -+ SAL IJ$ I -+ SAL IJ< EI -+ SAL IKOLE$ IKUL -+ SAL ILLAN(STZ)-- ILIA -+ SAL ILLAR(DT)-- ILIA -+ SAL INVER- INFE -+ SAL ITI(AÄOÖUÜ)- IZI -+ SAL IVIER$ IFIE -+ SAL I I -+ SAL JAVIE---<^ ZA -+ SAL JEAN^$ IA -+ SAL JEAN-^ IA -+ SAL JER-^ IE -+ SAL JE(LMNST)- IE -+ SAL JOR(GK)^$ IÖRK -+ SAL J I -+ SAL KC(ÄEIJ)- X -+ SAL KE(LMNRST)-3^ KE -+ SAL KH<^ K -+ SAL KIC$ KIZ -+ SAL KLE(LMNRST)-3^ KLE -+ SAL KOTELE-^ KUTL -+ SAL KREAT-^ KREA -+ SAL KST XT -+ SAL K(SßXZ) X -+ SAL KTI(AIOU)-3 XI -+ SAL KT(SßXZ) X -+ SAL K K -+ SAL LARVE- LARF -+ SAL LEAND-^ LEAN -+ SAL LEL- LE -+ SAL LE(MNRST)-3^ LE -+ SAL LETTE$ LET -+ SAL LFGNAG- LFKAN -+ SAL LIC$ LIZ -+ SAL LIVE^$ LEIF -+ SAL LUI(GS)-- LU -+ SAL L L -+ SAL MASSEU(RS)- NAZÖ -+ SAL MAURICE NURIZ -+ SAL MBH^$ MPH -+ SAL MB(SßZ)- N -+ SAL MC9^ NK -+ SAL MEMOIR-^ NENUA -+ SAL ME(LMNRST)-3^ NE -+ SAL MIGUEL NIKL -+ SAL MIKE^$ NEIK -+ SAL MN N -+ SAL MPJUTE- NPUT -+ SAL MP(SßZ)- N -+ SAL MP(BDJLMNPQRTVW)- NP -+ SAL M N -+ SAL NACH^^ NAK -+ SAL NADINE NATIN -+ SAL NAIV-- NA -+ SAL NAISE$ NEZE -+ SAL NCOISE$ ZUA -+ SAL NCOIS$ ZUA -+ SAL NEBEN^^ NEPN -+ SAL NE(LMNRST)-3^ NE -+ SAL NEN-3 NE -+ SAL NETTE$ NET -+ SAL NG(BDFJLMNPQRTVW)- NK -+ SAL NICHTS^^ NIX -+ SAL NICHT^^ NIKT -+ SAL NINE$ NIN -+ SAL NON^^ NUN -+ SAL NOT^^ NUT -+ SAL NTI(AIOU)-3 NZI -+ SAL NTIEL--3 NZI -+ SAL NYLON NEILUN -+ SAL ND(SßZ)$ NZ -+ SAL NT(SßZ)$ NZ -+ SAL ND'S$ NZ -+ SAL NT'S$ NZ -+ SAL NSTS$ NZ -+ SAL N N -+ SAL OBER^^ UPA -+ SAL OE2 Ö -+ SAL OGNIE- UNI -+ SAL OGN(AEOU)-$ UNI -+ SAL OIE$ Ö -+ SAL OIR$ UAR -+ SAL OIX UA -+ SAL OI<3 EU -+ SAL OJ(AÄEIOÖUÜ)-- U -+ SAL OKAY^$ UKE -+ SAL OLYN$ ULIN -+ SAL OTI(AÄOÖUÜ)- UZI -+ SAL OUI^ FI -+ SAL OUILLE$ ULIE -+ SAL OU(DT)-^ AU -+ SAL OUSE$ AUZ -+ SAL OUT- AU -+ SAL OU U -+ SAL OWS$ UZ -+ SAL OY(AÄEIOÖUÜ)-- U -+ SAL O(JY)< EU -+ SAL O U -+ SAL PATIEN--^ PAZI -+ SAL PENSIO-^ PANZI -+ SAL PE(LMNRST)-3^ PE -+ SAL PFER-^ FE -+ SAL P(FH)< F -+ SAL POLY^^ PULI -+ SAL PORTRAIT7 PURTRE -+ SAL PP(FH)--< P -+ SAL PP- _ -+ SAL PRIX^$ PRI -+ SAL P(SßZ)^ Z -+ SAL PTI(AÄOÖUÜ)-3 PZI -+ SAL PIC^$ PIK -+ SAL P P -+ SAL QUE(LMNRST)-3 KFE -+ SAL QUE$ K -+ SAL QUI(NS)$ KI -+ SAL QU KF -+ SAL Q< K -+ SAL RCH RK -+ SAL RECHERCH^ REZAZ -+ SAL RER$ RA -+ SAL RE(MNR)-4 RE -+ SAL RETTE$ RET -+ SAL RH<^ R -+ SAL RJA(MN)-- RI -+ SAL RTI(AÄOÖUÜ)-3 RZI -+ SAL RY(KN)-$ RI -+ SAL R R -+ SAL SAFE^$ ZEIF -+ SAL SAUCE-^ ZUZ -+ SAL SCHSCH---7 _ -+ SAL SCHTSCH Z -+ SAL SC(HZ)< Z -+ SAL SC ZK -+ SAL SELBSTST--7^^ ZELP -+ SAL SELBST7^^ ZELPZT -+ SAL SERVICE7^ ZÖRFIZ -+ SAL SE(LMNRST)-3^ ZE -+ SAL SETTE$ ZET -+ SAL SHP-^ Z -+ SAL SHST ZT -+ SAL SHTSH Z -+ SAL SHT Z -+ SAL SH3 Z -+ SAL SIEGLI-^ ZIKL -+ SAL SIGLI-^ ZIKL -+ SAL SIGHT ZEIT -+ SAL SIGN ZEIN -+ SAL SKI(NPZ)- ZKI -+ SAL SKI<^ ZI -+ SAL SOUND- ZAUN -+ SAL STAATS^^ ZTAZ -+ SAL STADT^^ ZTAT -+ SAL START^^ ZTART -+ SAL STAURANT7 ZTURAN -+ SAL STEAK- ZTE -+ SAL STRAF^^ ZTRAF -+ SAL ST'S$ Z -+ SAL STST-- _ -+ SAL STS(ACEHIOUÄÜÖ)-- ZT -+ SAL ST(SZ) Z -+ SAL STYN(AE)-$ ZTIN -+ SAL ST ZT -+ SAL SZE(NPT)-^ ZE -+ SAL SZI(ELN)-^ ZI -+ SAL SZCZ< Z -+ SAL SZT< ZT -+ SAL SZ<3 Z -+ SAL S Z -+ SAL T'S3$ Z -+ SAL TCH Z -+ SAL TEAT-^ TEA -+ SAL TE(LMNRST)-3^ TE -+ SAL TH< T -+ SAL TIC$ TIZ -+ SAL TOAS-^ TU -+ SAL TOILET- TULE -+ SAL TOIN- TUA -+ SAL TRAINI- TREN -+ SAL TSCH Z -+ SAL TSH Z -+ SAL TST ZT -+ SAL T(Sß) Z -+ SAL TT(SZ)--< _ -+ SAL TT9 T -+ SAL TZ- _ -+ SAL T T -+ SAL UEBER^^ IPA -+ SAL UE2 I -+ SAL UIE$ I -+ SAL UM^^ UN -+ SAL UNTERE-- UNTE -+ SAL UNTER^^ UNTA -+ SAL UNVER^^ UNFA -+ SAL UN^^ UN -+ SAL UTI(AÄOÖUÜ)- UZI -+ SAL U U -+ SAL VACL-^ FAZ -+ SAL VAC$ FAZ -+ SAL VEDD-^ FE -+ SAL VEREIN FAEIN -+ SAL VERSEN^ FAZN -+ SAL VER^^ FA -+ SAL VER FA -+ SAL VET(HT)-^ FET -+ SAL VETTE$ FET -+ SAL VIC$ FIZ -+ SAL VIEL FIL -+ SAL VIEW FIU -+ SAL VOR^^ FUR -+ SAL VY9^ FI -+ SAL V< F -+ SAL WE(LMNRST)-3^ FE -+ SAL WIC$ FIZ -+ SAL WIEDER^^ FITA -+ SAL WY9^ FI -+ SAL W F -+ SAL XE(LMNRST)-3^ XE -+ SAL X<^ Z -+ SAL X(CSZ) X -+ SAL XTS(CH)-- XT -+ SAL XT(SZ) Z -+ SAL X X -+ SAL YE(LMNRST)-3^ IE -+ SAL YE-3 I -+ SAL YOR(GK)^$ IÖRK -+ SAL Y(AOU)-<7 I -+ SAL YVES^$ IF -+ SAL YVONNE^$ IFUN -+ SAL Y I -+ SAL ZC(AOU)- ZK -+ SAL ZE(LMNRST)-3^ ZE -+ SAL ZH< Z -+ SAL ZS(CHT)-- _ -+ SAL ZS Z -+ SAL ZUERST ZUERZT -+ SAL ZURÜCK^^ ZURIK -+ SAL ZUVER^^ ZUFA # x -+ SAL Z Z -*** de_DE.orig.dic Sat Nov 26 19:59:52 2005 ---- de_DE.dic Mon Jan 2 15:35:27 2006 -*************** -*** 1,3 **** - 319017 -- 23508 - A-Bombe/N ---- 1,2 ---- +*** 725,729 **** + # So enabling this is the lesser evil. No perfect solution found so far... +! BREAK 2 +! BREAK - +! BREAK . +! +--- 743,1241 ---- + # So enabling this is the lesser evil. No perfect solution found so far... +! # BREAK 2 +! # BREAK - +! # BREAK . +! +! # German phonetic transformation rules for use with Aspell +! # Copyright (C) 2000 Björn Jacke +! # +! # This library is free software; you can redistribute it and/or +! # modify it under the terms of the GNU Lesser General Public +! # License version 2.1 as published by the Free Software Foundation; +! # +! # This library is distributed in the hope that it will be useful, +! # but WITHOUT ANY WARRANTY; without even the implied warranty of +! # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +! # Lesser General Public License for more details. +! # +! # You should have received a copy of the GNU Lesser General Public +! # License along with this library; if not, write to the Free Software +! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +! # +! # Björn Jacke may be reached by email at bjoern.jacke@gmx.de +! # +! # Changelog: +! # +! # 2000-01-05 Björn Jacke +! # Initial Release +! # 2000-01-07 Kevin Atkinson +! # Converted from header to data file. +! SAL followup 1 +! SAL collapse_result 1 +! +! SAL ÄER- E +! SAL ÄU< EU +! SAL Ä< E +! SAL É E +! SAL ÖER- Ö +! SAL Ö Ö +! SAL ÜBER^^ IPA +! SAL ÜER- I +! SAL Ü I +! SAL ß Z +! SAL ABELLE$ APL +! SAL ABELL$ APL +! SAL ABIENNE$ APIN +! SAL ACEY$ AZI +! SAL AEU< EU +! SAL AE2 E +! SAL AGNI-^ AKN +! SAL AGNIE- ANI +! SAL AGN(AEOU)-$ ANI +! SAL AIA2 AIA +! SAL AIE$ E +! SAL AILL(EOU)- ALI +! SAL AINE$ EN +! SAL AIRE$ ER +! SAL AIR- E +! SAL AISE$ EZ +! SAL AISSANCE$ EZANZ +! SAL AISSE$ EZ +! SAL AIX$ EX +! SAL AJ(AÄEIOÖUÜ)-- A +! SAL AKTIE AXIE +! SAL ALO(IY)^ ALUI +! SAL AMATEU(RS)- ANATÖ +! SAL ANIELLE$ ANIL +! SAL ANTI^^ ANTI +! SAL ANVER^^ ANFA +! SAL ATIA$ ATIA +! SAL ATIA(NS)-- ATI +! SAL ATI(AÄOÖUÜ)- AZI +! SAL AUAU-- _ +! SAL AUER< AUA +! SAL AUF^^ AUF +! SAL AULT$ U +! SAL AUSSE$ UZ +! SAL AUS(ST)-^ AUZ +! SAL AUS^^ AUZ +! SAL AUTO^^ AUTU +! SAL AUX(IY)- AUX +! SAL AUX U +! SAL AU AU +! SAL AVIER$ AFIE +! SAL AYER--< EI +! SAL AY(AÄEIOÖUÜ)-- A +! SAL A(IJY)< EI +! SAL A A +! SAL BEA(BCMNRU)-^ PEA +! SAL BEAT(AEIMORU)-^ PEAT +! SAL BEIGE^$ PEZ +! SAL BE(LMNRST)-^ PE +! SAL BETTE$ PET +! SAL BIC$ PIZ +! SAL BOWL(EI)- PUL +! SAL BP(AÄEIOÖRUÜY)- P +! SAL BUDGET7 PIKE +! SAL BUFFET7 PIFE +! SAL BYLLE$ PILE +! SAL BYLL$ PIL +! SAL BYTE< PEIT +! SAL B P +! SAL CÄ- Z +! SAL CÜ$ ZI +! SAL CACH(EI)-^ KEZ +! SAL CAE-- Z +! SAL CA(IY)$ ZEI +! SAL CCH Z +! SAL CCE- X +! SAL CE(EIJUY)-- Z +! SAL CENT< ZENT +! SAL CERST(EI)----^ KE +! SAL CER$ ZA +! SAL CE3 ZE +! SAL CHAO(ST)- KAU +! SAL CHAMPIO-^ ZENPI +! SAL CHAR(AI)-^ KAR +! SAL CHAU(CDFSVWXZ)- ZU +! SAL CHE(CF)- ZE +! SAL CHEM-^ KE +! SAL CHEQUE< ZEK +! SAL CHI(CFGPVW)- ZI +! SAL CH(AEUY)-<^ Z +! SAL CHK- _ +! SAL CH(LOR)-<^ K +! SAL CHST- X +! SAL CH(SßXZ)3 X +! SAL CH K +! SAL CIER$ ZIE +! SAL CYB-^ ZEI +! SAL CY9^ ZI +! SAL C(IJY)-3 Z +! SAL CKST XT +! SAL CK(SßXZ)3 X +! SAL C(CK)- _ +! SAL CLAUDET--- KLU +! SAL CLAUDINE^$ KLUTIN +! SAL COLE$ KUL +! SAL COUCH KAUZ +! SAL CQUES$ K +! SAL CQUE K +! SAL CREAT-^ KREA +! SAL CST XT +! SAL CS<^ Z +! SAL C(SßX) X +! SAL CT(SßXZ) X +! SAL CZ< Z +! SAL C< K +! SAL D'H^ T +! SAL D'S3$ Z +! SAL DAVO(NR)-^$ TAFU +! SAL DD(SZ)--< _ +! SAL DEPOT7 TEPU +! SAL DESIGN TIZEIN +! SAL DE(LMNRST)-3^ TE +! SAL DETTE$ TET +! SAL DIC$ TIZ +! SAL DJ(AEIOU)-^ I +! SAL DS(CH)--< T +! SAL DST ZT +! SAL DT- _ +! SAL DUIS-^ TI +! SAL DURCH^^ TURK +! SAL DZS(CH)-- T +! SAL D(SßZ) Z +! SAL D T +! SAL EAULT$ U +! SAL EAUX$ U +! SAL EAU U +! SAL EAV IF +! SAL EA(AÄEIOÖÜY)-3 EA +! SAL EA3$ EA +! SAL EA3 I +! SAL EBEN^^ EPN +! SAL EE9 E +! SAL EIEI-- _ +! SAL EIH-- E +! SAL EILLE$ EI +! SAL EI EI +! SAL EJ$ EI +! SAL EL-^ E +! SAL EL(DKL)--1 E +! SAL EL(MNT)--1$ E +! SAL ELYNE$ ELINE +! SAL ELYN$ ELIN +! SAL EL(AÄEIOÖUÜY)-1 EL +! SAL EL-1 L +! SAL EM-^ E +! SAL EM(DFKMPQT)--1 E +! SAL EM(AÄEIOÖUÜY)--1 E +! SAL EM-1 N +! SAL EN-^ E +! SAL EN(CDGKQT)--1 E +! SAL ENZ(AEIOUY)--1 EN +! SAL EN(AÄEINOÖUÜY)-1 EN +! SAL EN-<1 N +! SAL ERH(AÄEIOÖUÜ)-^ ER +! SAL ER-^ E +! SAL ER(AÄEIOÖUÜY)-1 A +! SAL ER1$ A +! SAL ER<1 A +! SAL ETI(AÄOÖÜU)- EZI +! SAL EUEU-- _ +! SAL EUILLE$ Ö +! SAL EUR$ ÖR +! SAL EUX Ö +! SAL EUYS$ EUZ +! SAL EU EU +! SAL EYER< EIA +! SAL EY< EI +! SAL E E +! SAL FANS--^$ FE +! SAL FAN-^$ FE +! SAL FAULT- FUL +! SAL FEE(DL)- FI +! SAL FEHLER FELA +! SAL FE(LMNRST)-3^ FE +! SAL FOND7 FUN +! SAL FRAIN$ FRA +! SAL FRISEU(RS)- FRIZÖ # x +! SAL F F +! SAL G'S$ X +! SAL GAGS^$ KEX +! SAL GAG^$ KEK +! SAL GD KT +! SAL GEGEN^^ KEKN +! SAL GE(LMNRST)-3^ KE +! SAL GETTE$ KET +! SAL G(CK)- _ +! SAL GG- _ +! SAL GI(AO)-^ I +! SAL GION$ KIUN +! SAL GIUS-^ IU +! SAL GMBH^$ GMPH +! SAL GNAC$ NIAK +! SAL GNON$ NIUN +! SAL GN$ N +! SAL GONCAL-^ KUNZA +! SAL GS(CH)-- K +! SAL GST XT +! SAL G(SßXZ) X +! SAL GUCK- KU +! SAL GUI-^ K +! SAL G K +! SAL HEAD- E +! SAL HE(LMNRST)-3^ E +! SAL HE(LMN)-1 E +! SAL HEUR1$ ÖR +! SAL H^ _ +! SAL IEC$ IZ +! SAL IEI-3 _ +! SAL IELL3 IEL +! SAL IENNE$ IN +! SAL IERRE$ IER +! SAL IETTE$ IT +! SAL IEU IÖ +! SAL IE<4 I +! SAL IGHT3$ EIT +! SAL IGNI(EO)- INI +! SAL IGN(AEOU)-$ INI +! SAL IJ(AOU)- I +! SAL IJ$ I +! SAL IJ< EI +! SAL IKOLE$ IKUL +! SAL ILLAN(STZ)-- ILIA +! SAL ILLAR(DT)-- ILIA +! SAL INVER- INFE +! SAL ITI(AÄOÖUÜ)- IZI +! SAL IVIER$ IFIE +! SAL I I +! SAL JAVIE---<^ ZA +! SAL JEAN^$ IA +! SAL JEAN-^ IA +! SAL JER-^ IE +! SAL JE(LMNST)- IE +! SAL JOR(GK)^$ IÖRK +! SAL J I +! SAL KC(ÄEIJ)- X +! SAL KE(LMNRST)-3^ KE +! SAL KH<^ K +! SAL KIC$ KIZ +! SAL KLE(LMNRST)-3^ KLE +! SAL KOTELE-^ KUTL +! SAL KREAT-^ KREA +! SAL KST XT +! SAL K(SßXZ) X +! SAL KTI(AIOU)-3 XI +! SAL KT(SßXZ) X +! SAL K K +! SAL LARVE- LARF +! SAL LEAND-^ LEAN +! SAL LEL- LE +! SAL LE(MNRST)-3^ LE +! SAL LETTE$ LET +! SAL LFGNAG- LFKAN +! SAL LIC$ LIZ +! SAL LIVE^$ LEIF +! SAL LUI(GS)-- LU +! SAL L L +! SAL MASSEU(RS)- NAZÖ +! SAL MAURICE NURIZ +! SAL MBH^$ MPH +! SAL MB(SßZ)- N +! SAL MC9^ NK +! SAL MEMOIR-^ NENUA +! SAL ME(LMNRST)-3^ NE +! SAL MIGUEL NIKL +! SAL MIKE^$ NEIK +! SAL MN N +! SAL MPJUTE- NPUT +! SAL MP(SßZ)- N +! SAL MP(BDJLMNPQRTVW)- NP +! SAL M N +! SAL NACH^^ NAK +! SAL NADINE NATIN +! SAL NAIV-- NA +! SAL NAISE$ NEZE +! SAL NCOISE$ ZUA +! SAL NCOIS$ ZUA +! SAL NEBEN^^ NEPN +! SAL NE(LMNRST)-3^ NE +! SAL NEN-3 NE +! SAL NETTE$ NET +! SAL NG(BDFJLMNPQRTVW)- NK +! SAL NICHTS^^ NIX +! SAL NICHT^^ NIKT +! SAL NINE$ NIN +! SAL NON^^ NUN +! SAL NOT^^ NUT +! SAL NTI(AIOU)-3 NZI +! SAL NTIEL--3 NZI +! SAL NYLON NEILUN +! SAL ND(SßZ)$ NZ +! SAL NT(SßZ)$ NZ +! SAL ND'S$ NZ +! SAL NT'S$ NZ +! SAL NSTS$ NZ +! SAL N N +! SAL OBER^^ UPA +! SAL OE2 Ö +! SAL OGNIE- UNI +! SAL OGN(AEOU)-$ UNI +! SAL OIE$ Ö +! SAL OIR$ UAR +! SAL OIX UA +! SAL OI<3 EU +! SAL OJ(AÄEIOÖUÜ)-- U +! SAL OKAY^$ UKE +! SAL OLYN$ ULIN +! SAL OTI(AÄOÖUÜ)- UZI +! SAL OUI^ FI +! SAL OUILLE$ ULIE +! SAL OU(DT)-^ AU +! SAL OUSE$ AUZ +! SAL OUT- AU +! SAL OU U +! SAL OWS$ UZ +! SAL OY(AÄEIOÖUÜ)-- U +! SAL O(JY)< EU +! SAL O U +! SAL PATIEN--^ PAZI +! SAL PENSIO-^ PANZI +! SAL PE(LMNRST)-3^ PE +! SAL PFER-^ FE +! SAL P(FH)< F +! SAL POLY^^ PULI +! SAL PORTRAIT7 PURTRE +! SAL PP(FH)--< P +! SAL PP- _ +! SAL PRIX^$ PRI +! SAL P(SßZ)^ Z +! SAL PTI(AÄOÖUÜ)-3 PZI +! SAL PIC^$ PIK +! SAL P P +! SAL QUE(LMNRST)-3 KFE +! SAL QUE$ K +! SAL QUI(NS)$ KI +! SAL QU KF +! SAL Q< K +! SAL RCH RK +! SAL RECHERCH^ REZAZ +! SAL RER$ RA +! SAL RE(MNR)-4 RE +! SAL RETTE$ RET +! SAL RH<^ R +! SAL RJA(MN)-- RI +! SAL RTI(AÄOÖUÜ)-3 RZI +! SAL RY(KN)-$ RI +! SAL R R +! SAL SAFE^$ ZEIF +! SAL SAUCE-^ ZUZ +! SAL SCHSCH---7 _ +! SAL SCHTSCH Z +! SAL SC(HZ)< Z +! SAL SC ZK +! SAL SELBSTST--7^^ ZELP +! SAL SELBST7^^ ZELPZT +! SAL SERVICE7^ ZÖRFIZ +! SAL SE(LMNRST)-3^ ZE +! SAL SETTE$ ZET +! SAL SHP-^ Z +! SAL SHST ZT +! SAL SHTSH Z +! SAL SHT Z +! SAL SH3 Z +! SAL SIEGLI-^ ZIKL +! SAL SIGLI-^ ZIKL +! SAL SIGHT ZEIT +! SAL SIGN ZEIN +! SAL SKI(NPZ)- ZKI +! SAL SKI<^ ZI +! SAL SOUND- ZAUN +! SAL STAATS^^ ZTAZ +! SAL STADT^^ ZTAT +! SAL START^^ ZTART +! SAL STAURANT7 ZTURAN +! SAL STEAK- ZTE +! SAL STRAF^^ ZTRAF +! SAL ST'S$ Z +! SAL STST-- _ +! SAL STS(ACEHIOUÄÜÖ)-- ZT +! SAL ST(SZ) Z +! SAL STYN(AE)-$ ZTIN +! SAL ST ZT +! SAL SZE(NPT)-^ ZE +! SAL SZI(ELN)-^ ZI +! SAL SZCZ< Z +! SAL SZT< ZT +! SAL SZ<3 Z +! SAL S Z +! SAL T'S3$ Z +! SAL TCH Z +! SAL TEAT-^ TEA +! SAL TE(LMNRST)-3^ TE +! SAL TH< T +! SAL TIC$ TIZ +! SAL TOAS-^ TU +! SAL TOILET- TULE +! SAL TOIN- TUA +! SAL TRAINI- TREN +! SAL TSCH Z +! SAL TSH Z +! SAL TST ZT +! SAL T(Sß) Z +! SAL TT(SZ)--< _ +! SAL TT9 T +! SAL TZ- _ +! SAL T T +! SAL UEBER^^ IPA +! SAL UE2 I +! SAL UIE$ I +! SAL UM^^ UN +! SAL UNTERE-- UNTE +! SAL UNTER^^ UNTA +! SAL UNVER^^ UNFA +! SAL UN^^ UN +! SAL UTI(AÄOÖUÜ)- UZI +! SAL U U +! SAL VACL-^ FAZ +! SAL VAC$ FAZ +! SAL VEDD-^ FE +! SAL VEREIN FAEIN +! SAL VERSEN^ FAZN +! SAL VER^^ FA +! SAL VER FA +! SAL VET(HT)-^ FET +! SAL VETTE$ FET +! SAL VIC$ FIZ +! SAL VIEL FIL +! SAL VIEW FIU +! SAL VOR^^ FUR +! SAL VY9^ FI +! SAL V< F +! SAL WE(LMNRST)-3^ FE +! SAL WIC$ FIZ +! SAL WIEDER^^ FITA +! SAL WY9^ FI +! SAL W F +! SAL XE(LMNRST)-3^ XE +! SAL X<^ Z +! SAL X(CSZ) X +! SAL XTS(CH)-- XT +! SAL XT(SZ) Z +! SAL X X +! SAL YE(LMNRST)-3^ IE +! SAL YE-3 I +! SAL YOR(GK)^$ IÖRK +! SAL Y(AOU)-<7 I +! SAL YVES^$ IF +! SAL YVONNE^$ IFUN +! SAL Y I +! SAL ZC(AOU)- ZK +! SAL ZE(LMNRST)-3^ ZE +! SAL ZH< Z +! SAL ZS(CHT)-- _ +! SAL ZS Z +! SAL ZUERST ZUERZT +! SAL ZURÜCK^^ ZURIK +! SAL ZUVER^^ ZUFA # x +! SAL Z Z diff --git a/runtime/spell/de/main.aap b/runtime/spell/de/main.aap index 78dfaabd44..49ec2f25bf 100644 --- a/runtime/spell/de/main.aap +++ b/runtime/spell/de/main.aap @@ -2,7 +2,7 @@ # # Since there is a big discussion about whether to use the old or the new # spelling rules, both have been included. -# "de": all possible words allowed +# "de": new German spelling # "de_de": old and new German spelling # "de_19": old German spelling # "de_20": new German spelling @@ -21,14 +21,21 @@ DE_REGIONS = de_$*REGIONS SPELLDIR = .. FILES = de_$*(REGIONS).aff de_$*(REGIONS).dic -ZIPFILE_DE = de_DE_comb.zip -ZIPFILE_19 = de_OLDSPELL.zip -ZIPFILE_20 = de_DE_neu.zip -ZIPFILE_AT = de_DE.zip -ZIPFILE_CH = de_CH.zip -ZIPFILES = $ZIPFILE_DE $ZIPFILE_19 $ZIPFILE_20 $ZIPFILE_AT $ZIPFILE_CH +# The de_20 is the same as de_DE dictionary and only uses the +# new revised orthography +FILE_DE_AFF = de_DE_frami.aff +FILE_DE_DIC = de_DE_frami.dic +FILE_20_AFF = de_DE_frami.aff +FILE_20_DIC = de_DE_frami.dic +FILE_AT_AFF = de_AT_frami.aff +FILE_AT_DIC = de_AT_frami.dic +FILE_CH_AFF = de_CH_frami.aff +FILE_CH_DIC = de_CH_frami.dic +#ZIPFILES = $ZIPFILE_DE $ZIPFILE_20 $ZIPFILE_AT $ZIPFILE_CH +ZIPFILE_19 = de_OLDSPELL.zip # unmaintained +DICT_FILES = $FILE_20_AFF $FILE_20_DIC $FILE_AT_AFF $FILE_AT_DIC $FILE_CH_AFF $FILE_CH_DIC -READMES = README_de_$*(REGIONS).txt +READMES = README_de_DE_frami.txt README_extension_owner.txt all: $SPELLDIR/de.latin1.spl $SPELLDIR/de.utf-8.spl ../README_de.txt @@ -41,46 +48,39 @@ $SPELLDIR/de.utf-8.spl : $FILES $VIM -u NONE -e -c "mkspell! $SPELLDIR/de $DE_REGIONS" -c q ../README_de.txt: $READMES - :print de_DE (combined) >! $target - :cat README_de_DE.txt >> $target + :fetch $READMES + :print de_DE_frami.txt >! $target + :cat README_de_DE_frami.txt >> $target :print =================================================== >>$target - :print de_19 (old) >> $target - :cat README_de_19.txt >> $target - :print =================================================== >>$target - :print de_20 (new) >> $target - :cat README_de_20.txt >> $target - :print =================================================== >>$target - :print de_AT (Austria) >> $target - :cat README_de_AT.txt >> $target - :print =================================================== >>$target - :print de_CH (Swiss) >> $target - :cat README_de_CH.txt >> $target + :print extension_owner >> $target + :cat README_extension_owner.txt >> $target # -# Fetching the files from the OpenOffice.org site. +# Fetching the files from the LibreOffices github repository. # The OLDSPELL file comes from elsewhere # -OODIR = http://ftp.services.openoffice.org/pub/OpenOffice.org/contrib/dictionaries +OODIR = https://github.com/LibreOffice/dictionaries/raw/master/de DEDIR = http://www.j3e.de/myspell -:attr {fetch = $OODIR/%file%} $ZIPFILES +:attr {fetch = $OODIR/%file%} $DICT_FILES +:attr {fetch = $OODIR/%file%} $READMES :attr {fetch = $DEDIR/%file%} $ZIPFILE_19 # The files don't depend on the .zip file so that we can delete it. # Only download the zip file if the targets don't exist. -de_DE.aff de_DE.dic: {buildcheck=} - :assertpkg unzip patch - :fetch $ZIPFILE_DE - :sys $UNZIP $ZIPFILE_DE - :delete $ZIPFILE_DE - :move de_DE_comb.aff de_DE.aff - :move de_DE_comb.dic de_DE.dic - :move README_de_DE_comb.txt README_de_DE.txt +de_DE.aff de_DE.dic de_20.aff de_20.dic: {buildcheck=} + :assertpkg patch + :fetch $FILE_DE_AFF + :fetch $FILE_DE_DIC + :move de_DE_frami.aff de_DE.aff + :move de_DE_frami.dic de_DE.dic @if not os.path.exists('de_DE.orig.aff'): :copy de_DE.aff de_DE.orig.aff @if not os.path.exists('de_DE.orig.dic'): :copy de_DE.dic de_DE.orig.dic @if os.path.exists('de_DE.diff'): :sys patch !README_de_19.txt @if not os.path.exists('de_19.orig.aff'): :copy de_19.aff de_19.orig.aff @if not os.path.exists('de_19.orig.dic'): @@ -98,54 +96,12 @@ de_19.aff de_19.dic: {buildcheck=} @if os.path.exists('de_19.diff'): :sys patch >de_AT.dic - # delete the first line, the word count - :sys $VIM -u NONE de_DE.dic -e -c 1delete -c wq - :cat de_DE.dic >>de_AT.dic - :delete de_DE.dic - :move de_DE.aff de_AT.aff - :move README_de_DE.txt README_de_AT.txt - - @if os.path.exists('de_DE.temp.aff'): - :move de_DE.temp.aff de_DE.aff - @if os.path.exists('de_DE.temp.dic'): - :move de_DE.temp.dic de_DE.dic - @if os.path.exists('README_de_DE.temp.txt'): - :move README_de_DE.temp.txt README_de_DE.txt - + :assertpkg patch + :fetch $FILE_AT_AFF + :fetch $FILE_AT_DIC + :move $FILE_AT_AFF de_AT.aff + :move $FILE_AT_DIC de_AT.dic @if not os.path.exists('de_AT.orig.aff'): :copy de_AT.aff de_AT.orig.aff @if not os.path.exists('de_AT.orig.dic'): @@ -154,10 +110,11 @@ de_AT.aff de_AT.dic: {buildcheck=} :sys patch >de_DE.diff :sys {force} diff -a -C 1 de_19.orig.aff de_19.aff >de_19.diff :sys {force} diff -a -C 1 de_19.orig.dic de_19.dic >>de_19.diff - :sys {force} diff -a -C 1 de_20.orig.aff de_20.aff >de_20.diff - :sys {force} diff -a -C 1 de_20.orig.dic de_20.dic >>de_20.diff :sys {force} diff -a -C 1 de_AT.orig.aff de_AT.aff >de_AT.diff :sys {force} diff -a -C 1 de_AT.orig.dic de_AT.dic >>de_AT.diff :sys {force} diff -a -C 1 de_CH.orig.aff de_CH.aff >de_CH.diff :sys {force} diff -a -C 1 de_CH.orig.dic de_CH.dic >>de_CH.diff + :copy de_DE.diff de_20.diff # Check for updated OpenOffice spell files. When there are changes the @@ -187,36 +143,24 @@ diff: check: :assertpkg unzip patch - :fetch $ZIPFILES - :mkdir tmp - :cd tmp + :fetch $ZIPFILE_19 + :fetch $DICT_FILES @try: - # Do the _AT one first, it overwrites the _DE files. - :sys $UNZIP ../$ZIPFILE_AT - :print >>de_AT.dic - # delete the first line, the word count - :sys ../$VIM -u NONE de_DE.dic -e -c 1delete -c wq - :cat de_DE.dic >>de_AT.dic - :delete de_DE.dic - :move de_DE.aff de_AT.aff - :move README_de_DE.txt README_de_AT.txt - - :sys $UNZIP ../$ZIPFILE_DE - :move de_DE_comb.aff de_DE.aff - :move de_DE_comb.dic de_DE.dic - :move README_de_DE_comb.txt README_de_DE.txt - + :mkdir tmp + :cd tmp :sys $UNZIP ../$ZIPFILE_19 + :copy ../*.aff . + :copy ../*.dic . :move de_OLDSPELL.aff de_19.aff :move de_OLDSPELL.dic de_19.dic - # there is no README file - :print There is no README file for the old spelling >!README_de_19.txt - :sys $UNZIP ../$ZIPFILE_20 - :move de_DE_neu.aff de_20.aff - :move de_DE_neu.dic de_20.dic - :move README_de_DE_neu.txt README_de_20.txt - - :sys $UNZIP ../$ZIPFILE_CH + :move de_DE_frami.aff de_DE.aff + :move de_DE_frami.dic de_DE.dic + :move de_AT_frami.dic de_AT.dic + :move de_AT_frami.aff de_AT.aff + :move de_CH_frami.dic de_CH.dic + :move de_CH_frami.aff de_CH.aff + :copy de_DE.dic de_20.dic + :copy de_DE.aff de_20.aff @import stat @for nm in ['de_DE', 'de_19', 'de_20', 'de_AT', 'de_CH']: @@ -225,12 +169,8 @@ check: @if os.stat('d')[stat.ST_SIZE] > 0: :copy $(nm).$ext ../$(nm).new.$ext :sys {force} diff ../README_$(nm).txt README_$(nm).txt >d - @if os.stat('d')[stat.ST_SIZE] > 0: - :copy README_$(nm).txt ../README_$(nm).new.txt @finally: :cd .. :delete {r}{f}{q} tmp - :delete $ZIPFILES - # vim: set sts=4 sw=4 : diff --git a/runtime/spell/fixdup.vim b/runtime/spell/fixdup.vim index 0dd532d5e6..3f28fb5179 100644 --- a/runtime/spell/fixdup.vim +++ b/runtime/spell/fixdup.vim @@ -15,6 +15,9 @@ while lnum <= line('$') continue " don't increment lnum, it's already at the next word endif endif + if lnum%1000 == 0 + echon "\r Processing line ".lnum. printf(" [ %02d%%]", lnum*100/line('$')) + endif let lnum += 1 endwhile From 6aba96dd5778b4201c9f5cb065d7669d3398e724 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 17:43:21 +0100 Subject: [PATCH 07/26] patch 8.1.0828: still using FEAT_VIRTUALEDIT Problem: Still using FEAT_VIRTUALEDIT. Solution: Remove last use of FEAT_VIRTUALEDIT. --- src/quickfix.c | 4 ---- src/version.c | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/quickfix.c b/src/quickfix.c index 8b6c223c3c..e292819f2e 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -3064,9 +3064,7 @@ qf_jump_goto_line( if (qf_col > 0) { curwin->w_cursor.col = qf_col - 1; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif if (qf_viscol == TRUE) { // Check each character from the beginning of the error @@ -4108,9 +4106,7 @@ qf_win_goto(win_T *win, linenr_T lnum) curbuf = win->w_buffer; curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; -#ifdef FEAT_VIRTUALEDIT curwin->w_cursor.coladd = 0; -#endif curwin->w_curswant = 0; update_topline(); // scroll to show the line redraw_later(VALID); diff --git a/src/version.c b/src/version.c index 39a4f8f844..9fa0ba4558 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 828, /**/ 827, /**/ From d39e275b57493f9e25e1b62f84810571eee30cf4 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 26 Jan 2019 20:07:38 +0100 Subject: [PATCH 08/26] patch 8.1.0829: when 'hidden' is set session creates extra buffers Problem: When 'hidden' is set session creates extra buffers. Solution: Move :badd commands to the end. (Jason Franklin) --- src/ex_docmd.c | 43 ++++++++++++++++++---------------- src/testdir/test_mksession.vim | 23 ++++++++++++++++++ src/version.c | 2 ++ 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 93fa697317..dcfdcd4543 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -11280,26 +11280,6 @@ makeopens( if (put_line(fd, "set shortmess=aoO") == FAIL) return FAIL; - /* Now put the other buffers into the buffer list */ - FOR_ALL_BUFFERS(buf) - { - if (!(only_save_windows && buf->b_nwindows == 0) - && !(buf->b_help && !(ssop_flags & SSOP_HELP)) -#ifdef FEAT_TERMINAL - /* skip terminal buffers: finished ones are not useful, others - * will be resurrected and result in a new buffer */ - && !bt_terminal(buf) -#endif - && buf->b_fname != NULL - && buf->b_p_bl) - { - if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L - : buf->b_wininfo->wi_fpos.lnum) < 0 - || ses_fname(fd, buf, &ssop_flags, TRUE) == FAIL) - return FAIL; - } - } - /* the global argument list */ if (ses_arglist(fd, "argglobal", &global_alist.al_ga, !(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL) @@ -11515,6 +11495,29 @@ makeopens( if (restore_stal && put_line(fd, "set stal=1") == FAIL) return FAIL; + // Now put the remaining buffers into the buffer list. + // This is near the end, so that when 'hidden' is set we don't create extra + // buffers. If the buffer was already created with another command the + // ":badd" will have no effect. + FOR_ALL_BUFFERS(buf) + { + if (!(only_save_windows && buf->b_nwindows == 0) + && !(buf->b_help && !(ssop_flags & SSOP_HELP)) +#ifdef FEAT_TERMINAL + // Skip terminal buffers: finished ones are not useful, others + // will be resurrected and result in a new buffer. + && !bt_terminal(buf) +#endif + && buf->b_fname != NULL + && buf->b_p_bl) + { + if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L + : buf->b_wininfo->wi_fpos.lnum) < 0 + || ses_fname(fd, buf, &ssop_flags, TRUE) == FAIL) + return FAIL; + } + } + /* * Wipe out an empty unnamed buffer we started in. */ diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim index 3698976caa..3038422010 100644 --- a/src/testdir/test_mksession.vim +++ b/src/testdir/test_mksession.vim @@ -225,6 +225,29 @@ func Test_mksession_blank_tabs() call delete('Xtest_mks.out') endfunc +func Test_mksession_buffer_count() + set hidden + + " Edit exactly three files in the current session. + %bwipe! + e Xfoo | tabe Xbar | tabe Xbaz + tabdo write + mksession! Xtest_mks.out + + " Verify that loading the session does not create additional buffers. + %bwipe! + source Xtest_mks.out + call assert_equal(3, len(getbufinfo())) + + " Clean up. + call delete('Xfoo') + call delete('Xbar') + call delete('Xbaz') + call delete('Xtest_mks.out') + %bwipe! + set hidden& +endfunc + if has('extra_search') func Test_mksession_hlsearch() diff --git a/src/version.c b/src/version.c index 9fa0ba4558..af289037c9 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 829, /**/ 828, /**/ From e3d065454408a103c39308651dd7793f0bf55ba6 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 14:29:24 +0100 Subject: [PATCH 09/26] patch 8.1.0830: test leaves directory behind on MS-Windows Problem: Test leaves directory behind on MS-Windows. Solution: Close buffer before deleting directory. --- src/testdir/test_swap.vim | 3 +++ src/version.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/testdir/test_swap.vim b/src/testdir/test_swap.vim index 208d4d966e..ce52578919 100644 --- a/src/testdir/test_swap.vim +++ b/src/testdir/test_swap.vim @@ -98,6 +98,9 @@ func Test_missing_dir() split bar/x.txt only + " Delete the buffer so that swap file is removed before we try to delete the + " directory. That fails on MS-Windows. + %bdelete! set directory& call delete('Xswapdir', 'rf') endfunc diff --git a/src/version.c b/src/version.c index af289037c9..9891796328 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 830, /**/ 829, /**/ From 0eb220c03057096a26dda9c5544b362dce6df4d7 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 14:41:43 +0100 Subject: [PATCH 10/26] patch 8.1.0831: xxd test fails if man page has dos fileformat Problem: Xxd test fails if man page has dos fileformat. Solution: Make a copy with unix fileformat. --- src/testdir/test_xxd.vim | 21 +++++++++++++++------ src/version.c | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim index 7762667119..e4e7755234 100644 --- a/src/testdir/test_xxd.vim +++ b/src/testdir/test_xxd.vim @@ -53,14 +53,20 @@ func Test_xxd() call assert_equal(expected[2:], getline(1,'$'), s:Mess(s:test)) endfor + " The following tests use the xxd man page. + " For these tests to pass, the fileformat must be "unix". + let man_copy = 'Xxd.1' + let man_page = '../../runtime/doc/xxd.1' + if has('win32') && !filereadable(man_page) + let man_page = '../../doc/xxd.1' + endif + %d + exe '0r ' man_page '| set ff=unix | $d | w' man_copy '| bwipe!' man_copy + " Test 5: Print 120 bytes as continuous hexdump with 20 octets per line let s:test += 1 %d - let fname = '../../runtime/doc/xxd.1' - if has('win32') && !filereadable(fname) - let fname = '../../doc/xxd.1' - endif - exe '0r! ' . s:xxd_cmd . ' -l 120 -ps -c20 ' . fname + exe '0r! ' . s:xxd_cmd . ' -l 120 -ps -c20 ' . man_copy $d let expected = [ \ '2e54482058584420312022417567757374203139', @@ -75,11 +81,14 @@ func Test_xxd() let s:test += 1 for arg in ['-l 13', '-l13', '-len 13'] %d - exe '0r! ' . s:xxd_cmd . ' -s 0x36 ' . arg . ' -cols 13 ' . fname + exe '0r! ' . s:xxd_cmd . ' -s 0x36 ' . arg . ' -cols 13 ' . man_copy $d call assert_equal('00000036: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test)) endfor + " Cleanup after tests 5 and 6 + call delete(man_copy) + " Test 7: Print C include let s:test += 1 call writefile(['TESTabcd09'], 'XXDfile') diff --git a/src/version.c b/src/version.c index 9891796328..1e5f7e3b6e 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 831, /**/ 830, /**/ From 2e0500921891e4fec57e97d3c0021aa2d2b4d7ae Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 15:00:36 +0100 Subject: [PATCH 11/26] patch 8.1.0832: confirm() is not tested Problem: confirm() is not tested. Solution: Add a test. (Dominique Pelle, closes #3868) --- src/testdir/test_functions.vim | 55 ++++++++++++++++++++++++++++++++++ src/version.c | 2 ++ 2 files changed, 57 insertions(+) diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index 3d8104817d..ceb8486927 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -1153,3 +1153,58 @@ func Test_func_exists_on_reload() call delete('Xfuncexists') delfunc ExistingFunction endfunc + +" Test confirm({msg} [, {choices} [, {default} [, {type}]]]) +func Test_confirm() + if !has('unix') || has('gui_running') + return + endif + + call feedkeys('o', 'L') + let a = confirm('Press O to proceed') + call assert_equal(1, a) + + call feedkeys('y', 'L') + let a = confirm('Are you sure?', "&Yes\n&No") + call assert_equal(1, a) + + call feedkeys('n', 'L') + let a = confirm('Are you sure?', "&Yes\n&No") + call assert_equal(2, a) + + " confirm() should return 0 when pressing CTRL-C. + call feedkeys("\", 'L') + let a = confirm('Are you sure?', "&Yes\n&No") + call assert_equal(0, a) + + " requires another character to avoid it being seen as the start of an + " escape sequence. Zero should be harmless. + call feedkeys("\0", 'L') + let a = confirm('Are you sure?', "&Yes\n&No") + call assert_equal(0, a) + + " Default choice is returned when pressing . + call feedkeys("\", 'L') + let a = confirm('Are you sure?', "&Yes\n&No") + call assert_equal(1, a) + + call feedkeys("\", 'L') + let a = confirm('Are you sure?', "&Yes\n&No", 2) + call assert_equal(2, a) + + call feedkeys("\", 'L') + let a = confirm('Are you sure?', "&Yes\n&No", 0) + call assert_equal(0, a) + + " Test with the {type} 4th argument + for type in ['Error', 'Question', 'Info', 'Warning', 'Generic'] + call feedkeys('y', 'L') + let a = confirm('Are you sure?', "&Yes\n&No\n", 1, type) + call assert_equal(1, a) + endfor + + call assert_fails('call confirm([])', 'E730:') + call assert_fails('call confirm("Are you sure?", [])', 'E730:') + call assert_fails('call confirm("Are you sure?", "&Yes\n&No\n", [])', 'E745:') + call assert_fails('call confirm("Are you sure?", "&Yes\n&No\n", 0, [])', 'E730:') +endfunc diff --git a/src/version.c b/src/version.c index 1e5f7e3b6e..fc8fe1b29d 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 832, /**/ 831, /**/ From d93090f41f70c521cfad5b25efcb0024b9480082 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 15:07:39 +0100 Subject: [PATCH 12/26] patch 8.1.0833: memory leak when jumps output is filtered Problem: Memory leak when jumps output is filtered. Solution: Free the filtered name. (Dominique Pelle, closes #3869) --- src/mark.c | 3 +++ src/version.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/mark.c b/src/mark.c index 276391743c..6a7ab00d8b 100644 --- a/src/mark.c +++ b/src/mark.c @@ -900,7 +900,10 @@ ex_jumps(exarg_T *eap UNUSED) // apply :filter /pat/ or file name not available if (name == NULL || message_filtered(name)) + { + vim_free(name); continue; + } msg_putchar('\n'); if (got_int) diff --git a/src/version.c b/src/version.c index fc8fe1b29d..9572886632 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 833, /**/ 832, /**/ From e40b9d47bf8f8f716d3ef5a95c8ecbbdc0a501f9 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 16:55:47 +0100 Subject: [PATCH 13/26] patch 8.1.0834: GUI may wait too long before dealing with messages Problem: GUI may wait too long before dealing with messages. Returning early may cause a mapping to time out. Solution: Use the waiting loop from Unix also for the GUI. (closes #3817, closes #3824) --- src/gui.c | 143 +++++++++++-------------- src/os_unix.c | 149 +++----------------------- src/proto/ui.pro | 1 + src/testdir/screendump.vim | 4 + src/ui.c | 212 +++++++++++++++++++++++++++++++++++++ src/version.c | 2 + 6 files changed, 297 insertions(+), 214 deletions(-) diff --git a/src/gui.c b/src/gui.c index c22f47716b..39968954a8 100644 --- a/src/gui.c +++ b/src/gui.c @@ -2896,10 +2896,14 @@ gui_wait_for_chars_3( * or FAIL otherwise. */ static int -gui_wait_for_chars_or_timer(long wtime) +gui_wait_for_chars_or_timer( + long wtime, + int *interrupted UNUSED, + int ignore_input UNUSED) { #ifdef FEAT_TIMERS - return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, NULL, 0); + return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, + interrupted, ignore_input); #else return gui_mch_wait_for_chars(wtime); #endif @@ -2907,6 +2911,59 @@ gui_wait_for_chars_or_timer(long wtime) /* * The main GUI input routine. Waits for a character from the keyboard. + * "wtime" == -1 Wait forever. + * "wtime" == 0 Don't wait. + * "wtime" > 0 Wait wtime milliseconds for a character. + * + * Returns the number of characters read or zero when timed out or interrupted. + * "buf" may be NULL, in which case a non-zero number is returned if characters + * are available. + */ + static int +gui_wait_for_chars_buf( + char_u *buf, + int maxlen, + long wtime, // don't use "time", MIPS cannot handle it + int tb_change_cnt) +{ + int retval; + +#ifdef FEAT_MENU + // If we're going to wait a bit, update the menus and mouse shape for the + // current State. + if (wtime != 0) + gui_update_menus(0); +#endif + + gui_mch_update(); + if (input_available()) // Got char, return immediately + { + if (buf != NULL && !typebuf_changed(tb_change_cnt)) + return read_from_input_buf(buf, (long)maxlen); + return 0; + } + if (wtime == 0) // Don't wait for char + return FAIL; + + // Before waiting, flush any output to the screen. + gui_mch_flush(); + + // Blink while waiting for a character. + gui_mch_start_blink(); + + // Common function to loop until "wtime" is met, while handling timers and + // other callbacks. + retval = inchar_loop(buf, maxlen, wtime, tb_change_cnt, + gui_wait_for_chars_or_timer, NULL); + + gui_mch_stop_blink(TRUE); + + return retval; +} + +/* + * Wait for a character from the keyboard without actually reading it. + * Also deals with timers. * wtime == -1 Wait forever. * wtime == 0 Don't wait. * wtime > 0 Wait wtime milliseconds for a character. @@ -2916,82 +2973,7 @@ gui_wait_for_chars_or_timer(long wtime) int gui_wait_for_chars(long wtime, int tb_change_cnt) { - int retval; -#if defined(ELAPSED_FUNC) - elapsed_T start_tv; -#endif - -#ifdef FEAT_MENU - /* - * If we're going to wait a bit, update the menus and mouse shape for the - * current State. - */ - if (wtime != 0) - gui_update_menus(0); -#endif - - gui_mch_update(); - if (input_available()) /* Got char, return immediately */ - return OK; - if (wtime == 0) /* Don't wait for char */ - return FAIL; - - /* Before waiting, flush any output to the screen. */ - gui_mch_flush(); - - if (wtime > 0) - { - /* Blink when waiting for a character. Probably only does something - * for showmatch() */ - gui_mch_start_blink(); - retval = gui_wait_for_chars_or_timer(wtime); - gui_mch_stop_blink(TRUE); - return retval; - } - -#if defined(ELAPSED_FUNC) - ELAPSED_INIT(start_tv); -#endif - - /* - * While we are waiting indefinitely for a character, blink the cursor. - */ - gui_mch_start_blink(); - - retval = FAIL; - /* - * We may want to trigger the CursorHold event. First wait for - * 'updatetime' and if nothing is typed within that time, and feedkeys() - * wasn't used, put the K_CURSORHOLD key in the input buffer. - */ - if (gui_wait_for_chars_or_timer(p_ut) == OK) - retval = OK; - else if (trigger_cursorhold() -#if defined(ELAPSED_FUNC) - && ELAPSED_FUNC(start_tv) >= p_ut -#endif - && typebuf.tb_change_cnt == tb_change_cnt) - { - char_u buf[3]; - - /* Put K_CURSORHOLD in the input buffer. */ - buf[0] = CSI; - buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; - add_to_input_buf(buf, 3); - - retval = OK; - } - - if (retval == FAIL && typebuf.tb_change_cnt == tb_change_cnt) - { - /* Blocking wait. */ - before_blocking(); - retval = gui_wait_for_chars_or_timer(-1L); - } - - gui_mch_stop_blink(TRUE); - return retval; + return gui_wait_for_chars_buf(NULL, 0, wtime, tb_change_cnt); } /* @@ -3004,10 +2986,7 @@ gui_inchar( long wtime, /* milli seconds */ int tb_change_cnt) { - if (gui_wait_for_chars(wtime, tb_change_cnt) - && !typebuf_changed(tb_change_cnt)) - return read_from_input_buf(buf, (long)maxlen); - return 0; + return gui_wait_for_chars_buf(buf, maxlen, wtime, tb_change_cnt); } /* diff --git a/src/os_unix.c b/src/os_unix.c index 765cd57e7a..c616e06fe1 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -355,6 +355,21 @@ mch_write(char_u *s, int len) RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL); } +/* + * Function passed to inchar_loop() to handle window resizing. + * If "check_only" is TRUE: Return whether there was a resize. + * If "check_only" is FALSE: Deal with the window resized. + */ + static int +resize_func(int check_only) +{ + if (check_only) + return do_resize; + while (do_resize) + handle_resize(); + return FALSE; +} + /* * mch_inchar(): low level input function. * Get a characters from the keyboard. @@ -370,138 +385,8 @@ mch_inchar( long wtime, /* don't use "time", MIPS cannot handle it */ int tb_change_cnt) { - int len; - int interrupted = FALSE; - int did_start_blocking = FALSE; - long wait_time; - long elapsed_time = 0; -#ifdef ELAPSED_FUNC - elapsed_T start_tv; - - ELAPSED_INIT(start_tv); -#endif - - /* repeat until we got a character or waited long enough */ - for (;;) - { - /* Check if window changed size while we were busy, perhaps the ":set - * columns=99" command was used. */ - while (do_resize) - handle_resize(); - -#ifdef MESSAGE_QUEUE - // Only process messages when waiting. - if (wtime != 0) - { - parse_queued_messages(); - // If input was put directly in typeahead buffer bail out here. - if (typebuf_changed(tb_change_cnt)) - return 0; - } -#endif - if (wtime < 0 && did_start_blocking) - /* blocking and already waited for p_ut */ - wait_time = -1; - else - { - if (wtime >= 0) - wait_time = wtime; - else - /* going to block after p_ut */ - wait_time = p_ut; -#ifdef ELAPSED_FUNC - elapsed_time = ELAPSED_FUNC(start_tv); -#endif - wait_time -= elapsed_time; - if (wait_time < 0) - { - if (wtime >= 0) - /* no character available within "wtime" */ - return 0; - - else - { - /* no character available within 'updatetime' */ - did_start_blocking = TRUE; - if (trigger_cursorhold() && maxlen >= 3 - && !typebuf_changed(tb_change_cnt)) - { - buf[0] = K_SPECIAL; - buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; - return 3; - } - /* - * If there is no character available within 'updatetime' - * seconds flush all the swap files to disk. - * Also done when interrupted by SIGWINCH. - */ - before_blocking(); - continue; - } - } - } - -#ifdef FEAT_JOB_CHANNEL - /* Checking if a job ended requires polling. Do this every 100 msec. */ - if (has_pending_job() && (wait_time < 0 || wait_time > 100L)) - wait_time = 100L; - /* If there is readahead then parse_queued_messages() timed out and we - * should call it again soon. */ - if ((wait_time < 0 || wait_time > 100L) && channel_any_readahead()) - wait_time = 10L; -#endif -#ifdef FEAT_BEVAL_GUI - if (p_beval && wait_time > 100L) - /* The 'balloonexpr' may indirectly invoke a callback while waiting - * for a character, need to check often. */ - wait_time = 100L; -#endif - - /* - * We want to be interrupted by the winch signal - * or by an event on the monitored file descriptors. - */ - if (WaitForChar(wait_time, &interrupted, FALSE)) - { - /* If input was put directly in typeahead buffer bail out here. */ - if (typebuf_changed(tb_change_cnt)) - return 0; - - /* - * For some terminals we only get one character at a time. - * We want the get all available characters, so we could keep on - * trying until none is available - * For some other terminals this is quite slow, that's why we don't - * do it. - */ - len = read_from_input_buf(buf, (long)maxlen); - if (len > 0) - return len; - continue; - } - - /* no character available */ -#ifndef ELAPSED_FUNC - /* estimate the elapsed time */ - elapsed_time += wait_time; -#endif - - if (do_resize /* interrupted by SIGWINCH signal */ -#ifdef FEAT_CLIENTSERVER - || server_waiting() -#endif -#ifdef MESSAGE_QUEUE - || interrupted -#endif - || wait_time > 0 - || (wtime < 0 && !did_start_blocking)) - continue; - - /* no character available or interrupted */ - break; - } - return 0; + return inchar_loop(buf, maxlen, wtime, tb_change_cnt, + WaitForChar, resize_func); } static void diff --git a/src/proto/ui.pro b/src/proto/ui.pro index ac830f0fcb..774a308966 100644 --- a/src/proto/ui.pro +++ b/src/proto/ui.pro @@ -2,6 +2,7 @@ void ui_write(char_u *s, int len); void ui_inchar_undo(char_u *s, int len); int ui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt); +int inchar_loop(char_u *buf, int maxlen, long wtime, int tb_change_cnt, int (*wait_func)(long wtime, int *interrupted, int ignore_input), int (*resize_func)(int check_only)); int ui_wait_for_chars_or_timer(long wtime, int (*wait_func)(long wtime, int *interrupted, int ignore_input), int *interrupted, int ignore_input); int ui_char_avail(void); void ui_delay(long msec, int ignoreinput); diff --git a/src/testdir/screendump.vim b/src/testdir/screendump.vim index 139f708c07..b46a477b73 100644 --- a/src/testdir/screendump.vim +++ b/src/testdir/screendump.vim @@ -58,6 +58,10 @@ func RunVimInTerminal(arguments, options) let cmd .= ' -v ' . a:arguments let buf = term_start(cmd, {'curwin': 1, 'term_rows': rows, 'term_cols': cols}) if &termwinsize == '' + " in the GUI we may end up with a different size, try to set it. + if term_getsize(buf) != [rows, cols] + call term_setsize(buf, rows, cols) + endif call assert_equal([rows, cols], term_getsize(buf)) else let rows = term_getsize(buf)[0] diff --git a/src/ui.c b/src/ui.c index 9150dafa6e..0d08c5d053 100644 --- a/src/ui.c +++ b/src/ui.c @@ -178,6 +178,48 @@ ui_inchar( ctrl_c_interrupts = FALSE; } + /* + * Here we call gui_inchar() or mch_inchar(), the GUI or machine-dependent + * input function. The functionality they implement is like this: + * + * while (not timed out) + * { + * handle-resize; + * parse-queued-messages; + * if (waited for 'updatetime') + * trigger-cursorhold; + * ui_wait_for_chars_or_timer() + * if (character available) + * break; + * } + * + * ui_wait_for_chars_or_timer() does: + * + * while (not timed out) + * { + * if (any-timer-triggered) + * invoke-timer-callback; + * wait-for-character(); + * if (character available) + * break; + * } + * + * wait-for-character() does: + * while (not timed out) + * { + * Wait for event; + * if (something on channel) + * read/write channel; + * else if (resized) + * handle_resize(); + * else if (system event) + * deal-with-system-event; + * else if (character available) + * break; + * } + * + */ + #ifdef FEAT_GUI if (gui.in_use) retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt); @@ -205,6 +247,176 @@ theend: return retval; } +#if defined(UNIX) || defined(FEAT_GUI) || defined(PROTO) +/* + * Common code for mch_inchar() and gui_inchar(): Wait for a while or + * indefinitely until characters are available, dealing with timers and + * messages on channels. + * + * "buf" may be NULL if the available characters are not to be returned, only + * check if they are available. + * + * Return the number of characters that are available. + * If "wtime" == 0 do not wait for characters. + * If "wtime" == n wait a short time for characters. + * If "wtime" == -1 wait forever for characters. + */ + int +inchar_loop( + char_u *buf, + int maxlen, + long wtime, // don't use "time", MIPS cannot handle it + int tb_change_cnt, + int (*wait_func)(long wtime, int *interrupted, int ignore_input), + int (*resize_func)(int check_only)) +{ + int len; + int interrupted = FALSE; + int did_start_blocking = FALSE; + long wait_time; + long elapsed_time = 0; +#ifdef ELAPSED_FUNC + elapsed_T start_tv; + + ELAPSED_INIT(start_tv); +#endif + + /* repeat until we got a character or waited long enough */ + for (;;) + { + /* Check if window changed size while we were busy, perhaps the ":set + * columns=99" command was used. */ + if (resize_func != NULL) + resize_func(FALSE); + +#ifdef MESSAGE_QUEUE + // Only process messages when waiting. + if (wtime != 0) + { + parse_queued_messages(); + // If input was put directly in typeahead buffer bail out here. + if (typebuf_changed(tb_change_cnt)) + return 0; + } +#endif + if (wtime < 0 && did_start_blocking) + // blocking and already waited for p_ut + wait_time = -1; + else + { + if (wtime >= 0) + wait_time = wtime; + else + // going to block after p_ut + wait_time = p_ut; +#ifdef ELAPSED_FUNC + elapsed_time = ELAPSED_FUNC(start_tv); +#endif + wait_time -= elapsed_time; + if (wait_time <= 0) + { + if (wtime >= 0) + // no character available within "wtime" + return 0; + + // No character available within 'updatetime'. + did_start_blocking = TRUE; + if (trigger_cursorhold() && maxlen >= 3 + && !typebuf_changed(tb_change_cnt)) + { + // Put K_CURSORHOLD in the input buffer or return it. + if (buf == NULL) + { + char_u ibuf[3]; + + ibuf[0] = CSI; + ibuf[1] = KS_EXTRA; + ibuf[2] = (int)KE_CURSORHOLD; + add_to_input_buf(ibuf, 3); + } + else + { + buf[0] = K_SPECIAL; + buf[1] = KS_EXTRA; + buf[2] = (int)KE_CURSORHOLD; + } + return 3; + } + + // There is no character available within 'updatetime' seconds: + // flush all the swap files to disk. Also done when + // interrupted by SIGWINCH. + before_blocking(); + continue; + } + } + +#ifdef FEAT_JOB_CHANNEL + if (wait_time < 0 || wait_time > 100L) + { + // Checking if a job ended requires polling. Do this at least + // every 100 msec. + if (has_pending_job()) + wait_time = 100L; + + // If there is readahead then parse_queued_messages() timed out and + // we should call it again soon. + if (channel_any_readahead()) + wait_time = 10L; + } +#endif +#ifdef FEAT_BEVAL_GUI + if (p_beval && wait_time > 100L) + // The 'balloonexpr' may indirectly invoke a callback while waiting + // for a character, need to check often. + wait_time = 100L; +#endif + + // Wait for a character to be typed or another event, such as the winch + // signal or an event on the monitored file descriptors. + if (wait_func(wait_time, &interrupted, FALSE)) + { + // If input was put directly in typeahead buffer bail out here. + if (typebuf_changed(tb_change_cnt)) + return 0; + + // We might have something to return now. + if (buf == NULL) + // "buf" is NULL, we were just waiting, not actually getting + // input. + return input_available(); + + len = read_from_input_buf(buf, (long)maxlen); + if (len > 0) + return len; + continue; + } + // Timed out or interrupted with no character available. + +#ifndef ELAPSED_FUNC + // estimate the elapsed time + elapsed_time += wait_time; +#endif + + if ((resize_func != NULL && resize_func(TRUE)) +#ifdef FEAT_CLIENTSERVER + || server_waiting() +#endif +#ifdef MESSAGE_QUEUE + || interrupted +#endif + || wait_time > 0 + || (wtime < 0 && !did_start_blocking)) + // no character available, but something to be done, keep going + continue; + + // no character available or interrupted, return zero + break; + } + return 0; +} +#endif + #if defined(FEAT_TIMERS) || defined(PROTO) /* * Wait for a timer to fire or "wait_func" to return non-zero. diff --git a/src/version.c b/src/version.c index 9572886632..0a6dce29f9 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 834, /**/ 833, /**/ From 3e9d4d85c4b5602f072be76b51865050d51fb3c4 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 17:08:40 +0100 Subject: [PATCH 14/26] patch 8.1.0835: GUI build fails on MS-Windows Problem: GUI build fails on MS-Windows. Solution: Adjust #ifdef. --- src/ui.c | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui.c b/src/ui.c index 0d08c5d053..d4278a39f8 100644 --- a/src/ui.c +++ b/src/ui.c @@ -399,7 +399,7 @@ inchar_loop( #endif if ((resize_func != NULL && resize_func(TRUE)) -#ifdef FEAT_CLIENTSERVER +#if defined(FEAT_CLIENTSERVER) && defined(UNIX) || server_waiting() #endif #ifdef MESSAGE_QUEUE diff --git a/src/version.c b/src/version.c index 0a6dce29f9..31bf37893b 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 835, /**/ 834, /**/ From 346d2a359a6874be6cdb683a8d190ba13aa10e94 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 20:43:41 +0100 Subject: [PATCH 15/26] patch 8.1.0836: user completion test can fail on MS-Windows Problem: User completion test can fail on MS-Windows. Solution: Allow for other names befor "Administrator". --- src/testdir/test_cmdline.vim | 3 ++- src/version.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 4dcda858e8..02eeb6b8c6 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -430,8 +430,9 @@ func Test_cmdline_complete_user_names() let names = system('net user') if names =~ 'Administrator' " Trying completion of :e ~A should complete to Administrator. + " There could be other names starting with "A" before Administrator. call feedkeys(':e ~A' . "\\\"\", 'tx') - call assert_match('^"e \~Administrator', @:) + call assert_match('^"e \~.*Administrator', @:) endif endif endfunc diff --git a/src/version.c b/src/version.c index 31bf37893b..dac3c62c55 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 836, /**/ 835, /**/ From 26d982185e21398738a9c688429c0a1840d7c9c3 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 27 Jan 2019 22:32:55 +0100 Subject: [PATCH 16/26] patch 8.1.0837: timer interrupting cursorhold and mapping not tested Problem: Timer interrupting cursorhold and mapping not tested. Solution: Add tests with timers. (Ozaki Kiichi, closes #3871) --- src/testdir/test_autocmd.vim | 27 ++++++++++++++++++++++-- src/testdir/test_mapping.vim | 40 +++++++++++++++++++++++++++++++++++- src/version.c | 2 ++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 0eabc2e30b..c502a26176 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -32,6 +32,28 @@ if has('timers') call timer_start(100, 'ExitInsertMode') call feedkeys('a', 'x!') call assert_equal(1, g:triggered) + unlet g:triggered + au! CursorHoldI + set updatetime& + endfunc + + func Test_cursorhold_insert_with_timer_interrupt() + if !has('job') + return + endif + " Need to move the cursor. + call feedkeys("ggG", "xt") + + " Confirm the timer invoked in exit_cb of the job doesn't disturb + " CursorHoldI event. + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=500 + call job_start(has('win32') ? 'cmd /c echo:' : 'echo', + \ {'exit_cb': {j, s -> timer_start(1000, 'ExitInsertMode')}}) + call feedkeys('a', 'x!') + call assert_equal(1, g:triggered) + unlet g:triggered au! CursorHoldI set updatetime& endfunc @@ -44,6 +66,7 @@ if has('timers') " CursorHoldI does not trigger after CTRL-X call feedkeys("a\", 'x!') call assert_equal(0, g:triggered) + unlet g:triggered au! CursorHoldI set updatetime& endfunc @@ -452,7 +475,7 @@ func s:AutoCommandOptionSet(match) endfunc func Test_OptionSet() - if !has("eval") || !has("autocmd") || !exists("+autochdir") + if !has("eval") || !exists("+autochdir") return endif @@ -595,7 +618,7 @@ endfunc func Test_OptionSet_diffmode() call test_override('starting', 1) - " 18: Changing an option when enetering diff mode + " 18: Changing an option when entering diff mode new au OptionSet diff :let &l:cul=v:option_new diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim index 5aaa743fad..921b693a97 100644 --- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -1,5 +1,7 @@ " Tests for mappings and abbreviations +source shared.vim + func Test_abbreviation() " abbreviation with 0x80 should work inoreab чкпр vim @@ -169,6 +171,9 @@ func Test_abbr_after_line_join() endfunc func Test_map_timeout() + if !has('timers') + return + endif nnoremap aaaa :let got_aaaa = 1 nnoremap bb :let got_bb = 1 nmap b aaa @@ -178,7 +183,7 @@ func Test_map_timeout() call feedkeys("\", "t") endfunc set timeout timeoutlen=200 - call timer_start(300, 'ExitInsert') + let timer = timer_start(300, 'ExitInsert') " After the 'b' Vim waits for another character to see if it matches 'bb'. " When it times out it is expanded to "aaa", but there is no wait for " "aaaa". Can't check that reliably though. @@ -193,6 +198,39 @@ func Test_map_timeout() nunmap b set timeoutlen& delfunc ExitInsert + call timer_stop(timer) +endfunc + +func Test_map_timeout_with_timer_interrupt() + if !has('job') || !has('timers') + return + endif + + " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key + " sequence. + new + let g:val = 0 + nnoremap \12 :let g:val = 1 + nnoremap \123 :let g:val = 2 + set timeout timeoutlen=1000 + + func ExitCb(job, status) + let g:timer = timer_start(1, {_ -> feedkeys("3\", 't')}) + endfunc + + call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'}) + call feedkeys('\12', 'xt!') + call assert_equal(2, g:val) + + bwipe! + nunmap \12 + nunmap \123 + set timeoutlen& + call WaitFor({-> exists('g:timer')}) + call timer_stop(g:timer) + unlet g:timer + unlet g:val + delfunc ExitCb endfunc func Test_abbreviation_CR() diff --git a/src/version.c b/src/version.c index dac3c62c55..6ceaf23c61 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 837, /**/ 836, /**/ From dec01206b224fd0fba66e4da20a602e941d74d04 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 28 Jan 2019 20:04:24 +0100 Subject: [PATCH 17/26] patch 8.1.0838: compiler warning for type conversion Problem: Compiler warning for type conversion. Solution: Add a type cast. (Mike Williams) --- src/channel.c | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/channel.c b/src/channel.c index 7c649b1714..419939897d 100644 --- a/src/channel.c +++ b/src/channel.c @@ -90,7 +90,7 @@ fd_write(sock_T fd, char *buf, size_t len) if (todo > MAX_NAMED_PIPE_SIZE) size = MAX_NAMED_PIPE_SIZE; else - size = todo; + size = (DWORD)todo; // If the pipe overflows while the job does not read the data, WriteFile // will block forever. This abandons the write. memset(&ov, 0, sizeof(ov)); diff --git a/src/version.c b/src/version.c index 6ceaf23c61..7d63c554d7 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 838, /**/ 837, /**/ From f58d81a18752cb9bf899b3f7328fc489cf6558e8 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 28 Jan 2019 20:19:05 +0100 Subject: [PATCH 18/26] patch 8.1.0839: when using VTP wrong colors after a color scheme change Problem: When using VTP wrong colors after a color scheme change. Solution: When VTP is active always clear after a color scheme change. (Nobuhiro Takasaki, closes #3872) --- src/ex_docmd.c | 9 +++++++++ src/version.c | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index dcfdcd4543..1646a22139 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -7211,6 +7211,15 @@ ex_colorscheme(exarg_T *eap) } else if (load_colors(eap->arg) == FAIL) semsg(_("E185: Cannot find color scheme '%s'"), eap->arg); + +#ifdef FEAT_VTP + else if (has_vtp_working()) + { + // background color change requires clear + redraw + update_screen(CLEAR); + redrawcmd(); + } +#endif } static void diff --git a/src/version.c b/src/version.c index 7d63c554d7..b69344ce18 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 839, /**/ 838, /**/ From 12dfc9eef14fe74c46145aa9e6cba9666f1bcd40 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 28 Jan 2019 22:32:58 +0100 Subject: [PATCH 19/26] patch 8.1.0840: getchar(0) never returns a character in the terminal Problem: getchar(0) never returns a character in the terminal. Solution: Call wait_func() at least once. --- src/gui_gtk_x11.c | 9 +++++---- src/gui_photon.c | 5 +++-- src/gui_w32.c | 8 +++++--- src/gui_x11.c | 7 ++++--- src/testdir/test_timers.vim | 10 ++++++++++ src/ui.c | 8 +++++++- src/version.c | 2 ++ 7 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 6882733696..e1de83a68b 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -6317,10 +6317,11 @@ gui_mch_wait_for_chars(long wtime) timed_out = FALSE; - /* this timeout makes sure that we will return if no characters arrived in - * time */ - if (wtime > 0) - timer = timeout_add(wtime, input_timer_cb, &timed_out); + // This timeout makes sure that we will return if no characters arrived in + // time. If "wtime" is zero just use one. + if (wtime >= 0) + timer = timeout_add(wtime <= 0 ? 1L : wtime, + input_timer_cb, &timed_out); else timer = 0; diff --git a/src/gui_photon.c b/src/gui_photon.c index 234d250669..94012287e7 100644 --- a/src/gui_photon.c +++ b/src/gui_photon.c @@ -1344,8 +1344,9 @@ gui_mch_wait_for_chars(int wtime) { is_timeout = FALSE; - if (wtime > 0) - PtSetResource(gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL, wtime, 0); + if (wtime >= 0) + PtSetResource(gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL, + wtime == 0 ? 1 : wtime, 0); while (1) { diff --git a/src/gui_w32.c b/src/gui_w32.c index c5e58790d2..ead617a79f 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -2097,12 +2097,14 @@ gui_mch_wait_for_chars(int wtime) s_timed_out = FALSE; - if (wtime > 0) + if (wtime >= 0) { - /* Don't do anything while processing a (scroll) message. */ + // Don't do anything while processing a (scroll) message. if (s_busy_processing) return FAIL; - s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)wtime, + + // When called with "wtime" zero, just want one msec. + s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)(wtime == 0 ? 1 : wtime), (TIMERPROC)_OnTimer); } diff --git a/src/gui_x11.c b/src/gui_x11.c index c8a3b773ab..ad91a21013 100644 --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -2683,9 +2683,10 @@ gui_mch_wait_for_chars(long wtime) timed_out = FALSE; - if (wtime > 0) - timer = XtAppAddTimeOut(app_context, (long_u)wtime, gui_x11_timer_cb, - &timed_out); + if (wtime >= 0) + timer = XtAppAddTimeOut(app_context, + (long_u)(wtime == 0 ? 1L : wtime), + gui_x11_timer_cb, &timed_out); #ifdef FEAT_JOB_CHANNEL /* If there is a channel with the keep_open flag we need to poll for input * on them. */ diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim index bccd31b93d..0b88d8af23 100644 --- a/src/testdir/test_timers.vim +++ b/src/testdir/test_timers.vim @@ -250,6 +250,16 @@ func Test_peek_and_get_char() call timer_stop(intr) endfunc +func Test_getchar_zero() + call timer_start(20, {id -> feedkeys('x', 'L')}) + let c = 0 + while c == 0 + let c = getchar(0) + sleep 10m + endwhile + call assert_equal('x', nr2char(c)) +endfunc + func Test_ex_mode() " Function with an empty line. func Foo(...) diff --git a/src/ui.c b/src/ui.c index d4278a39f8..0823d2dd23 100644 --- a/src/ui.c +++ b/src/ui.c @@ -272,6 +272,7 @@ inchar_loop( { int len; int interrupted = FALSE; + int did_call_wait_func = FALSE; int did_start_blocking = FALSE; long wait_time; long elapsed_time = 0; @@ -313,7 +314,11 @@ inchar_loop( elapsed_time = ELAPSED_FUNC(start_tv); #endif wait_time -= elapsed_time; - if (wait_time <= 0) + + // If the waiting time is now zero or less, we timed out. However, + // loop at least once to check for characters and events. Matters + // when "wtime" is zero. + if (wait_time <= 0 && did_call_wait_func) { if (wtime >= 0) // no character available within "wtime" @@ -374,6 +379,7 @@ inchar_loop( // Wait for a character to be typed or another event, such as the winch // signal or an event on the monitored file descriptors. + did_call_wait_func = TRUE; if (wait_func(wait_time, &interrupted, FALSE)) { // If input was put directly in typeahead buffer bail out here. diff --git a/src/version.c b/src/version.c index b69344ce18..ae28d083d5 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 840, /**/ 839, /**/ From 2339fa335fcce46226f871b2c95c433966c711e9 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 28 Jan 2019 22:59:36 +0100 Subject: [PATCH 20/26] patch 8.1.0841: travis config to get Lua on MacOS is too complicated Problem: Travis config to get Lua on MacOS is too complicated. Solution: Use an addons entry. (Ozaki Kiichi, closes 3876) --- .travis.yml | 6 +++++- src/version.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cf95cd6670..277e6feb00 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,6 +82,10 @@ addons: - tcl-dev - cscope - libgtk2.0-dev + homebrew: + packages: + - lua + update: true before_install: - rvm reset @@ -93,7 +97,7 @@ before_install: # building cffi only works with gcc, not with clang - if [ "$COVERAGE" = "yes" ]; then CC=gcc pip install --user pyopenssl ndg-httpsclient pyasn1; fi # Lua is not installed on Travis OSX - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export HOMEBREW_NO_AUTO_UPDATE=1; brew update; brew install lua; export LUA_PREFIX=/usr/local; fi + - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export LUA_PREFIX=/usr/local; fi # Use llvm-cov instead of gcov when compiler is clang. - if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CC" = "clang" ]; then ln -sf $(which llvm-cov) /home/travis/bin/gcov; fi diff --git a/src/version.c b/src/version.c index ae28d083d5..a90d52e667 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 841, /**/ 840, /**/ From cb908a813cebf7fb4608ff43fc3d258cf2768809 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 28 Jan 2019 23:20:04 +0100 Subject: [PATCH 21/26] patch 8.1.0842: getchar_zero test fails on MS-Windows Problem: getchar_zero test fails on MS-Windows. Solution: Disable the test for now. --- src/testdir/test_timers.vim | 11 +++++++++-- src/version.c | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim index 0b88d8af23..2cea3e47da 100644 --- a/src/testdir/test_timers.vim +++ b/src/testdir/test_timers.vim @@ -251,13 +251,20 @@ func Test_peek_and_get_char() endfunc func Test_getchar_zero() - call timer_start(20, {id -> feedkeys('x', 'L')}) + if has('win32') + " Console: no low-level input + " GUI: somehow doesn't work + return + endif + + let id = timer_start(20, {id -> feedkeys('x', 'L')}) let c = 0 while c == 0 let c = getchar(0) sleep 10m endwhile call assert_equal('x', nr2char(c)) + call timer_stop(id) endfunc func Test_ex_mode() @@ -265,7 +272,7 @@ func Test_ex_mode() func Foo(...) endfunc - let timer = timer_start(40, function('g:Foo'), {'repeat':-1}) + let timer = timer_start(40, function('g:Foo'), {'repeat':-1}) " This used to throw error E749. exe "normal Qsleep 100m\rvi\r" call timer_stop(timer) diff --git a/src/version.c b/src/version.c index a90d52e667..c8bb2f7de6 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 842, /**/ 841, /**/ From e0de2164f62a1736cdc64dbf804b77db8af90c10 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 29 Jan 2019 20:17:28 +0100 Subject: [PATCH 22/26] patch 8.1.0843: memory leak when running "make test_cd" Problem: Memory leak when running "make test_cd". Solution: Free the stack element when failing. (Dominique Pelle, closes #3877) --- src/misc2.c | 15 +++++++++++++++ src/version.c | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/misc2.c b/src/misc2.c index ca8f56d384..df3f8e169b 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -4657,7 +4657,10 @@ vim_findfile(void *search_ctx_arg) add_pathsep(file_path); } else + { + ff_free_stack_element(stackp); goto fail; + } } /* append the fix part of the search path */ @@ -4667,7 +4670,10 @@ vim_findfile(void *search_ctx_arg) add_pathsep(file_path); } else + { + ff_free_stack_element(stackp); goto fail; + } #ifdef FEAT_PATH_EXTRA rest_of_wildcards = stackp->ffs_wc_path; @@ -4687,7 +4693,10 @@ vim_findfile(void *search_ctx_arg) if (len + 1 < MAXPATHL) file_path[len++] = '*'; else + { + ff_free_stack_element(stackp); goto fail; + } } if (*p == 0) @@ -4718,7 +4727,10 @@ vim_findfile(void *search_ctx_arg) if (len + 1 < MAXPATHL) file_path[len++] = *rest_of_wildcards++; else + { + ff_free_stack_element(stackp); goto fail; + } file_path[len] = NUL; if (vim_ispathsep(*rest_of_wildcards)) @@ -4787,7 +4799,10 @@ vim_findfile(void *search_ctx_arg) STRCAT(file_path, search_ctx->ffsc_file_to_search); } else + { + ff_free_stack_element(stackp); goto fail; + } /* * Try without extra suffix and then with suffixes diff --git a/src/version.c b/src/version.c index c8bb2f7de6..e78fde7dfb 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 843, /**/ 842, /**/ From 50948e4ac24314d5a70404bbc592ffc28755ad9f Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 29 Jan 2019 20:36:56 +0100 Subject: [PATCH 23/26] patch 8.1.0844: when timer fails test will hang forever Problem: When timer fails test will hang forever. Solution: Use reltime() to limit waiting time. (Ozaki Kiichi, closes #3878) --- src/testdir/test_timers.vim | 4 +++- src/version.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim index 2cea3e47da..78ec005676 100644 --- a/src/testdir/test_timers.vim +++ b/src/testdir/test_timers.vim @@ -257,9 +257,11 @@ func Test_getchar_zero() return endif + " Measure the elapsed time to avoid a hang when it fails. + let start = reltime() let id = timer_start(20, {id -> feedkeys('x', 'L')}) let c = 0 - while c == 0 + while c == 0 && reltimefloat(reltime(start)) < 0.2 let c = getchar(0) sleep 10m endwhile diff --git a/src/version.c b/src/version.c index e78fde7dfb..cf7c47eb42 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 844, /**/ 843, /**/ From 2a4857a1fcf1d188e5b985ac21bcfc532eddde94 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 29 Jan 2019 22:29:07 +0100 Subject: [PATCH 24/26] patch 8.1.0845: having job_status() free the job causes problems Problem: Having job_status() free the job causes problems. Solution: Do not actually free the job or terminal yet, put it in a list and free it a bit later. Do not use a terminal after checking the job status. (closes #3873) --- src/channel.c | 64 ++++++++++++++++++++++++++++++------ src/misc2.c | 3 ++ src/proto/terminal.pro | 1 + src/terminal.c | 74 +++++++++++++++++++++++++++++------------- src/version.c | 2 ++ 5 files changed, 111 insertions(+), 33 deletions(-) diff --git a/src/channel.c b/src/channel.c index 419939897d..cf68271925 100644 --- a/src/channel.c +++ b/src/channel.c @@ -5161,8 +5161,11 @@ job_free_contents(job_T *job) } } +/* + * Remove "job" from the list of jobs. + */ static void -job_free_job(job_T *job) +job_unlink(job_T *job) { if (job->jv_next != NULL) job->jv_next->jv_prev = job->jv_prev; @@ -5170,6 +5173,12 @@ job_free_job(job_T *job) first_job = job->jv_next; else job->jv_prev->jv_next = job->jv_next; +} + + static void +job_free_job(job_T *job) +{ + job_unlink(job); vim_free(job); } @@ -5183,12 +5192,44 @@ job_free(job_T *job) } } +job_T *jobs_to_free = NULL; + +/* + * Put "job" in a list to be freed later, when it's no longer referenced. + */ + static void +job_free_later(job_T *job) +{ + job_unlink(job); + job->jv_next = jobs_to_free; + jobs_to_free = job; +} + + static void +free_jobs_to_free_later(void) +{ + job_T *job; + + while (jobs_to_free != NULL) + { + job = jobs_to_free; + jobs_to_free = job->jv_next; + job_free_contents(job); + vim_free(job); + } +} + #if defined(EXITFREE) || defined(PROTO) void job_free_all(void) { while (first_job != NULL) job_free(first_job); + free_jobs_to_free_later(); + +# ifdef FEAT_TERMINAL + free_unused_terminals(); +# endif } #endif @@ -5359,6 +5400,8 @@ win32_build_cmd(list_T *l, garray_T *gap) * NOTE: Must call job_cleanup() only once right after the status of "job" * changed to JOB_ENDED (i.e. after job_status() returned "dead" first or * mch_detect_ended_job() returned non-NULL). + * If the job is no longer used it will be removed from the list of jobs, and + * deleted a bit later. */ void job_cleanup(job_T *job) @@ -5394,15 +5437,13 @@ job_cleanup(job_T *job) channel_need_redraw = TRUE; } - /* Do not free the job in case the close callback of the associated channel - * isn't invoked yet and may get information by job_info(). */ + // Do not free the job in case the close callback of the associated channel + // isn't invoked yet and may get information by job_info(). if (job->jv_refcount == 0 && !job_channel_still_useful(job)) - { - /* The job was already unreferenced and the associated channel was - * detached, now that it ended it can be freed. Careful: caller must - * not use "job" after this! */ - job_free(job); - } + // The job was already unreferenced and the associated channel was + // detached, now that it ended it can be freed. However, a caller might + // still use it, thus free it a bit later. + job_free_later(job); } /* @@ -5609,9 +5650,12 @@ job_check_ended(void) if (job == NULL) break; did_end = TRUE; - job_cleanup(job); // may free "job" + job_cleanup(job); // may add "job" to jobs_to_free } + // Actually free jobs that were cleaned up. + free_jobs_to_free_later(); + if (channel_need_redraw) { channel_need_redraw = FALSE; diff --git a/src/misc2.c b/src/misc2.c index df3f8e169b..657e164913 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -6386,6 +6386,9 @@ parse_queued_messages(void) // changes, e.g. stdin may have been closed. if (job_check_ended()) continue; +# endif +# ifdef FEAT_TERMINAL + free_unused_terminals(); # endif break; } diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro index a318fc87fa..e6914c0ba0 100644 --- a/src/proto/terminal.pro +++ b/src/proto/terminal.pro @@ -5,6 +5,7 @@ void ex_terminal(exarg_T *eap); int term_write_session(FILE *fd, win_T *wp); int term_should_restore(buf_T *buf); void free_terminal(buf_T *buf); +void free_unused_terminals(void); void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); int term_job_running(term_T *term); int term_none_open(term_T *term); diff --git a/src/terminal.c b/src/terminal.c index f33521a9f3..87530af2ef 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -803,10 +803,17 @@ free_scrollback(term_T *term) ga_clear(&term->tl_scrollback); } + +// Terminals that need to be freed soon. +term_T *terminals_to_free = NULL; + /* * Free a terminal and everything it refers to. * Kills the job if there is one. * Called when wiping out a buffer. + * The actual terminal structure is freed later in free_unused_terminals(), + * because callbacks may wipe out a buffer while the terminal is still + * referenced. */ void free_terminal(buf_T *buf) @@ -816,6 +823,8 @@ free_terminal(buf_T *buf) if (term == NULL) return; + + // Unlink the terminal form the list of terminals. if (first_term == term) first_term = term->tl_next; else @@ -834,29 +843,43 @@ free_terminal(buf_T *buf) job_stop(term->tl_job, NULL, "kill"); job_unref(term->tl_job); } + term->tl_next = terminals_to_free; + terminals_to_free = term; - free_scrollback(term); - - term_free_vterm(term); - vim_free(term->tl_title); -#ifdef FEAT_SESSION - vim_free(term->tl_command); -#endif - vim_free(term->tl_kill); - vim_free(term->tl_status_text); - vim_free(term->tl_opencmd); - vim_free(term->tl_eof_chars); -#ifdef WIN3264 - if (term->tl_out_fd != NULL) - fclose(term->tl_out_fd); -#endif - vim_free(term->tl_cursor_color); - vim_free(term); buf->b_term = NULL; if (in_terminal_loop == term) in_terminal_loop = NULL; } + void +free_unused_terminals() +{ + while (terminals_to_free != NULL) + { + term_T *term = terminals_to_free; + + terminals_to_free = term->tl_next; + + free_scrollback(term); + + term_free_vterm(term); + vim_free(term->tl_title); +#ifdef FEAT_SESSION + vim_free(term->tl_command); +#endif + vim_free(term->tl_kill); + vim_free(term->tl_status_text); + vim_free(term->tl_opencmd); + vim_free(term->tl_eof_chars); +#ifdef WIN3264 + if (term->tl_out_fd != NULL) + fclose(term->tl_out_fd); +#endif + vim_free(term->tl_cursor_color); + vim_free(term); + } +} + /* * Get the part that is connected to the tty. Normally this is PART_IN, but * when writing buffer lines to the job it can be another. This makes it @@ -1275,6 +1298,7 @@ term_convert_key(term_T *term, int c, char *buf) /* * Return TRUE if the job for "term" is still running. * If "check_job_status" is TRUE update the job status. + * NOTE: "term" may be freed by callbacks. */ static int term_job_running_check(term_T *term, int check_job_status) @@ -1285,10 +1309,15 @@ term_job_running_check(term_T *term, int check_job_status) && term->tl_job != NULL && channel_is_open(term->tl_job->jv_channel)) { + job_T *job = term->tl_job; + + // Careful: Checking the job status may invoked callbacks, which close + // the buffer and terminate "term". However, "job" will not be freed + // yet. if (check_job_status) - job_status(term->tl_job); - return (term->tl_job->jv_status == JOB_STARTED - || term->tl_job->jv_channel->ch_keep_open); + job_status(job); + return (job->jv_status == JOB_STARTED + || (job->jv_channel != NULL && job->jv_channel->ch_keep_open)); } return FALSE; } @@ -2151,9 +2180,8 @@ terminal_loop(int blocking) #ifdef FEAT_GUI if (!curbuf->b_term->tl_system) #endif - /* TODO: skip screen update when handling a sequence of keys. */ - /* Repeat redrawing in case a message is received while redrawing. - */ + // TODO: skip screen update when handling a sequence of keys. + // Repeat redrawing in case a message is received while redrawing. while (must_redraw != 0) if (update_screen(0) == FAIL) break; diff --git a/src/version.c b/src/version.c index cf7c47eb42..3609fb0b82 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 845, /**/ 844, /**/ From 39536dd557e847e80572044c2be319db5886abe3 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 29 Jan 2019 22:58:21 +0100 Subject: [PATCH 25/26] patch 8.1.0846: not easy to recognize the system Vim runs on Problem: Not easy to recognize the system Vim runs on. Solution: Add more items to the features list. (Ozaki Kiichi, closes #3855) --- runtime/doc/eval.txt | 66 +++++++++++++++++++++------------ src/evalfunc.c | 16 +++++++- src/testdir/test_channel.vim | 2 +- src/testdir/test_functions.vim | 68 ++++++++++++++++++++++++++-------- src/testdir/test_terminal.vim | 2 +- src/testdir/test_writefile.vim | 2 +- src/version.c | 2 + 7 files changed, 115 insertions(+), 43 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index c41fdcee1b..46a503e889 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 8.1. Last change: 2019 Jan 24 +*eval.txt* For Vim version 8.1. Last change: 2019 Jan 29 VIM REFERENCE MANUAL by Bram Moolenaar @@ -696,7 +696,7 @@ similar to -1. > :let otherblob = myblob[:] " make a copy of the Blob If the first index is beyond the last byte of the Blob or the second index is -before the first byte, the result is an empty list. There is no error +before the first index, the result is an empty list. There is no error message. If the second index is equal to or greater than the length of the list the @@ -2511,7 +2511,10 @@ remote_read({serverid} [, {timeout}]) remote_send({server}, {string} [, {idvar}]) String send key sequence remote_startserver({name}) none become server {name} -remove({list}, {idx} [, {end}]) any remove items {idx}-{end} from {list} +remove({list}, {idx} [, {end}]) any/List + remove items {idx}-{end} from {list} +remove({blob}, {idx} [, {end}]) Number/Blob + remove bytes {idx}-{end} from {blob} remove({dict}, {key}) any remove entry {key} from {dict} rename({from}, {to}) Number rename (move) file from {from} to {to} repeat({expr}, {count}) String repeat {expr} {count} times @@ -6056,13 +6059,9 @@ line({expr}) The result is a Number, which is the line number of the file line(".") line number of the cursor line("'t") line number of mark t line("'" . marker) line number of mark marker -< *last-position-jump* - This autocommand jumps to the last known position in a file - just after opening it, if the '" mark is set: > - :au BufReadPost * - \ if line("'\"") > 1 && line("'\"") <= line("$") && &ft !~# 'commit' - \ | exe "normal! g`\"" - \ | endif +< + To jump to the last known position when opening a file see + |last-position-jump|. line2byte({lnum}) *line2byte()* Return the byte count from the start of the buffer for line @@ -6504,8 +6503,10 @@ min({expr}) Return the minimum value of all items in {expr}. *mkdir()* *E739* mkdir({name} [, {path} [, {prot}]]) Create directory {name}. + If {path} is "p" then intermediate directories are created as necessary. Otherwise it must be "". + If {prot} is given it is used to set the protection bits of the new directory. The default is 0755 (rwxr-xr-x: r/w for the user readable for others). Use 0700 to make it unreadable @@ -6514,9 +6515,17 @@ mkdir({name} [, {path} [, {prot}]]) with 0755. Example: > :call mkdir($HOME . "/tmp/foo/bar", "p", 0700) + < This function is not available in the |sandbox|. + There is no error if the directory already exists and the "p" - flag is passed (since patch 8.0.1708). + flag is passed (since patch 8.0.1708). However, without the + "p" option the call will fail. + + The function result is a Number, which is 1 if the call was + successful or 0 if the directory creation failed or partly + failed. + Not available on all systems. To check use: > :if exists("*mkdir") < @@ -7325,6 +7334,9 @@ remove({list}, {idx} [, {end}]) *remove()* Example: > :echo "last item: " . remove(mylist, -1) :call remove(mylist, 0, 9) +< + Use |delete()| to remove a file. + remove({blob}, {idx} [, {end}]) Without {end}: Remove the byte at {idx} from |Blob| {blob} and return the byte. @@ -7335,13 +7347,12 @@ remove({blob}, {idx} [, {end}]) Example: > :echo "last byte: " . remove(myblob, -1) :call remove(mylist, 0, 9) + remove({dict}, {key}) Remove the entry from {dict} with key {key}. Example: > :echo "removed " . remove(dict, "one") < If there is no {key} in {dict} this is an error. - Use |delete()| to remove a file. - rename({from}, {to}) *rename()* Rename the file by the name {from} to the name {to}. This should also work to move files across file systems. The @@ -9724,10 +9735,10 @@ type({expr}) The result is a Number representing the type of {expr}. Dictionary: 4 |v:t_dict| Float: 5 |v:t_float| Boolean: 6 |v:t_bool| (v:false and v:true) - None 7 |v:t_none| (v:null and v:none) - Job 8 |v:t_job| - Channel 9 |v:t_channel| - Blob 10 |v:t_blob| + None: 7 |v:t_none| (v:null and v:none) + Job: 8 |v:t_job| + Channel: 9 |v:t_channel| + Blob: 10 |v:t_blob| For backward compatibility, this method can be used: > :if type(myvar) == type(0) :if type(myvar) == type("") @@ -10150,7 +10161,7 @@ all_builtin_terms Compiled with all builtin terminals enabled. amiga Amiga version of Vim. arabic Compiled with Arabic support |Arabic|. arp Compiled with ARP support (Amiga). -autocmd Compiled with autocommand support. |autocommand| +autocmd Compiled with autocommand support. (always true) autochdir Compiled with support for 'autochdir' autoservername Automatically enable |clientserver| balloon_eval Compiled with |balloon-eval| support. @@ -10159,6 +10170,7 @@ beos BeOS version of Vim. browse Compiled with |:browse| support, and browse() will work. browsefilter Compiled with support for |browsefilter|. +bsd Compiled on an OS in the BSD family (excluding macOS). builtin_terms Compiled with some builtin terminals. byte_offset Compiled with support for 'o' in 'statusline' cindent Compiled with 'cindent' support. @@ -10171,6 +10183,7 @@ comments Compiled with |'comments'| support. compatible Compiled to be very Vi compatible. cryptv Compiled with encryption support |encryption|. cscope Compiled with |cscope| support. +cursorbind Compiled with |cursorbind| (always true) debug Compiled with "DEBUG" defined. dialog_con Compiled with console dialog support. dialog_gui Compiled with GUI dialog support. @@ -10182,7 +10195,7 @@ ebcdic Compiled on a machine with ebcdic character set. emacs_tags Compiled with support for Emacs tags. eval Compiled with expression evaluation support. Always true, of course! -ex_extra |+ex_extra|, always true now +ex_extra |+ex_extra| (always true) extra_search Compiled with support for |'incsearch'| and |'hlsearch'| farsi Compiled with Farsi support |farsi|. @@ -10211,6 +10224,7 @@ gui_running Vim is running in the GUI, or it will start soon. gui_win32 Compiled with MS Windows Win32 GUI. gui_win32s idem, and Win32s system being used (Windows 3.1) hangul_input Compiled with Hangul input support. |hangul| +hpux HP-UX version of Vim. iconv Can use iconv() for conversion. insert_expand Compiled with support for CTRL-X expansion commands in Insert mode. @@ -10221,6 +10235,7 @@ langmap Compiled with 'langmap' support. libcall Compiled with |libcall()| support. linebreak Compiled with 'linebreak', 'breakat', 'showbreak' and 'breakindent' support. +linux Linux version of Vim. lispindent Compiled with support for lisp indenting. listcmds Compiled with commands for the buffer list |:files| and the argument list |arglist|. @@ -10271,7 +10286,7 @@ quickfix Compiled with |quickfix| support. reltime Compiled with |reltime()| support. rightleft Compiled with 'rightleft' support. ruby Compiled with Ruby interface |ruby|. -scrollbind Compiled with 'scrollbind' support. +scrollbind Compiled with 'scrollbind' support. (always true) showcmd Compiled with 'showcmd' support. signs Compiled with |:sign| support. smartindent Compiled with 'smartindent' support. @@ -10279,6 +10294,7 @@ spell Compiled with spell checking support |spell|. startuptime Compiled with |--startuptime| support. statusline Compiled with support for 'statusline', 'rulerformat' and special formats of 'titlestring' and 'iconstring'. +sun SunOS version of Vim. sun_workshop Support for Sun |workshop| has been removed. syntax Compiled with syntax highlighting support |syntax|. syntax_items There are active syntax highlighting items for the @@ -10310,27 +10326,29 @@ user_commands User-defined commands. vcon Win32: Virtual console support is working, can use 'termguicolors'. Also see |+vtp|. vertsplit Compiled with vertically split windows |:vsplit|. + (always true) vim_starting True while initial source'ing takes place. |startup| *vim_starting* viminfo Compiled with viminfo support. -virtualedit Compiled with 'virtualedit' option. +virtualedit Compiled with 'virtualedit' option. (always true) visual Compiled with Visual mode. (always true) visualextra Compiled with extra Visual mode commands. (always true) |blockwise-operators|. vms VMS version of Vim. -vreplace Compiled with |gR| and |gr| commands. +vreplace Compiled with |gR| and |gr| commands. (always true) vtp Compiled for vcon support |+vtp| (check vcon to find out if it works in the current console). wildignore Compiled with 'wildignore' option. wildmenu Compiled with 'wildmenu' option. -win16 old version for MS-Windows 3.1 (always False) +win16 old version for MS-Windows 3.1 (always false) win32 Win32 version of Vim (MS-Windows 95 and later, 32 or 64 bits) win32unix Win32 version of Vim, using Unix files (Cygwin) win64 Win64 version of Vim (MS-Windows 64 bit). -win95 Win32 version for MS-Windows 95/98/ME (always False) +win95 Win32 version for MS-Windows 95/98/ME (always false) winaltkeys Compiled with 'winaltkeys' option. windows Compiled with support for more than one window. + (always true) writebackup Compiled with 'writebackup' default on. xfontset Compiled with X fontset support |xfontset|. xim Compiled with X input method support |xim|. diff --git a/src/evalfunc.c b/src/evalfunc.c index 874e3a66da..c7ba6f3081 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -6118,6 +6118,15 @@ f_has(typval_T *argvars, typval_T *rettv) #ifdef __BEOS__ "beos", #endif +#if defined(BSD) && !defined(MACOS_X) + "bsd", +#endif +#ifdef hpux + "hpux", +#endif +#ifdef __linux__ + "linux", +#endif #ifdef MACOS_X "mac", /* Mac OS X (and, once, Mac OS Classic) */ "osx", /* Mac OS X */ @@ -6129,6 +6138,11 @@ f_has(typval_T *argvars, typval_T *rettv) #ifdef __QNX__ "qnx", #endif +#ifdef SUN_SYSTEM + "sun", +#else + "moon", +#endif #ifdef UNIX "unix", #endif @@ -6158,7 +6172,7 @@ f_has(typval_T *argvars, typval_T *rettv) #endif "autocmd", #ifdef FEAT_AUTOCHDIR - "autochdir", + "autochdir", #endif #ifdef FEAT_AUTOSERVERNAME "autoservername", diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 7b0a917352..f81701a076 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -29,7 +29,7 @@ endfunc func s:get_resources() let pid = getpid() - if has('mac') + if executable('lsof') return systemlist('lsof -p ' . pid . ' | awk ''$4~/^[0-9]*[rwu]$/&&$5=="REG"{print$NF}''') elseif isdirectory('/proc/' . pid . '/fd/') return systemlist('readlink /proc/' . pid . '/fd/* | grep -v ''^/dev/''') diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index ceb8486927..b08d9aa856 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -1054,22 +1054,31 @@ func Test_libcall_libcallnr() let libc = 'msvcrt.dll' elseif has('mac') let libc = 'libSystem.B.dylib' - elseif system('uname -s') =~ 'SunOS' - " Set the path to libc.so according to the architecture. - let test_bits = system('file ' . GetVimProg()) - let test_arch = system('uname -p') - if test_bits =~ '64-bit' && test_arch =~ 'sparc' - let libc = '/usr/lib/sparcv9/libc.so' - elseif test_bits =~ '64-bit' && test_arch =~ 'i386' - let libc = '/usr/lib/amd64/libc.so' - else - let libc = '/usr/lib/libc.so' - endif - else + elseif executable('ldd') + let libc = matchstr(split(system('ldd ' . GetVimProg())), '/libc\.so\>') + endif + if get(l:, 'libc', '') ==# '' " On Unix, libc.so can be in various places. - " Interestingly, using an empty string for the 1st argument of libcall - " allows to call functions from libc which is not documented. - let libc = '' + if has('linux') + " There is not documented but regarding the 1st argument of glibc's + " dlopen an empty string and nullptr are equivalent, so using an empty + " string for the 1st argument of libcall allows to call functions. + let libc = '' + elseif has('sun') + " Set the path to libc.so according to the architecture. + let test_bits = system('file ' . GetVimProg()) + let test_arch = system('uname -p') + if test_bits =~ '64-bit' && test_arch =~ 'sparc' + let libc = '/usr/lib/sparcv9/libc.so' + elseif test_bits =~ '64-bit' && test_arch =~ 'i386' + let libc = '/usr/lib/amd64/libc.so' + else + let libc = '/usr/lib/libc.so' + endif + else + " Unfortunately skip this test until a good way is found. + return + endif endif if has('win32') @@ -1208,3 +1217,32 @@ func Test_confirm() call assert_fails('call confirm("Are you sure?", "&Yes\n&No\n", [])', 'E745:') call assert_fails('call confirm("Are you sure?", "&Yes\n&No\n", 0, [])', 'E730:') endfunc + +func Test_platform_name() + " The system matches at most only one name. + let names = ['amiga', 'beos', 'bsd', 'hpux', 'linux', 'mac', 'qnx', 'sun', 'vms', 'win32', 'win32unix'] + call assert_inrange(0, 1, len(filter(copy(names), 'has(v:val)'))) + + " Is Unix? + call assert_equal(has('beos'), has('beos') && has('unix')) + call assert_equal(has('bsd'), has('bsd') && has('unix')) + call assert_equal(has('hpux'), has('hpux') && has('unix')) + call assert_equal(has('linux'), has('linux') && has('unix')) + call assert_equal(has('mac'), has('mac') && has('unix')) + call assert_equal(has('qnx'), has('qnx') && has('unix')) + call assert_equal(has('sun'), has('sun') && has('unix')) + call assert_equal(has('win32'), has('win32') && !has('unix')) + call assert_equal(has('win32unix'), has('win32unix') && has('unix')) + + if has('unix') && executable('uname') + let uname = system('uname') + call assert_equal(uname =~? 'BeOS', has('beos')) + call assert_equal(uname =~? 'BSD\|DragonFly', has('bsd')) + call assert_equal(uname =~? 'HP-UX', has('hpux')) + call assert_equal(uname =~? 'Linux', has('linux')) + call assert_equal(uname =~? 'Darwin', has('mac')) + call assert_equal(uname =~? 'QNX', has('qnx')) + call assert_equal(uname =~? 'SunOS', has('sun')) + call assert_equal(uname =~? 'CYGWIN\|MSYS', has('win32unix')) + endif +endfunc diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index 25ec2b5ca5..698da04982 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -559,7 +559,7 @@ endfunction func Test_terminal_noblock() let buf = term_start(&shell) - if has('mac') + if has('bsd') || has('mac') || has('sun') " The shell or something else has a problem dealing with more than 1000 " characters at the same time. let len = 1000 diff --git a/src/testdir/test_writefile.vim b/src/testdir/test_writefile.vim index 2e47b48a8f..ff3675661f 100644 --- a/src/testdir/test_writefile.vim +++ b/src/testdir/test_writefile.vim @@ -33,7 +33,7 @@ func Test_writefile_fails_gently() endfunc func Test_writefile_fails_conversion() - if !has('iconv') || system('uname -s') =~ 'SunOS' + if !has('iconv') || has('sun') return endif set nobackup nowritebackup diff --git a/src/version.c b/src/version.c index 3609fb0b82..f693b660e9 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 846, /**/ 845, /**/ From 9172d23d05f3f25996e03612654920b01158d734 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 29 Jan 2019 23:06:54 +0100 Subject: [PATCH 26/26] patch 8.1.0847: may use terminal after it was cleaned up Problem: May use terminal after it was cleaned up. Solution: Use the job pointer. --- src/terminal.c | 15 ++++++++++----- src/version.c | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/terminal.c b/src/terminal.c index 87530af2ef..7605914438 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -1375,19 +1375,24 @@ term_try_stop_job(buf_T *buf) job_stop(buf->b_term->tl_job, NULL, how); - /* wait for up to a second for the job to die */ + // wait for up to a second for the job to die for (count = 0; count < 100; ++count) { - /* buffer, terminal and job may be cleaned up while waiting */ + job_T *job; + + // buffer, terminal and job may be cleaned up while waiting if (!buf_valid(buf) || buf->b_term == NULL || buf->b_term->tl_job == NULL) return OK; + job = buf->b_term->tl_job; - /* call job_status() to update jv_status */ - job_status(buf->b_term->tl_job); - if (buf->b_term->tl_job->jv_status >= JOB_ENDED) + // Call job_status() to update jv_status. It may cause the job to be + // cleaned up but it won't be freed. + job_status(job); + if (job->jv_status >= JOB_ENDED) return OK; + ui_delay(10L, FALSE); mch_check_messages(); parse_queued_messages(); diff --git a/src/version.c b/src/version.c index f693b660e9..729f650174 100644 --- a/src/version.c +++ b/src/version.c @@ -783,6 +783,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 847, /**/ 846, /**/