summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-02-22 08:49:11 +0000
committerBram Moolenaar <Bram@vim.org>2005-02-22 08:49:11 +0000
commit26a60b45245080771bc2452b2634cb1f5acd60ed (patch)
tree82a54fd6544b2c2a57b5c52cb4d64c42dcd640a3
parentdf177f679e950a2ab2ad5fe7d45c1daface004d7 (diff)
downloadvim-26a60b45245080771bc2452b2634cb1f5acd60ed.zip
updated for version 7.0051
-rw-r--r--runtime/doc/autocmd.txt6
-rw-r--r--runtime/doc/change.txt36
-rw-r--r--runtime/doc/eval.txt54
-rw-r--r--runtime/doc/options.txt55
-rw-r--r--runtime/doc/pattern.txt20
-rw-r--r--runtime/doc/repeat.txt9
-rw-r--r--runtime/doc/starting.txt12
-rw-r--r--runtime/doc/tags30
-rw-r--r--runtime/doc/windows.txt4
-rw-r--r--runtime/filetype.vim5
-rw-r--r--runtime/ftplugin/vim.vim6
-rw-r--r--src/ex_getln.c359
-rw-r--r--src/gui_mac.c721
-rw-r--r--src/ops.c22
-rw-r--r--src/option.c61
-rw-r--r--src/option.h7
-rw-r--r--src/os_mac_conv.c323
-rw-r--r--src/po/Make_mvc.mak4
-rw-r--r--src/proto/eval.pro3
-rw-r--r--src/screen.c12
-rw-r--r--src/search.c2
-rw-r--r--src/structs.h4
-rw-r--r--src/syntax.c17
-rw-r--r--src/term.c8
-rw-r--r--src/undo.c184
-rw-r--r--src/version.h4
26 files changed, 1588 insertions, 380 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index c815f362a..e994df886 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -1,4 +1,4 @@
-*autocmd.txt* For Vim version 7.0aa. Last change: 2005 Feb 07
+*autocmd.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -204,10 +204,12 @@ FilterReadPre Before reading a file from a filter command.
the current buffer, not the name of the
temporary file that is the output of the
filter command.
+ Not triggered when 'shelltemp' is off.
*FilterReadPost*
FilterReadPost After reading a file from a filter command.
Vim checks the pattern against the name of
the current buffer as with FilterReadPre.
+ Not triggered when 'shelltemp' is off.
*FileType*
FileType When the 'filetype' option has been set.
<afile> can be used for the name of the file
@@ -270,11 +272,13 @@ FilterWritePre Before writing a file for a filter command or
the current buffer, not the name of the
temporary file that is the output of the
filter command.
+ Not triggered when 'shelltemp' is off.
*FilterWritePost*
FilterWritePost After writing a file for a filter command or
making a diff.
Vim checks the pattern against the name of
the current buffer as with FilterWritePre.
+ Not triggered when 'shelltemp' is off.
*FileChangedShell*
FileChangedShell When Vim notices that the modification time of
a file has changed since editing started.
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index 766bcb0fc..379d5e1fa 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1,4 +1,4 @@
-*change.txt* For Vim version 7.0aa. Last change: 2005 Feb 08
+*change.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -112,19 +112,22 @@ gJ Join [count] lines, with a minimum of two lines.
Vi}
*:j* *:join*
-:[range]j[oin][!] Join [range] lines. Same as "J", except with [!]
+:[range]j[oin][!] [flags]
+ Join [range] lines. Same as "J", except with [!]
the join does not insert or delete any spaces.
If a [range] has equal start and end values, this
command does nothing. The default behavior is to
join the current line with the line below it.
{not in Vi: !}
+ See |ex-flags| for [flags].
-:[range]j[oin][!] {count}
+:[range]j[oin][!] {count} [flags]
Join {count} lines, starting with [range] (default:
current line |cmdline-ranges|). Same as "J", except
with [!] the join does not insert or delete any
spaces.
{not in Vi: !}
+ See |ex-flags| for [flags].
These commands delete the <EOL> between lines. This has the effect of joining
multiple lines into one line. You can repeat these commands (except ":j") and
@@ -236,10 +239,12 @@ If you prefer "cw" to include the space after a word, use this mapping: >
:map cw dwi
<
*:c* *:ch* *:change*
-:{range}c[hange] Replace lines of text with some different text.
+:{range}c[hange][!] Replace lines of text with some different text.
Type a line containing only "." to stop replacing.
Without {range}, this command changes only the current
line.
+ Adding [!] toggles 'autoindent' for the time this
+ command is executed.
==============================================================================
3. Simple changes *simple-change*
@@ -424,12 +429,15 @@ SHIFTING LINES LEFT OR RIGHT *shift-left-right*
lines to [indent] (default 0). {not in Vi}
*:>*
-:[range]> Shift {count} [range] lines one 'shiftwidth' right.
+:[range]> [flags] Shift {count} [range] lines one 'shiftwidth' right.
Repeat '>' for shifting multiple 'shiftwidth's.
+ See |ex-flags| for [flags].
-:[range]> {count} Shift {count} lines one 'shiftwidth' right, starting
+:[range]> {count} [flags]
+ Shift {count} lines one 'shiftwidth' right, starting
with [range] (default current line |cmdline-ranges|).
Repeat '>' for shifting multiple 'shiftwidth's.
+ See |ex-flags| for [flags].
The ">" and "<" commands are handy for changing the indentation within
programs. Use the 'shiftwidth' option to set the size of the white space
@@ -519,7 +527,7 @@ comment (starting with '"') after the ":!" command.
4.2 Substitute *:substitute*
*:s* *:su*
-:[range]s[ubstitute]/{pattern}/{string}/[&][c][e][g][p][r][i][I] [count]
+:[range]s[ubstitute]/{pattern}/{string}/[&][#][c][e][g][p][r][i][I] [count]
For each line in [range] replace a match of {pattern}
with {string}.
For the {pattern} see |pattern|.
@@ -533,8 +541,8 @@ comment (starting with '"') after the ":!" command.
Also see |cmdline-ranges|.
See |:s_flags| for the flags.
-:[range]s[ubstitute] [c][e][g][p][r][i][I] [count]
-:[range]&[&][c][e][g][p][r][i][I] [count] *:&*
+:[range]s[ubstitute] [#][c][e][g][p][r][i][I] [count]
+:[range]&[&][#][c][e][g][p][r][i][I] [count] *:&*
Repeat last :substitute with same search pattern and
substitute string, but without the same flags. You
may add extra flags (see |:s_flags|).
@@ -544,7 +552,7 @@ comment (starting with '"') after the ":!" command.
'r' flags isn't required, but in scripts it's a good
idea to keep it to avoid confusion.
-:[range]~[&][c][e][g][p][r][i][I] [count] *:~*
+:[range]~[&][#][c][e][g][p][r][i][I] [count] *:~*
Repeat last substitute with same substitute string
but with last used search pattern. This is like
":&r". See |:s_flags| for the flags.
@@ -622,7 +630,10 @@ The flags that you can use for the substitute commands:
{not in Vi}
[p] Print the line containing the last substitute.
- {not in Vi}
+
+[#] Like [p] and prepend the line number.
+
+[l] Like [l] but print the text like |:list|.
[r] Only useful in combination with ":&" or ":s" without arguments. ":&r"
works the same way as ":~": When the search pattern is empty, use the
@@ -668,6 +679,9 @@ For the definition of a pattern, see |pattern|.
When the {string} starts with "\=" it is evaluated as an expression, see
|sub-replace-expression|. Otherwise these characters in {string} have a
special meaning:
+ *:s%*
+When {string} is equal to "%" and '/' is included with the 'cpotions' option,
+then the {string} of the previous substitute command is used. |cpo-/|
magic nomagic action ~
& \& replaced with the whole matched pattern *s/\&*
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 736ab793b..028aa089f 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 7.0aa. Last change: 2005 Feb 11
+*eval.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1484,13 +1484,16 @@ matchstr( {expr}, {pat}[, {start}[, {count}]])
String {count}'th match of {pat} in {expr}
max({list}) Number maximum value of items in {list}
min({list}) Number minumum value of items in {list}
+mkdir({name} [, {path} [, {prot}]])
+ Number create directory {name}
mode() String current editing mode
nextnonblank( {lnum}) Number line nr of non-blank line >= {lnum}
nr2char( {expr}) String single char with ASCII value {expr}
prevnonblank( {lnum}) Number line nr of non-blank line <= {lnum}
range( {expr} [, {max} [, {stride}]])
List items from {expr} to {max}
-readfile({fname} [, {binary}]) List get list of lines from file {fname}
+readfile({fname} [, {binary} [, {max}]])
+ List get list of lines from file {fname}
remote_expr( {server}, {string} [, {idvar}])
String send expression
remote_foreground( {server}) Number bring Vim server to the foreground
@@ -3099,6 +3102,19 @@ min({list}) Return the minumum value of all items in {list}.
be used as a Number this results in an error.
An empty List results in zero.
+ *mkdir()* *E749*
+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
+ for others.
+ This function is not available in the |sandbox|.
+ Not available on all systems. To check use: >
+ :if exists("*mkdir")
+<
*mode()*
mode() Return a string that indicates the current mode:
n Normal
@@ -3158,7 +3174,7 @@ range({expr} [, {max} [, {stride}]]) *range()*
range(2, -2, -1) " [2, 1, 0, -1, -2]
<
*readfile()*
-readfile({fname} [, {binary}])
+readfile({fname} [, {binary} [, {max}]])
Read file {fname} and return a List, each line of the file as
an item. Lines broken at NL characters. Macintosh files
separated with CR will result in a single long line (unless a
@@ -3171,9 +3187,16 @@ readfile({fname} [, {binary}])
- CR characters that appear before a NL are removed.
- Whether the last line ends in a NL or not does not matter.
All NUL characters are replaced with a NL character.
- Note that the whole file is read into memory and there is no
- recognition of encoding. Read a file into a buffer if you
- need to.
+ When {max} is given this specifies the maximum number of lines
+ to be read. Useful if you only want to check the first ten
+ lines of a file: >
+ :for line in readfile(fname, '', 10)
+ : if line =~ 'Date' | echo line | endif
+ :endfor
+< When {max} is zero or negative the result is an empty list.
+ Note that without {max} the whole file is read into memory.
+ Also note that there is no recognition of encoding. Read a
+ file into a buffer if you need to.
When the file can't be opened an error message is given and
the result is an empty list.
Also see |writefile()|.
@@ -3997,6 +4020,8 @@ extra_search Compiled with support for |'incsearch'| and
|'hlsearch'|
farsi Compiled with Farsi support |farsi|.
file_in_path Compiled with support for |gf| and |<cfile>|
+filterpipe When 'shelltemp' is off pipes are used for shell
+ read/write/filter commands
find_in_path Compiled with support for include file searches
|+find_in_path|.
fname_case Case in file names matters (for Amiga, MS-DOS, and
@@ -4374,7 +4399,7 @@ The file "~/vim/bufnetfuncs.vim" should then define functions that start with
Using an autoload script ~
-
+ *autoload* *E746*
Using a script in the "autoload" directory is simpler, but requires using
exactly the right file name. A function that can be autoloaded has a name
like this: >
@@ -4404,9 +4429,24 @@ Vim will look for the file "autoload/foo/bar.vim" in 'runtimepath'.
The name before the first colon must be at least two characters long,
otherwise it looks like a scope, such as "s:".
+This also works when reading a variable that has not been set yet: >
+
+ :let l = foo:bar:lvar
+
+When assigning a value to such a variable nothing special happens. This can
+be used to pass settings to the autoload script before it's loaded: >
+
+ :let foo:bar:toggle = 1
+ :call foo:bar:func()
+
Note that when you make a mistake and call a function that is supposed to be
defined in an autoload script, but the script doesn't actually define the
function, the script will be sourced every time you try to call the function.
+And you will get an error message every time.
+
+Also note that if you have two script files, and one calls a function in the
+other and vise versa, before the used function is defined, it won't work.
+Avoid using the autoload functionality at the toplevel.
==============================================================================
6. Curly braces names *curly-braces-names*
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 25558d642..e8b4a9d15 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 7.0aa. Last change: 2005 Feb 10
+*options.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1745,9 +1745,11 @@ A jump table for the options with a short description can be found at |Q_op|.
enables cancelling the mapping by typing <F1><Esc>.
*cpo-l*
l Backslash in a [] range in a search pattern is taken
- literally, only "\]" is special See |/[]|
+ literally, only "\]", "\^", "\-" and "\\" are special.
+ See |/[]|
'l' included: "/[ \t]" finds <Space>, '\' and 't'
'l' excluded: "/[ \t]" finds <Space> and <Tab>
+ Also see |cpo-\|.
*cpo-L*
L When the 'list' option is set, 'wrapmargin',
'textwidth', 'softtabstop' and Virtual Replace mode
@@ -1895,17 +1897,31 @@ A jump table for the options with a short description can be found at |Q_op|.
contains behavior ~
*cpo-#*
# A count before "D", "o" and "O" has no effect.
+ *cpo-&*
+ & When ":preserve" was used keep the swap file when
+ exiting normally while this buffer is still loaded.
+ This flag is tested when exiting.
+ *cpo-\*
+ \ Backslash in a [] range in a search pattern is taken
+ literally, only "\]" is special See |/[]|
+ 'l' included: "/[ \t]" finds <Space>, '\' and 't'
+ 'l' excluded: "/[ \t]" finds <Space> and <Tab>
+ Also see |cpo-\|.
+ *cpo-/*
+ / When "%" is used as the replacement string in a |:s|
+ command, use the previous replacement string. |:s%|
*cpo-{*
{ The |{| and |}| commands also stop at a "{" character
at the start of a line.
+ *cpo-.*
+ . The ":chdir" and ":cd" commands fail if the current
+ buffer is modified, unless ! is used. Vim doesn't
+ need this, since it remembers the full path of an
+ opened file.
*cpo-bar*
| The value of the $LINES and $COLUMNS environment
variables overrule the terminal size values obtained
with system specific functions.
- *cpo-&*
- & When ":preserve" was used keep the swap file when
- exiting normally while this buffer is still loaded.
- This flag is tested when exiting.
*'cscopepathcomp'* *'cspc'*
@@ -1972,6 +1988,9 @@ A jump table for the options with a short description can be found at |Q_op|.
When set to "msg", error messages that would otherwise be omitted will
be given anyway. This is useful when debugging 'foldexpr' or
'indentexpr'.
+ When set to "beep", a message will be given when otherwise only a beep
+ would be produced.
+ The values can be combined, separated by a comma.
*'define'* *'def'*
'define' 'def' string (default "^\s*#\s*define")
@@ -4708,6 +4727,11 @@ A jump table for the options with a short description can be found at |Q_op|.
List of items that control the format of the output of |:hardcopy|.
See |popt-option|.
+ *'prompt'* *'noprompt'*
+'prompt' boolean (default on)
+ global
+ When on a ":" prompt is used in Ex mode.
+
*'quoteescape'* *'qe'*
'quoteescape' 'qe' string (default "\")
local to buffer
@@ -5239,6 +5263,22 @@ A jump table for the options with a short description can be found at |Q_op|.
separator. To test if this is so use: >
if exists('+shellslash')
<
+ *'shelltemp'* *'stmp'* *'noshelltemp'* *'nostmp'*
+'shelltemp' 'stmp' boolean (Vi default off, Vim default on)
+ global
+ {not in Vi}
+ When on, use temp files for shell commands. When off use a pipe.
+ When using a pipe is not possible temp files are used anyway.
+ Currently a pipe is only supported on Unix. You can check it with: >
+ :if has("filterpipe")
+< The advantage of using a pipe is that nobody can read the temp file
+ and the 'shell' command does not need to support redirection.
+ The advantage of using a temp file is that the file type and encoding
+ can be detected.
+ The |FilterReadPre|, |FilterReadPost| and |FilterWritePre|,
+ |FilterWritePost| autocommands event are not triggered when
+ 'shelltemp' is off.
+
*'shelltype'* *'st'*
'shelltype' 'st' number (default 0)
global
@@ -5288,7 +5328,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|'cindent'|, |>>|, |<<|, etc.
*'shortmess'* *'shm'*
-'shortmess' 'shm' string (Vim default "filnxtToO", Vi default: "")
+'shortmess' 'shm' string (Vim default "filnxtToO", Vi default: "",
+ POSIX default: "A")
global
{not in Vi}
This option helps to avoid all the |hit-enter| prompts caused by file
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
index 2ff676ac2..d12f0a054 100644
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -1,4 +1,4 @@
-*pattern.txt* For Vim version 7.0aa. Last change: 2005 Jan 26
+*pattern.txt* For Vim version 7.0aa. Last change: 2005 Feb 20
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -522,11 +522,6 @@ An atom can be followed by an indication of how many times the atom can be
matched and in what way. This is called a multi. See |/multi| for an
overview.
-It is not possible to use a multi that can match more than one time after an
-atom that can match an empty string. That's because this could result in an
-endless loop. If you try it, you will get this error message: >
- *, \+ or \{ operand could be empty
-<
*/star* */\star* *E56*
* (use \* when 'magic' is not set)
Matches 0 or more of the preceding atom, as many as possible.
@@ -577,7 +572,7 @@ endless loop. If you try it, you will get this error message: >
\{-} matches 0 or more of the preceding atom, as few as possible
{Vi does not have any of these}
- n and m are positive decimal numbers
+ n and m are positive decimal numbers or zero
If a "-" appears immediately after the "{", then a shortest match
first algorithm is used (see example below). In particular, "\{-}" is
@@ -982,6 +977,17 @@ x A single character, with no special meaning, matches itself
a list of at least one character, each of which is either '-', '.',
'/', alphabetic, numeric, '_' or '~'.
These items only work for 8-bit characters.
+ */[[=* *[==]*
+ - An equivalence class. This means that characters are matched that
+ have almost the same meaning, e.g., when ignoring accents. The form
+ is:
+ [=a=]
+ Currrently this is only implemented for latin1. Also works for the
+ latin1 characters in utf-8 and latin9.
+ */[[.* *[..]*
+ - A collation element. This currently simply accepts a single
+ character in the form:
+ [.a.]
*/\]*
- To include a literal ']', '^', '-' or '\' in the collection, put a
backslash before it: "[xyz\]]", "[\^xyz]", "[xy\-z]" and "[xyz\\]".
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index ef8442b25..04fb0ada3 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -1,4 +1,4 @@
-*repeat.txt* For Vim version 7.0aa. Last change: 2005 Jan 28
+*repeat.txt* For Vim version 7.0aa. Last change: 2005 Feb 19
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -81,6 +81,11 @@ This replaces all occurrences of "pat" with "PAT". The same can be done with:
:%s/pat/PAT/g
Which is two characters shorter!
+A special case is using ":visual" as a command. This will move to a matching
+line, go to Normal mode to let you execute commands there until you use |Q| to
+return to Ex mode. This will be repeated for each matching line. While doing
+this you cannot use ":global".
+
==============================================================================
3. Complex repeats *complex-repeat*
@@ -102,7 +107,7 @@ q Stops recording. (Implementation note: The 'q' that
expression. The result of the expression is then
executed. See also |@:|. {Vi: only named registers}
- *@@*
+ *@@* *E748*
@@ Repeat the previous @{0-9a-z":*} [count] times.
:[addr]*{0-9a-z".=} *:@* *:star*
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 46a5e0b02..337c2ca92 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1,4 +1,4 @@
-*starting.txt* For Vim version 7.0aa. Last change: 2005 Feb 10
+*starting.txt* For Vim version 7.0aa. Last change: 2005 Feb 19
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -263,8 +263,14 @@ a slash. Thus "-R" means recovery and "-/R" readonly.
To be used when Vim is used to execute Ex commands from a file
instead of a terminal. Switches off most prompts and
informative messages. Also warnings and error messages.
- But ":print" output is displayed. And when 'verbose' is
- non-zero messages are printed (for debugging).
+ The output of these commands is displayed (to stdout):
+ :print
+ :list
+ :number
+ :set to display option values.
+ When 'verbose' is non-zero messages are printed (for
+ debugging, to stderr).
+ 'term' and $TERM are not used.
If Vim appears to be stuck try typing "qa!<Enter>". You don't
get a prompt thus you can't see Vim is waiting for you to type
something.
diff --git a/runtime/doc/tags b/runtime/doc/tags
index bc1e9ef0f..dedbc71fc 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -506,6 +506,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
'nopi' options.txt /*'nopi'*
'nopreserveindent' options.txt /*'nopreserveindent'*
'nopreviewwindow' options.txt /*'nopreviewwindow'*
+'noprompt' options.txt /*'noprompt'*
'nopvw' options.txt /*'nopvw'*
'noreadonly' options.txt /*'noreadonly'*
'noremap' options.txt /*'noremap'*
@@ -528,6 +529,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
'nosecure' options.txt /*'nosecure'*
'nosft' options.txt /*'nosft'*
'noshellslash' options.txt /*'noshellslash'*
+'noshelltemp' options.txt /*'noshelltemp'*
'noshiftround' options.txt /*'noshiftround'*
'noshortname' options.txt /*'noshortname'*
'noshowcmd' options.txt /*'noshowcmd'*
@@ -549,6 +551,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
'nossl' options.txt /*'nossl'*
'nosta' options.txt /*'nosta'*
'nostartofline' options.txt /*'nostartofline'*
+'nostmp' options.txt /*'nostmp'*
'noswapfile' options.txt /*'noswapfile'*
'noswf' options.txt /*'noswf'*
'nota' options.txt /*'nota'*
@@ -633,7 +636,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
'printmbcharset' options.txt /*'printmbcharset'*
'printmbfont' options.txt /*'printmbfont'*
'printoptions' options.txt /*'printoptions'*
-'prompt' vi_diff.txt /*'prompt'*
+'prompt' options.txt /*'prompt'*
'pt' options.txt /*'pt'*
'pvh' options.txt /*'pvh'*
'pvw' options.txt /*'pvw'*
@@ -687,6 +690,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
'shellquote' options.txt /*'shellquote'*
'shellredir' options.txt /*'shellredir'*
'shellslash' options.txt /*'shellslash'*
+'shelltemp' options.txt /*'shelltemp'*
'shelltype' options.txt /*'shelltype'*
'shellxquote' options.txt /*'shellxquote'*
'shiftround' options.txt /*'shiftround'*
@@ -732,6 +736,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
'startofline' options.txt /*'startofline'*
'statusline' options.txt /*'statusline'*
'stl' options.txt /*'stl'*
+'stmp' options.txt /*'stmp'*
'sts' options.txt /*'sts'*
'su' options.txt /*'su'*
'sua' options.txt /*'sua'*
@@ -1213,6 +1218,8 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
/. pattern.txt /*\/.*
//; pattern.txt /*\/\/;*
/<CR> pattern.txt /*\/<CR>*
+/[[. pattern.txt /*\/[[.*
+/[[= pattern.txt /*\/[[=*
/[] pattern.txt /*\/[]*
/\ pattern.txt /*\/\\*
/\$ pattern.txt /*\/\\$*
@@ -1848,7 +1855,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
:display change.txt /*:display*
:dj tagsrch.txt /*:dj*
:djump tagsrch.txt /*:djump*
-:dl tagsrch.txt /*:dl*
+:dli tagsrch.txt /*:dli*
:dlist tagsrch.txt /*:dlist*
:do autocmd.txt /*:do*
:doau autocmd.txt /*:doau*
@@ -2280,6 +2287,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
:rv starting.txt /*:rv*
:rviminfo starting.txt /*:rviminfo*
:s change.txt /*:s*
+:s% change.txt /*:s%*
:sN windows.txt /*:sN*
:sNext windows.txt /*:sNext*
:s\= change.txt /*:s\\=*
@@ -2840,6 +2848,7 @@ CTRL-M motion.txt /*CTRL-M*
CTRL-N motion.txt /*CTRL-N*
CTRL-O motion.txt /*CTRL-O*
CTRL-P motion.txt /*CTRL-P*
+CTRL-Q gui_w32.txt /*CTRL-Q*
CTRL-R undo.txt /*CTRL-R*
CTRL-T tagsrch.txt /*CTRL-T*
CTRL-U scroll.txt /*CTRL-U*
@@ -3653,6 +3662,10 @@ E742 eval.txt /*E742*
E743 eval.txt /*E743*
E744 netbeans.txt /*E744*
E745 eval.txt /*E745*
+E746 eval.txt /*E746*
+E747 syntax.txt /*E747*
+E748 repeat.txt /*E748*
+E749 eval.txt /*E749*
E75 vi_diff.txt /*E75*
E76 pattern.txt /*E76*
E77 message.txt /*E77*
@@ -3922,6 +3935,7 @@ ZZ editing.txt /*ZZ*
[( motion.txt /*[(*
[++opt] editing.txt /*[++opt]*
[+cmd] editing.txt /*[+cmd]*
+[..] pattern.txt /*[..]*
[/ motion.txt /*[\/*
[:alnum:] pattern.txt /*[:alnum:]*
[:alpha:] pattern.txt /*[:alpha:]*
@@ -3940,6 +3954,7 @@ ZZ editing.txt /*ZZ*
[:upper:] pattern.txt /*[:upper:]*
[:xdigit:] pattern.txt /*[:xdigit:]*
[<MiddleMouse> change.txt /*[<MiddleMouse>*
+[==] pattern.txt /*[==]*
[D tagsrch.txt /*[D*
[I tagsrch.txt /*[I*
[M motion.txt /*[M*
@@ -4121,6 +4136,7 @@ autocmds-kept version5.txt /*autocmds-kept*
autocommand autocmd.txt /*autocommand*
autocommand-events autocmd.txt /*autocommand-events*
autocommand-pattern autocmd.txt /*autocommand-pattern*
+autoload eval.txt /*autoload*
autoload-functions eval.txt /*autoload-functions*
avoid-hit-enter version5.txt /*avoid-hit-enter*
aw motion.txt /*aw*
@@ -4385,6 +4401,8 @@ cpo-% options.txt /*cpo-%*
cpo-& options.txt /*cpo-&*
cpo-+ options.txt /*cpo-+*
cpo-- options.txt /*cpo--*
+cpo-. options.txt /*cpo-.*
+cpo-/ options.txt /*cpo-\/*
cpo-< options.txt /*cpo-<*
cpo-> options.txt /*cpo->*
cpo-A options.txt /*cpo-A*
@@ -4404,6 +4422,8 @@ cpo-R options.txt /*cpo-R*
cpo-S options.txt /*cpo-S*
cpo-W options.txt /*cpo-W*
cpo-X options.txt /*cpo-X*
+cpo-Z options.txt /*cpo-Z*
+cpo-\ options.txt /*cpo-\\*
cpo-a options.txt /*cpo-a*
cpo-b options.txt /*cpo-b*
cpo-bar options.txt /*cpo-bar*
@@ -4655,6 +4675,7 @@ evim.vim starting.txt /*evim.vim*
ex starting.txt /*ex*
ex-cmd-index index.txt /*ex-cmd-index*
ex-edit-index index.txt /*ex-edit-index*
+ex-flags cmdline.txt /*ex-flags*
ex: options.txt /*ex:*
except-autocmd eval.txt /*except-autocmd*
except-autocmd-Cmd eval.txt /*except-autocmd-Cmd*
@@ -5048,7 +5069,6 @@ hebrew hebrew.txt /*hebrew*
hebrew.txt hebrew.txt /*hebrew.txt*
help various.txt /*help*
help-context help.txt /*help-context*
-help-tags tags 1
help-translated various.txt /*help-translated*
help-xterm-window various.txt /*help-xterm-window*
help.txt help.txt /*help.txt*
@@ -5503,8 +5523,8 @@ messages message.txt /*messages*
meta intro.txt /*meta*
min() eval.txt /*min()*
minimal-features os_msdos.txt /*minimal-features*
-missing-commands vi_diff.txt /*missing-commands*
missing-options vi_diff.txt /*missing-options*
+mkdir() eval.txt /*mkdir()*
mlang.txt mlang.txt /*mlang.txt*
mode() eval.txt /*mode()*
mode-Ex intro.txt /*mode-Ex*
@@ -6132,6 +6152,7 @@ sign.txt sign.txt /*sign.txt*
signs sign.txt /*signs*
simple-change change.txt /*simple-change*
simplify() eval.txt /*simplify()*
+simulated-command vi_diff.txt /*simulated-command*
single-repeat repeat.txt /*single-repeat*
skeleton autocmd.txt /*skeleton*
slow-fast-terminal term.txt /*slow-fast-terminal*
@@ -6206,6 +6227,7 @@ swap-file recover.txt /*swap-file*
swapfile-changed version4.txt /*swapfile-changed*
syn-sync-grouphere syntax.txt /*syn-sync-grouphere*
syn-sync-groupthere syntax.txt /*syn-sync-groupthere*
+syn-sync-linecont syntax.txt /*syn-sync-linecont*
synID() eval.txt /*synID()*
synIDattr() eval.txt /*synIDattr()*
synIDtrans() eval.txt /*synIDtrans()*
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index f9616a72b..fb7cf9e1c 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -1,4 +1,4 @@
-*windows.txt* For Vim version 7.0aa. Last change: 2005 Jan 26
+*windows.txt* For Vim version 7.0aa. Last change: 2005 Feb 18
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -587,7 +587,7 @@ can also get to them with the buffer list commands, like ":bnext".
not split. Also see |++opt| and |+cmd|.
*:sfir* *:sfirst*
-:sfir[st [++opt] [+cmd]
+:sfir[st] [++opt] [+cmd]
Same as ":srewind".
*:sla* *:slast*
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index fa1908cf7..bbbb6d2c1 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1,7 +1,7 @@
" Vim support file to detect file types
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2005 Jan 27
+" Last Change: 2005 Feb 18
" Listen very carefully, I will say this only once
if exists("did_load_filetypes")
@@ -512,6 +512,9 @@ au BufNewFile,BufRead *.erl setf erlang
" Elm Filter Rules file
au BufNewFile,BufRead filter-rules setf elmfilt
+" ESMTP rc file
+au BufNewFile,BufRead *esmtprc setf esmtprc
+
" ESQL-C
au BufNewFile,BufRead *.ec,*.EC setf esqlc
diff --git a/runtime/ftplugin/vim.vim b/runtime/ftplugin/vim.vim
index fce830e8e..698d3ee87 100644
--- a/runtime/ftplugin/vim.vim
+++ b/runtime/ftplugin/vim.vim
@@ -1,7 +1,7 @@
" Vim filetype plugin
" Language: Vim
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2004 Sep 13
+" Last Change: 2005 Feb 14
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -58,4 +58,6 @@ if exists("loaded_matchit")
endif
let &cpo = cpo_save
-setlocal cpo+=M " makes \%( match \)
+
+" removed this, because 'cpoptions' is a global option.
+" setlocal cpo+=M " makes \%( match \)
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 05c85b49f..4c9d17d78 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -681,16 +681,29 @@ getcmdline(firstc, count, indent)
if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
&& (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
{
- gotesc = FALSE; /* Might have typed ESC previously, don't
- truncate the cmdline now. */
- if (ccheck_abbr(c + ABBR_OFF))
- goto cmdline_changed;
- if (!cmd_silent)
+ /* In Ex mode a backslash escapes a newline. */
+ if (exmode_active
+ && c != ESC
+ && ccline.cmdpos > 0
+ && ccline.cmdpos == ccline.cmdlen
+ && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
{
- windgoto(msg_row, 0);
- out_flush();
+ if (c == K_KENTER)
+ c = '\n';
+ }
+ else
+ {
+ gotesc = FALSE; /* Might have typed ESC previously, don't
+ truncate the cmdline now. */
+ if (ccheck_abbr(c + ABBR_OFF))
+ goto cmdline_changed;
+ if (!cmd_silent)
+ {
+ windgoto(msg_row, 0);
+ out_flush();
+ }
+ break;
}
- break;
}
/*
@@ -1879,25 +1892,24 @@ getexline(c, dummy, indent)
* Get an Ex command line for Ex mode.
* In Ex mode we only use the OS supplied line editing features and no
* mappings or abbreviations.
+ * Returns a string in allocated memory or NULL.
*/
/* ARGSUSED */
char_u *
-getexmodeline(c, dummy, indent)
- int c; /* normally ':', NUL for ":append" */
+getexmodeline(promptc, dummy, indent)
+ int promptc; /* normally ':', NUL for ":append" and '?' for
+ :s prompt */
void *dummy; /* cookie not used */
int indent; /* indent for inside conditionals */
{
- garray_T line_ga;
- int len;
- int off = 0;
- char_u *pend;
- int finished = FALSE;
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
- int startcol = 0;
- int c1;
- int escaped = FALSE; /* CTRL-V typed */
- int vcol = 0;
-#endif
+ garray_T line_ga;
+ char_u *pend;
+ int startcol = 0;
+ int c1;
+ int escaped = FALSE; /* CTRL-V typed */
+ int vcol = 0;
+ char_u *p;
+ int prev_char = 0;
/* Switch cursor on now. This avoids that it happens after the "\n", which
* confuses the system function that computes tabstops. */
@@ -1905,27 +1917,24 @@ getexmodeline(c, dummy, indent)
/* always start in column 0; write a newline if necessary */
compute_cmdrow();
- if (msg_col)
+ if ((msg_col || msg_didout) && promptc != '?')
msg_putchar('\n');
- if (c == ':')
+ if (promptc == ':')
{
/* indent that is only displayed, not in the line itself */
- msg_putchar(':');
+ if (p_prompt)
+ msg_putchar(':');
while (indent-- > 0)
msg_putchar(' ');
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
startcol = msg_col;
-#endif
}
ga_init2(&line_ga, 1, 30);
/* autoindent for :insert and :append is in the line itself */
- if (c <= 0)
+ if (promptc <= 0)
{
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
vcol = indent;
-#endif
while (indent >= 8)
{
ga_append(&line_ga, TAB);
@@ -1938,198 +1947,180 @@ getexmodeline(c, dummy, indent)
msg_putchar(' ');
}
}
+ ++no_mapping;
+ ++allow_keys;
/*
* Get the line, one character at a time.
*/
got_int = FALSE;
- while (!got_int && !finished)
+ while (!got_int)
{
if (ga_grow(&line_ga, 40) == FAIL)
break;
pend = (char_u *)line_ga.ga_data + line_ga.ga_len;
- /* Get one character (inchar gets a third of maxlen characters!) */
- len = inchar(pend + off, 3, -1L, 0);
- if (len < 0)
- continue; /* end of input script reached */
- /* for a special character, we need at least three characters */
- if ((*pend == K_SPECIAL || *pend == CSI) && off + len < 3)
- {
- off += len;
- continue;
- }
- len += off;
- off = 0;
+ /* Get one character at a time. Don't use inchar(), it can't handle
+ * special characters. */
+ c1 = vgetc();
/*
- * When using the GUI, and for systems that don't have cooked input,
- * handle line editing here.
+ * Handle line editing.
+ * Previously this was left to the system, putting the terminal in
+ * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
*/
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
-# ifndef NO_COOKED_INPUT
- if (gui.in_use)
-# endif
+ if (got_int)
{
- if (got_int)
- {
- msg_putchar('\n');
- break;
- }
+ msg_putchar('\n');
+ break;
+ }
- while (len > 0)
+ if (!escaped)
+ {
+ /* CR typed means "enter", which is NL */
+ if (c1 == '\r')
+ c1 = '\n';
+
+ if (c1 == BS || c1 == K_BS
+ || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
{
- c1 = *pend++;
- --len;
- if ((c1 == K_SPECIAL
-# if !defined(NO_COOKED_INPUT) || defined(FEAT_GUI)
- || c1 == CSI
-# endif
- ) && len >= 2)
+ if (line_ga.ga_len > 0)
{
- c1 = TO_SPECIAL(pend[0], pend[1]);
- pend += 2;
- len -= 2;
+ --line_ga.ga_len;
+ goto redraw;
}
+ continue;
+ }
- if (!escaped)
- {
- /* CR typed means "enter", which is NL */
- if (c1 == '\r')
- c1 = '\n';
-
- if (c1 == BS || c1 == K_BS
- || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
- {
- if (line_ga.ga_len > 0)
- {
- int i, v;
- char_u *q;
-
- --line_ga.ga_len;
- /* compute column that cursor should be in */
- v = 0;
- q = ((char_u *)line_ga.ga_data);
- for (i = 0; i < line_ga.ga_len; ++i)
- {
- if (*q == TAB)
- v += 8 - v % 8;
- else
- v += ptr2cells(q);
- ++q;
- }
- /* erase characters to position cursor */
- while (vcol > v)
- {
- msg_putchar('\b');
- msg_putchar(' ');
- msg_putchar('\b');
- --vcol;
- }
- }
- continue;
- }
-
- if (c1 == Ctrl_U)
- {
- msg_col = startcol;
- msg_clr_eos();
- line_ga.ga_len = 0;
- continue;
- }
+ if (c1 == Ctrl_U)
+ {
+ msg_col = startcol;
+ msg_clr_eos();
+ line_ga.ga_len = 0;
+ continue;
+ }
- if (c1 == Ctrl_T)
- c1 = TAB; /* very simplistic... */
+ if (c1 == Ctrl_T)
+ {
+ p = (char_u *)line_ga.ga_data;
+ p[line_ga.ga_len] = NUL;
+ indent = get_indent_str(p, 8);
+ indent += curbuf->b_p_sw - indent % curbuf->b_p_sw;
+add_indent:
+ while (get_indent_str(p, 8) < indent)
+ {
+ char_u *s = skipwhite(p);
- if (c1 == Ctrl_D)
+ ga_grow(&line_ga, 1);
+ mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
+ *s = ' ';
+ ++line_ga.ga_len;
+ }
+redraw:
+ /* redraw the line */
+ msg_col = startcol;
+ windgoto(msg_row, msg_col);
+ vcol = 0;
+ for (p = (char_u *)line_ga.ga_data;
+ p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
+ {
+ if (*p == TAB)
{
- char_u *p;
-
- /* Delete one shiftwidth. */
- p = (char_u *)line_ga.ga_data;
- p[line_ga.ga_len] = NUL;
- indent = get_indent_str(p, 8);
- --indent;
- indent -= indent % 8;
- while (get_indent_str(p, 8) > indent)
- {
- char_u *s = skipwhite(p);
-
- mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
- --line_ga.ga_len;
- }
- msg_col = startcol;
- for (vcol = 0; *p != NUL; ++p)
+ do
{
- if (*p == TAB)
- {
- do
- {
- msg_putchar(' ');
- } while (++vcol % 8);
- }
- else
- {
- msg_outtrans_len(p, 1);
- vcol += char2cells(*p);
- }
- }
- msg_clr_eos();
- continue;
+ msg_putchar(' ');
+ } while (++vcol % 8);
}
-
- if (c1 == Ctrl_V)
+ else
{
- escaped = TRUE;
- continue;
+ msg_outtrans_len(p, 1);
+ vcol += char2cells(*p);
}
}
+ msg_clr_eos();
+ continue;
+ }
- if (IS_SPECIAL(c1))
- c1 = '?';
- ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
- if (c1 == '\n')
- msg_putchar('\n');
- else if (c1 == TAB)
+ if (c1 == Ctrl_D)
+ {
+ /* Delete one shiftwidth. */
+ p = (char_u *)line_ga.ga_data;
+ if (prev_char == '0' || prev_char == '^')
{
- /* Don't use chartabsize(), 'ts' can be different */
- do
- {
- msg_putchar(' ');
- } while (++vcol % 8);
+ if (prev_char == '^')
+ ex_keep_indent = TRUE;
+ indent = 0;
+ p[--line_ga.ga_len] = NUL;
}
else
{
- msg_outtrans_len(
- ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
- vcol += char2cells(c1);
+ p[line_ga.ga_len] = NUL;
+ indent = get_indent_str(p, 8);
+ --indent;
+ indent -= indent % curbuf->b_p_sw;
+ }
+ while (get_indent_str(p, 8) > indent)
+ {
+ char_u *s = skipwhite(p);
+
+ mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
+ --line_ga.ga_len;
}
- ++line_ga.ga_len;
- escaped = FALSE;
+ goto add_indent;
+ }
+
+ if (c1 == Ctrl_V || c1 == Ctrl_Q)
+ {
+ escaped = TRUE;
+ continue;
}
- windgoto(msg_row, msg_col);
+
+ /* Ignore special key codes: mouse movement, K_IGNORE, etc. */
+ if (IS_SPECIAL(c1))
+ continue;
+ }
+
+ if (IS_SPECIAL(c1))
+ c1 = '?';
+ ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+ prev_char = c1;
+ if (c1 == '\n')
+ msg_putchar('\n');
+ else if (c1 == TAB)
+ {
+ /* Don't use chartabsize(), 'ts' can be different */
+ do
+ {
+ msg_putchar(' ');
+ } while (++vcol % 8);
}
-# ifndef NO_COOKED_INPUT
else
-# endif
-#endif
-#ifndef NO_COOKED_INPUT
{
- line_ga.ga_len += len;
+ msg_outtrans_len(
+ ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
+ vcol += char2cells(c1);
}
-#endif
+ ++line_ga.ga_len;
+ escaped = FALSE;
+
+ windgoto(msg_row, msg_col);
pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
- if (line_ga.ga_len && pend[-1] == '\n')
+
+ /* we are done when a NL is entered, but not when it comes after a
+ * backslash */
+ if (line_ga.ga_len > 0 && pend[-1] == '\n'
+ && (line_ga.ga_len <= 1 || pend[-2] != '\\'))
{
- finished = TRUE;
--line_ga.ga_len;
--pend;
*pend = NUL;
+ break;
}
}
- /* note that cursor has moved, because of the echoed <CR> */
- screen_down();
+ --no_mapping;
+ --allow_keys;
+
/* make following messages go to the next line */
msg_didout = FALSE;
msg_col = 0;
@@ -3797,10 +3788,10 @@ addstar(fname, len, context)
set_expand_context(xp)
expand_T *xp;
{
- /* only expansion for ':' and '>' commands */
+ /* only expansion for ':', '>' and '=' command-lines */
if (ccline.cmdfirstc != ':'
#ifdef FEAT_EVAL
- && ccline.cmdfirstc != '>'
+ && ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
#endif
)
{
@@ -3828,8 +3819,16 @@ set_cmd_context(xp, str, len, col)
old_char = str[col];
str[col] = NUL;
nextcomm = str;
- while (nextcomm != NULL)
- nextcomm = set_one_cmd_context(xp, nextcomm);
+
+#ifdef FEAT_EVAL
+ if (ccline.cmdfirstc == '=')
+ /* pass CMD_SIZE because there is no real command */
+ set_context_for_expression(xp, str, CMD_SIZE);
+ else
+#endif
+ while (nextcomm != NULL)
+ nextcomm = set_one_cmd_context(xp, nextcomm);
+
str[col] = old_char;
}
@@ -5477,7 +5476,7 @@ ex_window()
* Call the main loop until <CR> or CTRL-C is typed.
*/
cmdwin_result = 0;
- main_loop(TRUE);
+ main_loop(TRUE, FALSE);
RedrawingDisabled = i;
diff --git a/src/gui_mac.c b/src/gui_mac.c
index dbdda8a0d..b43aec0e5 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -91,6 +91,19 @@ static OSType _ftype = 'TEXT';
static EventHandlerUPP mouseWheelHandlerUPP = NULL;
#endif
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+# define USE_CARBONKEYHANDLER
+static EventHandlerUPP keyEventHandlerUPP = NULL;
+/* Defined in os_mac_conv.c */
+extern char_u *mac_utf16_to_enc __ARGS((UniChar *from, size_t fromLen, size_t *actualLen));
+extern UniChar *mac_enc_to_utf16 __ARGS((char_u *from, size_t fromLen, size_t *actualLen));
+extern CFStringRef mac_enc_to_cfstring __ARGS((char_u *from, size_t fromLen));
+#endif
+
+#ifdef MACOS_X
+SInt32 gMacSystemVersion;
+#endif
+
/* Debugging feature: start Vim window OFFSETed */
#undef USE_OFFSETED_WINDOW
@@ -213,6 +226,12 @@ static struct
} gFontPanelInfo = { 0, 0, 0, false };
#endif
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+# define USE_ATSUI_DRAWING
+ATSUStyle gFontStyle;
+Boolean gIsFontFallbackSet;
+#endif
+
/*
* The Quickdraw global is predefined in CodeWarior
* but is not in Apple MPW
@@ -504,6 +523,63 @@ points_to_pixels(char_u *str, char_u **end, int vertical)
return pixels;
}
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+/*
+ * Deletes all traces of any Windows-style mnemonic text (including any
+ * parentheses) from a menu item and returns the cleaned menu item title.
+ * The caller is responsible for releasing the returned string.
+ */
+ static CFStringRef
+menu_title_removing_mnemonic(menu)
+ vimmenu_T *menu;
+{
+ CFStringRef name;
+ size_t menuTitleLen;
+ CFIndex displayLen;
+ CFRange mnemonicStart;
+ CFRange mnemonicEnd;
+ CFMutableStringRef cleanedName;
+
+ menuTitleLen = STRLEN(menu->dname);
+ name = mac_enc_to_cfstring(menu->dname, menuTitleLen);
+
+ if (name)
+ {
+ /* Simple mnemonic-removal algorithm, assumes single parenthesized
+ * mnemonic character towards the end of the menu text */
+ mnemonicStart = CFStringFind(name, CFSTR("("), kCFCompareBackwards);
+ displayLen = CFStringGetLength(name);
+
+ if (mnemonicStart.location != kCFNotFound
+ && (mnemonicStart.location + 2) < displayLen
+ && CFStringGetCharacterAtIndex(name,
+ mnemonicStart.location + 1) == (UniChar)menu->mnemonic)
+ {
+ if (CFStringFindWithOptions(name, CFSTR(")"),
+ CFRangeMake(mnemonicStart.location + 1,
+ displayLen - mnemonicStart.location - 1),
+ kCFCompareBackwards, &mnemonicEnd) &&
+ (mnemonicStart.location + 2) == mnemonicEnd.location)
+ {
+ cleanedName = CFStringCreateMutableCopy(NULL, 0, name);
+ if (cleanedName)
+ {
+ CFStringDelete(cleanedName,
+ CFRangeMake(mnemonicStart.location,
+ mnemonicEnd.location + 1 -
+ mnemonicStart.location));
+
+ CFRelease(name);
+ name = cleanedName;
+ }
+ }
+ }
+ }
+
+ return name;
+}
+#endif
+
/*
* Convert a list of FSSpec aliases into a list of fullpathname
* character strings.
@@ -1231,20 +1307,19 @@ HandleODocAE(const AppleEvent *theAEvent, AppleEvent *theReply, long refCon)
/* Select the text if possible */
if (gotPosition)
{
- VIsual_active = TRUE;
- VIsual_select = FALSE;
- if (thePosition.lineNum < 0)
+ VIsual_active = TRUE;
+ VIsual_select = FALSE;
+ VIsual = curwin->w_cursor;
+ if (thePosition.lineNum < 0)
{
- VIsual_mode = 'v';
- VIsual = curwin->w_cursor;
- goto_byte(thePosition.endRange);
- }
- else
+ VIsual_mode = 'v';
+ goto_byte(thePosition.endRange);
+ }
+ else
{
- VIsual_mode = 'V';
- VIsual = curwin->w_cursor;
- VIsual.col = 0;
- }
+ VIsual_mode = 'V';
+ VIsual.col = 0;
+ }
}
#endif
setcursor();
@@ -1541,25 +1616,47 @@ InstallFontPanelHandler()
* Fill the buffer pointed to by outName with the name and size
* of the font currently selected in the Font Panel.
*/
+#define FONT_STYLE_BUFFER_SIZE 32
static void
GetFontPanelSelection(char_u* outName)
{
- Str255 buf;
- Boolean isBold = false, isItalic = false;
+ Str255 buf;
+ ByteCount fontNameLen = 0;
+ ATSUFontID fid;
+ char_u styleString[FONT_STYLE_BUFFER_SIZE];
if (!outName)
return;
- (void)FMGetFontFamilyName(gFontPanelInfo.family, buf);
- p2cstrcpy(outName, buf);
+ if (FMGetFontFamilyName(gFontPanelInfo.family, buf) == noErr)
+ {
+ /* Canonicalize localized font names */
+ if (FMGetFontFromFontFamilyInstance(gFontPanelInfo.family,
+ gFontPanelInfo.style, &fid, NULL) != noErr)
+ return;
-#if 0 /* TODO: enable when styles are supported in gui_mac_find_font() */
- isBold = (gFontPanelInfo.style & bold);
- isItalic = (gFontPanelInfo.style & italic);
-#endif
+ /* Request font name with Mac encoding (otherwise we could
+ * get an unwanted utf-16 name) */
+ if (ATSUFindFontName(fid, kFontFullName, kFontMacintoshPlatform,
+ kFontNoScriptCode, kFontNoLanguageCode,
+ 255, outName, &fontNameLen, NULL) != noErr)
+ return;
- sprintf(&outName[buf[0]], ":h%d%s%s", gFontPanelInfo.size,
- (isBold ? ":b" : ""), (isItalic ? ":i" : ""));
+ /* Only encode font size, because style (bold, italic, etc) is
+ * already part of the font full name */
+ snprintf(styleString, FONT_STYLE_BUFFER_SIZE, ":h%d",
+ gFontPanelInfo.size/*,
+ ((gFontPanelInfo.style & bold)!=0 ? ":b" : ""),
+ ((gFontPanelInfo.style & italic)!=0 ? ":i" : ""),
+ ((gFontPanelInfo.style & underline)!=0 ? ":u" : "")*/);
+
+ if ((fontNameLen + STRLEN(styleString)) < 255)
+ STRCPY(outName + fontNameLen, styleString);
+ }
+ else
+ {
+ *outName = NULL;
+ }
}
#endif
@@ -2213,7 +2310,187 @@ gui_mac_doSuspendEvent(event)
/*
* Handle the key
*/
+#ifdef USE_CARBONKEYHANDLER
+# define INLINE_KEY_BUFFER_SIZE 80
+ static pascal OSStatus
+gui_mac_doKeyEventCarbon(EventHandlerCallRef nextHandler, EventRef theEvent,
+ void *data)
+{
+ /* Multibyte-friendly key event handler */
+ OSStatus e = -1;
+ UInt32 actualSize;
+ UniChar *text;
+ char_u result[INLINE_KEY_BUFFER_SIZE];
+ short len = 0;
+ UInt32 key_sym;
+ char charcode;
+ int key_char;
+ UInt32 modifiers;
+ size_t encLen;
+ char_u *to = NULL;
+ Boolean isSpecial = FALSE;
+ int i;
+
+ /* Mask the mouse (as per user setting) */
+ if (p_mh)
+ ObscureCursor();
+
+ do
+ {
+ if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText,
+ typeUnicodeText, NULL, 0, &actualSize, NULL))
+ break;
+
+ text = (UniChar *)alloc(actualSize);
+
+ if (text)
+ {
+ do
+ {
+ if (noErr != GetEventParameter(theEvent,
+ kEventParamTextInputSendText,
+ typeUnicodeText, NULL, actualSize, NULL, text))
+ break;
+ EventRef keyEvent;
+ if (noErr != GetEventParameter(theEvent,
+ kEventParamTextInputSendKeyboardEvent,
+ typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent))
+ break;
+ if (noErr != GetEventParameter(keyEvent,
+ kEventParamKeyModifiers,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers))
+ break;
+ if (noErr != GetEventParameter(keyEvent,
+ kEventParamKeyCode,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym))
+ break;
+ if (noErr != GetEventParameter(keyEvent,
+ kEventParamKeyMacCharCodes,
+ typeChar, NULL, sizeof(char), NULL, &charcode))
+ break;
+
+ key_char = charcode;
+
+ if (modifiers & controlKey)
+ {
+ if ((modifiers & ~(controlKey|shiftKey)) == 0
+ && (key_char == '2' || key_char == '6'))
+ {
+ /* CTRL-^ and CTRL-@ don't work in the normal way. */
+ if (key_char == '2')
+ key_char = Ctrl_AT;
+ else
+ key_char = Ctrl_HAT;
+
+ text[0] = (UniChar)key_char;
+ modifiers = 0;
+ }
+ }
+
+ if (modifiers & cmdKey)
+#ifndef USE_CMD_KEY
+ break; /* Let system handle Cmd+... */
+#else
+ {
+ /* Intercept CMD-. */
+ if (key_char == '.')
+ got_int = TRUE;
+
+ /* Convert the modifiers */
+ modifiers = EventModifiers2VimModifiers(modifiers);
+
+ /* Following code to simplify and consolidate modifiers
+ * taken liberally from gui_w48.c */
+
+ key_char = simplify_key(key_char, (int *)&modifiers);
+
+ /* remove SHIFT for keys that are already shifted, e.g.,
+ * '(' and '*' */
+ if (key_char < 0x100 &&
+ !isalpha(key_char) && isprint(key_char))
+ modifiers &= ~MOD_MASK_SHIFT;
+
+ /* Interpret META, include SHIFT, etc. */
+ key_char = extract_modifiers(key_char, (int *)&modifiers);
+ if (key_char == CSI)
+ key_char = K_CSI;
+
+ if (modifiers)
+ {
+ result[len++] = CSI;
+ result[len++] = KS_MODIFIER;
+ result[len++] = modifiers;
+ }
+
+ isSpecial = TRUE;
+ }
+#endif
+ else
+ {
+ /* Find the special key (eg., for cursor keys) */
+ if (!(actualSize > sizeof(UniChar)) &&
+ ((text[0] < 0x20) || (text[0] == 0x7f)))
+ {
+ for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i)
+ if (special_keys[i].key_sym == key_sym)
+ {
+ key_char = TO_SPECIAL(special_keys[i].vim_code0,
+ special_keys[i].vim_code1);
+ key_char = simplify_key(key_char,
+ (int *)&modifiers);
+ isSpecial = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (isSpecial && IS_SPECIAL(key_char))
+ {
+ result[len++] = CSI;
+ result[len++] = K_SECOND(key_char);
+ result[len++] = K_THIRD(key_char);
+ }
+ else
+ {
+ encLen = actualSize;
+ to = mac_utf16_to_enc(text, actualSize, &encLen);
+ }
+
+ if (to)
+ {
+ /* This is basically add_to_input_buf_csi() */
+ for (i = 0; i < encLen && len < (INLINE_KEY_BUFFER_SIZE-1); ++i)
+ {
+ result[len++] = to[i];
+ if (to[i] == CSI)
+ {
+ result[len++] = KS_EXTRA;
+ result[len++] = (int)KE_CSI;
+ }
+ }
+ vim_free(to);
+ }
+ add_to_input_buf(result, len);
+ e = noErr;
+ }
+ while (0);
+
+ vim_free(text);
+ if (e == noErr)
+ {
+ /* Fake event to wake up WNE (required to get
+ * key repeat working */
+ PostEvent(keyUp, 0);
+ return noErr;
+ }
+ }
+ }
+ while (0);
+
+ return CallNextEventHandler(nextHandler, theEvent);
+}
+#else
void
gui_mac_doKeyEvent(EventRecord *theEvent)
{
@@ -2387,6 +2664,7 @@ gui_mac_doKeyEvent(EventRecord *theEvent)
add_to_input_buf(string, len);
}
+#endif
/*
* Handle MouseClick
@@ -2664,11 +2942,12 @@ gui_mac_handle_event(event)
/* Handle normal event */
switch (event->what)
{
+#ifndef USE_CARBONKEYHANDLER
case (keyDown):
case (autoKey):
gui_mac_doKeyEvent(event);
break;
-
+#endif
case (keyUp):
/* We don't care about when the key get release */
break;
@@ -2747,7 +3026,27 @@ gui_mac_find_font(font_name)
pFontName[0] = STRLEN(font_name);
*p = c;
+ /* Get the font name, minus the style suffix (:h, etc) */
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+ char_u fontName[256];
+ char_u *styleStart = vim_strchr(font_name, ':');
+ size_t fontNameLen = styleStart ? styleStart - font_name : STRLEN(fontName);
+ vim_strncpy(fontName, font_name, fontNameLen);
+
+ ATSUFontID fontRef;
+ FMFontStyle fontStyle;
+ font_id = 0;
+
+ if (ATSUFindFontFromName(&pFontName[1], pFontName[0], kFontFullName,
+ kFontMacintoshPlatform, kFontNoScriptCode, kFontNoLanguageCode,
+ &fontRef) == noErr)
+ {
+ if (FMGetFontFamilyInstanceFromFont(fontRef, &font_id, &fontStyle) != noErr)
+ font_id = 0;
+ }
+#else
GetFNum(pFontName, &font_id);
+#endif
if (font_id == 0)
{
@@ -2767,7 +3066,17 @@ gui_mac_find_font(font_name)
}
}
if (changed)
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+ if (ATSUFindFontFromName(&pFontName[1], pFontName[0],
+ kFontFullName, kFontNoPlatformCode, kFontNoScriptCode,
+ kFontNoLanguageCode, &fontRef) == noErr)
+ {
+ if (FMGetFontFamilyInstanceFromFont(fontRef, &font_id, &fontStyle) != noErr)
+ font_id = 0;
+ }
+#else
GetFNum(pFontName, &font_id);
+#endif
}
#else
@@ -2782,7 +3091,12 @@ gui_mac_find_font(font_name)
{
/* Oups, the system font was it the one the user want */
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+ if (FMGetFontFamilyName(systemFont, systemFontname) != noErr)
+ return NOFONT;
+#else
GetFontName(0, systemFontname);
+#endif
if (!EqualString(pFontName, systemFontname, false, false))
return NOFONT;
}
@@ -3079,6 +3393,15 @@ gui_mch_init()
EventTypeSpec eventTypeSpec;
EventHandlerRef mouseWheelHandlerRef;
#endif
+#ifdef USE_CARBONKEYHANDLER
+ EventHandlerRef keyEventHandlerRef;
+#endif
+
+#ifdef MACOS_X
+ if (Gestalt(gestaltSystemVersion, &gMacSystemVersion) != noErr)
+ gMacSystemVersion = 0x1000; /* Default to minimum sensible value */
+#endif
+
#if 1
InitCursor();
@@ -3238,9 +3561,24 @@ gui_mch_init()
}
#endif
+#ifdef USE_CARBONKEYHANDLER
+ eventTypeSpec.eventClass = kEventClassTextInput;
+ eventTypeSpec.eventKind = kEventUnicodeForKeyEvent;
+ keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_doKeyEventCarbon);
+ if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP, 1,
+ &eventTypeSpec, NULL, &keyEventHandlerRef))
+ {
+ keyEventHandlerRef = NULL;
+ DisposeEventHandlerUPP(keyEventHandlerUPP);
+ keyEventHandlerUPP = NULL;
+ }
+#endif
+
+/*
#ifdef FEAT_MBYTE
- set_option_value((char_u *)"termencoding", 0L, (char_u *)"macroman", 0);
+ set_option_value((char_u *)"encoding", 0L, (char_u *)"utf-8", 0);
#endif
+*/
/* TODO: Load bitmap if using TOOLBAR */
return OK;
@@ -3290,11 +3628,21 @@ gui_mch_exit(int rc)
/* TODO: find out all what is missing here? */
DisposeRgn(cursorRgn);
+#ifdef USE_CARBONKEYHANDLER
+ if (keyEventHandlerUPP)
+ DisposeEventHandlerUPP(keyEventHandlerUPP);
+#endif
+
#ifdef USE_MOUSEWHEEL
if (mouseWheelHandlerUPP != NULL)
DisposeEventHandlerUPP(mouseWheelHandlerUPP);
#endif
+#ifdef USE_ATSUI_DRAWING
+ if (gFontStyle)
+ ATSUDisposeStyle(gFontStyle);
+#endif
+
/* Exit to shell? */
exit(rc);
}
@@ -3466,6 +3814,14 @@ gui_mch_init_font(font_name, fontset)
GuiFont font;
char_u used_font_name[512];
+#ifdef USE_ATSUI_DRAWING
+ if (gFontStyle == NULL)
+ {
+ if (ATSUCreateStyle(&gFontStyle) != noErr)
+ gFontStyle = NULL;
+ }
+#endif
+
if (font_name == NULL)
{
/* First try to get the suggested font */
@@ -3523,6 +3879,54 @@ gui_mch_init_font(font_name, fontset)
TextSize(font >> 16);
TextFont(font & 0xFFFF);
+#ifdef USE_ATSUI_DRAWING
+ ATSUFontID fontID;
+ Fixed fontSize;
+ ATSStyleRenderingOptions fontOptions;
+
+ if (gFontStyle)
+ {
+ fontID = font & 0xFFFF;
+ fontSize = Long2Fix(font >> 16);
+
+ /* No antialiasing by default (do not attempt to touch antialising
+ * options on pre-Jaguar) */
+ fontOptions =
+#ifdef MACOS_X
+ (gMacSystemVersion >= 0x1020) ?
+ kATSStyleNoAntiAliasing :
+#endif
+ kATSStyleNoOptions;
+
+ ATSUAttributeTag attribTags[] =
+ {
+ kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag,
+ kATSUMaxATSUITagValue+1
+ };
+ ByteCount attribSizes[] =
+ {
+ sizeof(ATSUFontID), sizeof(Fixed),
+ sizeof(ATSStyleRenderingOptions), sizeof font
+ };
+ ATSUAttributeValuePtr attribValues[] =
+ {
+ &fontID, &fontSize, &fontOptions, &font
+ };
+
+ /* Convert font id to ATSUFontID */
+ if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr)
+ {
+ if (ATSUSetAttributes(gFontStyle,
+ (sizeof attribTags)/sizeof(ATSUAttributeTag),
+ attribTags, attribSizes, attribValues) != noErr)
+ {
+ ATSUDisposeStyle(gFontStyle);
+ gFontStyle = NULL;
+ }
+ }
+ }
+#endif
+
GetFontInfo(&font_info);
gui.char_ascent = font_info.ascent;
@@ -3592,9 +3996,99 @@ gui_mch_get_fontname(font, name)
gui_mch_set_font(font)
GuiFont font;
{
- /*
- * TODO: maybe avoid set again the current font.
- */
+#ifdef USE_ATSUI_DRAWING
+ GuiFont currFont;
+ ByteCount actualFontByteCount;
+ ATSUFontID fontID;
+ Fixed fontSize;
+ ATSStyleRenderingOptions fontOptions;
+
+ if (gFontStyle)
+ {
+ /* Avoid setting same font again */
+ if (ATSUGetAttribute(gFontStyle, kATSUMaxATSUITagValue+1, sizeof font,
+ &currFont, &actualFontByteCount) == noErr &&
+ actualFontByteCount == (sizeof font))
+ {
+ if (currFont == font)
+ return;
+ }
+
+ fontID = font & 0xFFFF;
+ fontSize = Long2Fix(font >> 16);
+ /* Respect p_antialias setting only for wide font.
+ * The reason for doing this at the moment is a bit complicated,
+ * but it's mainly because a) latin (non-wide) aliased fonts
+ * look bad in OS X 10.3.x and below (due to a bug in ATS), and
+ * b) wide multibyte input does not suffer from that problem. */
+ fontOptions =
+#ifdef MACOS_X
+ (p_antialias && (font == gui.wide_font)) ?
+ kATSStyleNoOptions : kATSStyleNoAntiAliasing;
+#else
+ kATSStyleNoOptions;
+#endif
+
+ ATSUAttributeTag attribTags[] =
+ {
+ kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag,
+ kATSUMaxATSUITagValue+1
+ };
+ ByteCount attribSizes[] =
+ {
+ sizeof(ATSUFontID), sizeof(Fixed),
+ sizeof(ATSStyleRenderingOptions), sizeof font
+ };
+ ATSUAttributeValuePtr attribValues[] =
+ {
+ &fontID, &fontSize, &fontOptions, &font
+ };
+
+ if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr)
+ {
+ if (ATSUSetAttributes(gFontStyle,
+ (sizeof attribTags)/sizeof(ATSUAttributeTag),
+ attribTags, attribSizes, attribValues) != noErr)
+ {
+#ifndef NDEBUG
+ fprintf(stderr, "couldn't set font style\n");
+#endif
+ ATSUDisposeStyle(gFontStyle);
+ gFontStyle = NULL;
+ }
+ }
+
+ }
+
+ if (!gIsFontFallbackSet)
+ {
+ /* Setup automatic font substitution. The user's guifontwide
+ * is tried first, then the system tries other fonts. */
+/*
+ ATSUAttributeTag fallbackTags[] = { kATSULineFontFallbacksTag };
+ ByteCount fallbackSizes[] = { sizeof(ATSUFontFallbacks) };
+ ATSUCreateFontFallbacks(&gFontFallbacks);
+ ATSUSetObjFontFallbacks(gFontFallbacks, );
+*/
+ if (gui.wide_font)
+ {
+ ATSUFontID fallbackFonts;
+ gIsFontFallbackSet = TRUE;
+
+ if (FMGetFontFromFontFamilyInstance(
+ (gui.wide_font & 0xFFFF),
+ 0,
+ &fallbackFonts,
+ NULL) == noErr)
+ {
+ ATSUSetFontFallbacks((sizeof fallbackFonts)/sizeof(ATSUFontID), &fallbackFonts, kATSUSequentialFallbacksPreferred);
+ }
+/*
+ ATSUAttributeValuePtr fallbackValues[] = { };
+*/
+ }
+ }
+#endif
TextSize(font >> 16);
TextFont(font & 0xFFFF);
}
@@ -3820,9 +4314,17 @@ gui_mch_draw_string(row, col, s, len, flags)
int flags;
{
#if defined(FEAT_GUI) && defined(MACOS_X)
+#ifndef USE_ATSUI_DRAWING
SInt32 sys_version;
#endif
+#endif
#ifdef FEAT_MBYTE
+#ifdef USE_ATSUI_DRAWING
+ /* ATSUI requires utf-16 strings */
+ UniCharCount utf16_len;
+ UniChar *tofree = mac_enc_to_utf16(s, len, (size_t *)&utf16_len);
+ utf16_len /= sizeof(UniChar);
+#else
char_u *tofree = NULL;
if (output_conv.vc_type != CONV_NONE)
@@ -3832,8 +4334,11 @@ gui_mch_draw_string(row, col, s, len, flags)
s = tofree;
}
#endif
+#endif
#if defined(FEAT_GUI) && defined(MACOS_X)
+ /* ATSUI automatically antialiases text */
+#ifndef USE_ATSUI_DRAWING
/*
* On OS X, try using Quartz-style text antialiasing.
*/
@@ -3845,8 +4350,9 @@ gui_mch_draw_string(row, col, s, len, flags)
/* Quartz antialiasing is available only in OS 10.2 and later. */
UInt32 qd_flags = (p_antialias ?
kQDUseCGTextRendering | kQDUseCGTextMetrics : 0);
- (void)SwapQDTextFlags(qd_flags);
+ QDSwapTextFlags(qd_flags);
}
+#endif
/*
* When antialiasing we're using srcOr mode, we have to clear the block
@@ -3857,18 +4363,37 @@ gui_mch_draw_string(row, col, s, len, flags)
* The following is like calling gui_mch_clear_block(row, col, row, col +
* len - 1), but without setting the bg color to gui.back_pixel.
*/
+#ifdef USE_ATSUI_DRAWING
+ if ((flags & DRAW_TRANSP) == 0)
+#else
if (((sys_version >= 0x1020 && p_antialias) || p_linespace != 0)
&& !(flags & DRAW_TRANSP))
+#endif
{
Rect rc;
rc.left = FILL_X(col);
rc.top = FILL_Y(row);
+#ifdef FEAT_MBYTE
+ /* Multibyte computation taken from gui_w32.c */
+ if (has_mbyte)
+ {
+ int cell_len = 0;
+ int n;
+
+ /* Compute the length in display cells. */
+ for (n = 0; n < len; n += MB_BYTE2LEN(s[n]))
+ cell_len += (*mb_ptr2cells)(s + n);
+ rc.right = FILL_X(col + cell_len);
+ }
+ else
+#endif
rc.right = FILL_X(col + len) + (col + len == Columns);
rc.bottom = FILL_Y(row + 1);
EraseRect(&rc);
}
+#ifndef USE_ATSUI_DRAWING
if (sys_version >= 0x1020 && p_antialias)
{
StyleParameter face;
@@ -3888,6 +4413,7 @@ gui_mch_draw_string(row, col, s, len, flags)
}
else
#endif
+#endif
{
/* Use old-style, non-antialiased QuickDraw text rendering. */
TextMode(srcCopy);
@@ -3901,6 +4427,25 @@ gui_mch_draw_string(row, col, s, len, flags)
}
MoveTo(TEXT_X(col), TEXT_Y(row));
+#ifdef USE_ATSUI_DRAWING
+ ATSUTextLayout textLayout;
+
+ if (ATSUCreateTextLayoutWithTextPtr(tofree,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ utf16_len,
+ (gFontStyle ? 1 : 0), &utf16_len,
+ (gFontStyle ? &gFontStyle : NULL),
+ &textLayout) == noErr)
+ {
+ ATSUSetTransientFontMatching(textLayout, TRUE);
+
+ ATSUDrawText(textLayout,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+
+ ATSUDisposeTextLayout(textLayout);
+ }
+#else
DrawText((char *)s, 0, len);
@@ -3916,6 +4461,7 @@ gui_mch_draw_string(row, col, s, len, flags)
MoveTo(FILL_X(col), FILL_Y(row + 1) - 1);
LineTo(FILL_X(col + len) - 1, FILL_Y(row + 1) - 1);
}
+#endif
}
#ifdef FEAT_MBYTE
@@ -4021,14 +4567,16 @@ gui_mch_draw_hollow_cursor(color)
{
Rect rc;
- gui_mch_set_fg_color(color);
-
/*
* Note: FrameRect() excludes right and bottom of rectangle.
*/
rc.left = FILL_X(gui.col);
rc.top = FILL_Y(gui.row);
rc.right = rc.left + gui.char_width;
+#ifdef FEAT_MBYTE
+ if (mb_lefthalve(gui.row, gui.col))
+ rc.right += gui.char_width;
+#endif
rc.bottom = rc.top + gui.char_height;
gui_mch_set_fg_color(color);
@@ -4060,7 +4608,8 @@ gui_mch_draw_part_cursor(w, h, color)
gui_mch_set_fg_color(color);
- PaintRect(&rc);
+ FrameRect(&rc);
+// PaintRect(&rc);
}
@@ -4346,11 +4895,11 @@ clip_mch_request_selection(cbd)
if (flavor == 0)
{
- error = GetScrapFlavorFlags(scrap, kScrapFlavorTypeText, &scrapFlags);
+ error = GetScrapFlavorFlags(scrap, kScrapFlavorTypeUnicode, &scrapFlags);
if (error != noErr)
return;
- error = GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &scrapSize);
+ error = GetScrapFlavorSize(scrap, kScrapFlavorTypeUnicode, &scrapSize);
if (error != noErr)
return;
}
@@ -4374,7 +4923,7 @@ clip_mch_request_selection(cbd)
HLock(textOfClip);
#ifdef USE_CARBONIZED
error = GetScrapFlavorData(scrap,
- flavor ? VIMSCRAPFLAVOR : kScrapFlavorTypeText,
+ flavor ? VIMSCRAPFLAVOR : kScrapFlavorTypeUnicode,
&scrapSize, *textOfClip);
#else
scrapSize = GetScrap(textOfClip, 'TEXT', &scrapOffset);
@@ -4387,7 +4936,11 @@ clip_mch_request_selection(cbd)
type = (strchr(*textOfClip, '\r') != NULL) ? MLINE : MCHAR;
tempclip = lalloc(scrapSize + 1, TRUE);
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+ mch_memmove(tempclip, *textOfClip + flavor, scrapSize);
+#else
STRNCPY(tempclip, *textOfClip + flavor, scrapSize);
+#endif
tempclip[scrapSize] = 0;
searchCR = (char *)tempclip;
@@ -4400,19 +4953,15 @@ clip_mch_request_selection(cbd)
}
-#ifdef FEAT_MBYTE
- if (input_conv.vc_type != CONV_NONE)
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+ /* Convert from utf-16 (clipboard) */
+ size_t encLen = 0;
+ char_u *to = mac_utf16_to_enc((UniChar *)tempclip, scrapSize, &encLen);
+ if (to)
{
- char_u *to;
- int l = scrapSize;
-
- to = string_convert(&input_conv, tempclip, &l);
- if (to != NULL)
- {
- vim_free(tempclip);
- tempclip = to;
- scrapSize = l;
- }
+ scrapSize = encLen;
+ vim_free(tempclip);
+ tempclip = to;
}
#endif
clip_yank_selection(type, tempclip, scrapSize, cbd);
@@ -4471,19 +5020,14 @@ clip_mch_set_selection(cbd)
type = clip_convert_selection(&str, (long_u *) &scrapSize, cbd);
-#ifdef FEAT_MBYTE
- if (str != NULL && output_conv.vc_type != CONV_NONE)
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+ size_t utf16_len = 0;
+ UniChar *to = mac_enc_to_utf16(str, scrapSize, &utf16_len);
+ if (to)
{
- char_u *to;
- int l = scrapSize;
-
- to = string_convert(&output_conv, str, &l);
- if (to != NULL)
- {
- vim_free(str);
- str = to;
- scrapSize = l;
- }
+ scrapSize = utf16_len;
+ vim_free(str);
+ str = (char_u *)to;
}
#endif
@@ -4504,9 +5048,9 @@ clip_mch_set_selection(cbd)
#ifdef USE_CARBONIZED
**textOfClip = type;
- STRNCPY(*textOfClip + 1, str, scrapSize);
+ mch_memmove(*textOfClip + 1, str, scrapSize);
GetCurrentScrap(&scrap);
- PutScrapFlavor(scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone,
+ PutScrapFlavor(scrap, kScrapFlavorTypeUnicode, kScrapFlavorMaskNone,
scrapSize, *textOfClip + 1);
PutScrapFlavor(scrap, VIMSCRAPFLAVOR, kScrapFlavorMaskNone,
scrapSize + 1, *textOfClip);
@@ -4599,7 +5143,11 @@ gui_mch_add_menu(menu, idx)
*/
static long next_avail_id = 128;
long menu_after_me = 0; /* Default to the end */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFStringRef name;
+#else
char_u *name;
+#endif
short index;
vimmenu_T *parent = menu->parent;
vimmenu_T *brother = menu->next;
@@ -4625,13 +5173,21 @@ gui_mch_add_menu(menu, idx)
menu_after_me = hierMenu;
/* Convert the name */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ name = menu_title_removing_mnemonic(menu);
+#else
name = C2Pascal_save(menu->dname);
+#endif
if (name == NULL)
return;
/* Create the menu unless it's the help menu */
#ifdef USE_HELPMENU
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ if (menu->priority == 9999)
+#else
if (STRNCMP(name, "\4Help", 5) == 0)
+#endif
{
menu->submenu_id = kHMHelpMenuID;
menu->submenu_handle = gui.MacOSHelpMenu;
@@ -4644,7 +5200,12 @@ gui_mch_add_menu(menu, idx)
* OSStatus SetMenuTitle(MenuRef, ConstStr255Param title);
*/
menu->submenu_id = next_avail_id;
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ if (CreateNewMenu(menu->submenu_id, 0, (MenuRef *)&menu->submenu_handle) == noErr)
+ SetMenuTitleWithCFString((MenuRef)menu->submenu_handle, name);
+#else
menu->submenu_handle = NewMenu(menu->submenu_id, name);
+#endif
next_avail_id++;
}
@@ -4676,13 +5237,21 @@ gui_mch_add_menu(menu, idx)
* to avoid special character recognition by InsertMenuItem
*/
InsertMenuItem(parent->submenu_handle, "\p ", idx); /* afterItem */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
+#else
SetMenuItemText(parent->submenu_handle, idx+1, name);
+#endif
SetItemCmd(parent->submenu_handle, idx+1, 0x1B);
SetItemMark(parent->submenu_handle, idx+1, menu->submenu_id);
InsertMenu(menu->submenu_handle, hierMenu);
}
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFRelease(name);
+#else
vim_free(name);
+#endif
#if 0
/* Done by Vim later on */
@@ -4698,7 +5267,11 @@ gui_mch_add_menu_item(menu, idx)
vimmenu_T *menu;
int idx;
{
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFStringRef name;
+#else
char_u *name;
+#endif
vimmenu_T *parent = menu->parent;
int menu_inserted;
@@ -4710,7 +5283,11 @@ gui_mch_add_menu_item(menu, idx)
for older OS call GetMenuItemData (menu, item, isCommandID?, data) */
/* Convert the name */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ name = menu_title_removing_mnemonic(menu);
+#else
name = C2Pascal_save(menu->dname);
+#endif
/* Where are just a menu item, so no handle, no id */
menu->submenu_id = 0;
@@ -4796,15 +5373,23 @@ gui_mch_add_menu_item(menu, idx)
if (!menu_inserted)
InsertMenuItem(parent->submenu_handle, "\p ", idx); /* afterItem */
/* Set the menu item name. */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
+#else
SetMenuItemText(parent->submenu_handle, idx+1, name);
+#endif
#if 0
/* Called by Vim */
DrawMenuBar();
#endif
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFRelease(name);
+#else
/* TODO: Can name be freed? */
vim_free(name);
+#endif
}
void
@@ -5811,17 +6396,33 @@ gui_mch_settitle(title, icon)
/* TODO: Get vim to make sure maxlen (from p_titlelen) is smaller
* that 256. Even better get it to fit nicely in the titlebar.
*/
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ CFStringRef windowTitle;
+ size_t windowTitleLen;
+#else
char_u *pascalTitle;
+#endif
if (title == NULL) /* nothing to do */
return;
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+ windowTitleLen = STRLEN(title);
+ windowTitle = mac_enc_to_cfstring(title, windowTitleLen);
+
+ if (windowTitle)
+ {
+ SetWindowTitleWithCFString(gui.VimWindow, windowTitle);
+ CFRelease(windowTitle);
+ }
+#else
pascalTitle = C2Pascal_save(title);
if (pascalTitle != NULL)
{
SetWTitle(gui.VimWindow, pascalTitle);
vim_free(pascalTitle);
}
+#endif
}
#endif
diff --git a/src/ops.c b/src/ops.c
index 7c426d147..78078c342 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -1105,10 +1105,20 @@ do_execreg(regname, colon, addcr)
int remap;
if (regname == '@') /* repeat previous one */
+ {
+ if (lastc == NUL)
+ {
+ EMSG(_("E748: No previously used register"));
+ return FAIL;
+ }
regname = lastc;
+ }
/* check for valid regname */
if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE))
+ {
+ emsg_invreg(regname);
return FAIL;
+ }
lastc = regname;
#ifdef FEAT_CLIPBOARD
@@ -3597,7 +3607,13 @@ error:
else
curbuf->b_op_end.col = 0;
- if (flags & PUT_CURSEND)
+ if (flags & PUT_CURSLINE)
+ {
+ /* ":put": put cursor on last inserte line */
+ curwin->w_cursor.lnum = lnum;
+ beginline(BL_WHITE | BL_FIX);
+ }
+ else if (flags & PUT_CURSEND)
{
/* put cursor after inserted text */
if (y_type == MLINE)
@@ -3616,7 +3632,7 @@ error:
}
else if (y_type == MLINE)
{
- /* put cursor onfirst non-blank in first inserted line */
+ /* put cursor on first non-blank in first inserted line */
curwin->w_cursor.col = 0;
if (dir == FORWARD)
++curwin->w_cursor.lnum;
@@ -5676,7 +5692,7 @@ write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len)
if (!valid_yank_reg(name, TRUE)) /* check for valid reg name */
{
- EMSG2(_("E354: Invalid register name: '%s'"), transchar(name));
+ emsg_invreg(name);
return;
}
diff --git a/src/option.c b/src/option.c
index 205b21c20..4444b1f89 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1723,8 +1723,8 @@ static struct vimoption
#endif
},
{"prompt", NULL, P_BOOL|P_VI_DEF,
- (char_u *)NULL, PV_NONE,
- {(char_u *)FALSE, (char_u *)0L}},
+ (char_u *)&p_prompt, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L}},
{"quoteescape", "qe", P_STRING|P_ALLOCED|P_VI_DEF,
#ifdef FEAT_TEXTOBJ
(char_u *)&p_qe, PV_QE,
@@ -1922,6 +1922,9 @@ static struct vimoption
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)FALSE, (char_u *)0L}},
+ {"shelltemp", "stmp", P_BOOL,
+ (char_u *)&p_stmp, PV_NONE,
+ {(char_u *)FALSE, (char_u *)TRUE}},
{"shelltype", "st", P_NUM|P_VI_DEF,
#ifdef AMIGA
(char_u *)&p_st, PV_NONE,
@@ -2501,7 +2504,7 @@ static char *(p_bsdir_values[]) = {"current", "last", "buffer", NULL};
static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
#endif
static char *(p_swb_values[]) = {"useopen", "split", NULL};
-static char *(p_debug_values[]) = {"msg", NULL};
+static char *(p_debug_values[]) = {"msg", "beep", NULL};
#ifdef FEAT_VERTSPLIT
static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
#endif
@@ -2593,7 +2596,10 @@ set_init_1()
/* Use POSIX compatibility when $VIM_POSIX is set. */
if (mch_getenv((char_u *)"VIM_POSIX") != NULL)
+ {
set_string_default("cpo", (char_u *)CPO_ALL);
+ set_string_default("shm", (char_u *)"A");
+ }
/*
* Find default value for 'shell' option.
@@ -2885,6 +2891,23 @@ set_init_1()
vim_setenv("LANG", buf);
}
}
+# else
+# ifdef MACOS
+ if (mch_getenv((char_u *)"LANG") == NULL)
+ {
+ char buf[20];
+ if (LocaleRefGetPartString(NULL,
+ kLocaleLanguageMask | kLocaleLanguageVariantMask |
+ kLocaleRegionMask | kLocaleRegionVariantMask,
+ sizeof buf, buf) == noErr && *buf)
+ {
+ vim_setenv("LANG", buf);
+# ifdef HAVE_LOCALE_H
+ setlocale(LC_ALL, "");
+# endif
+ }
+ }
+# endif
# endif
/* enc_locale() will try to find the encoding of the current locale. */
@@ -3093,6 +3116,9 @@ set_init_2()
* wrong when the window height changes.
*/
set_number_default("scroll", (long_u)Rows >> 1);
+ idx = findoption((char_u *)"scroll");
+ if (!(options[idx].flags & P_WAS_SET))
+ set_option_default(idx, OPT_LOCAL, p_cp);
comp_col();
/*
@@ -3423,7 +3449,8 @@ do_set(arg, opt_flags)
if (*arg == NUL)
{
showoptions(0, opt_flags);
- return OK;
+ did_show = TRUE;
+ goto theend;
}
while (*arg != NUL) /* loop to process all options */
@@ -3446,12 +3473,16 @@ do_set(arg, opt_flags)
set_options_default(OPT_FREE | opt_flags);
}
else
+ {
showoptions(1, opt_flags);
+ did_show = TRUE;
+ }
}
else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
{
showoptions(2, opt_flags);
show_termcodes();
+ did_show = TRUE;
arg += 7;
}
else
@@ -4187,6 +4218,19 @@ skip:
arg = skipwhite(arg);
}
+theend:
+ if (silent_mode && did_show)
+ {
+ /* After displaying option values in silent mode. */
+ silent_mode = FALSE;
+ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+ msg_putchar('\n');
+ cursor_on(); /* msg_start() switches it off */
+ out_flush();
+ silent_mode = TRUE;
+ info_message = FALSE; /* use mch_msg(), not mch_errmsg() */
+ }
+
return OK;
}
@@ -7547,7 +7591,11 @@ showoneopt(p, opt_flags)
struct vimoption *p;
int opt_flags; /* OPT_LOCAL or OPT_GLOBAL */
{
- char_u *varp;
+ char_u *varp;
+ int save_silent = silent_mode;
+
+ silent_mode = FALSE;
+ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
varp = get_varp_scope(p, opt_flags);
@@ -7567,6 +7615,9 @@ showoneopt(p, opt_flags)
option_value2string(p, opt_flags);
msg_outtrans(NameBuff);
}
+
+ silent_mode = save_silent;
+ info_message = FALSE;
}
/*
diff --git a/src/option.h b/src/option.h
index 674eb4e5d..cd05f539e 100644
--- a/src/option.h
+++ b/src/option.h
@@ -174,10 +174,13 @@
#define CPO_PARA '{' /* "{" is also a paragraph boundary */
#define CPO_TSIZE '|' /* $LINES and $COLUMNS overrule term size */
#define CPO_PRESERVE '&' /* keep swap file after :preserve */
+#define CPO_SUBPERCENT '/' /* % in :s string uses previous one */
+#define CPO_BACKSL '\\' /* \ is not special in [] */
+#define CPO_CHDIR '.' /* don't chdir if buffer is modified */
/* default values for Vim, Vi and POSIX */
#define CPO_VIM "aABceFs"
#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpqrRsStuvwWxXyZ$!%*-+<>"
-#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpqrRsStuvwWxXyZ$!%*-+<>#{|&"
+#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpqrRsStuvwWxXyZ$!%*-+<>#{|&/\\."
/* characters for p_ww option: */
#define WW_ALL "bshl<>[],~"
@@ -479,6 +482,7 @@ EXTERN char_u *p_pfn; /* 'printfont' */
EXTERN char_u *p_popt; /* 'printoptions' */
EXTERN char_u *p_header; /* 'printheader' */
#endif
+EXTERN int p_prompt; /* 'prompt' */
#ifdef FEAT_GUI
EXTERN char_u *p_guifont; /* 'guifont' */
# ifdef FEAT_XFONTSET
@@ -675,6 +679,7 @@ EXTERN char_u *p_srr; /* 'shellredir' */
#ifdef AMIGA
EXTERN long p_st; /* 'shelltype' */
#endif
+EXTERN int p_stmp; /* 'shelltemp' */
#ifdef BACKSLASH_IN_FILENAME
EXTERN int p_ssl; /* 'shellslash' */
#endif
diff --git a/src/os_mac_conv.c b/src/os_mac_conv.c
index 3f64e3da4..68d46c0f2 100644
--- a/src/os_mac_conv.c
+++ b/src/os_mac_conv.c
@@ -21,6 +21,21 @@ extern char_u *mac_string_convert __ARGS((char_u *ptr, int len, int *lenp, int f
extern int macroman2enc __ARGS((char_u *ptr, long *sizep, long real_size));
extern int enc2macroman __ARGS((char_u *from, size_t fromlen, char_u *to, int *tolenp, int maxtolen, char_u *rest, int *restlenp));
+extern void mac_conv_init __ARGS((void));
+extern void mac_conv_cleanup __ARGS((void));
+extern char_u *mac_utf16_to_enc __ARGS((UniChar *from, size_t fromLen, size_t *actualLen));
+extern UniChar *mac_enc_to_utf16 __ARGS((char_u *from, size_t fromLen, size_t *actualLen));
+extern CFStringRef mac_enc_to_cfstring __ARGS((char_u *from, size_t fromLen));
+extern char_u *mac_precompose_path __ARGS((char_u *decompPath, size_t decompLen, size_t *precompLen));
+
+static char_u *mac_utf16_to_utf8 __ARGS((UniChar *from, size_t fromLen, size_t *actualLen));
+static UniChar *mac_utf8_to_utf16 __ARGS((char_u *from, size_t fromLen, size_t *actualLen));
+
+/* Converter for composing decomposed HFS+ file paths */
+static TECObjectRef gPathConverter;
+/* Converter used by mac_utf16_to_utf8 */
+static TECObjectRef gUTF16ToUTF8Converter;
+
/*
* A Mac version of string_convert_ext() for special cases.
*/
@@ -59,6 +74,8 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
*unconvlenp = 0;
cfstr = CFStringCreateWithBytes(NULL, ptr, len, from, 0);
+ if(cfstr == NULL)
+ fprintf(stderr, "Encoding failed\n");
/* When conversion failed, try excluding bytes from the end, helps when
* there is an incomplete byte sequence. Only do up to 6 bytes to avoid
* looping a long time when there really is something unconvertable. */
@@ -70,6 +87,7 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
}
if (cfstr == NULL)
return NULL;
+
if (to == kCFStringEncodingUTF8)
buflen = len * 6 + 1;
else
@@ -80,6 +98,22 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
CFRelease(cfstr);
return NULL;
}
+
+#if 0
+ CFRange convertRange = CFRangeMake(0, CFStringGetLength(cfstr));
+ /* Determine output buffer size */
+ CFStringGetBytes(cfstr, convertRange, to, NULL, FALSE, NULL, 0, (CFIndex *)&buflen);
+ retval = (buflen > 0) ? alloc(buflen) : NULL;
+ if (retval == NULL) {
+ CFRelease(cfstr);
+ return NULL;
+ }
+
+ if (lenp)
+ *lenp = buflen / sizeof(char_u);
+
+ if (!CFStringGetBytes(cfstr, convertRange, to, NULL, FALSE, retval, buflen, NULL))
+#endif
if (!CFStringGetCString(cfstr, retval, buflen, to))
{
CFRelease(cfstr);
@@ -89,6 +123,7 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
return NULL;
}
+ fprintf(stderr, "Trying char-by-char conversion...\n");
/* conversion failed for the whole string, but maybe it will work
* for each character */
for (d = retval, in = 0, out = 0; in < len && out < buflen - 1;)
@@ -128,6 +163,7 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
CFRelease(cfstr);
if (lenp != NULL)
*lenp = strlen(retval);
+
return retval;
}
@@ -230,4 +266,291 @@ enc2macroman(from, fromlen, to, tolenp, maxtolen, rest, restlenp)
return OK;
}
+/*
+ * Initializes text converters
+ */
+ void
+mac_conv_init()
+{
+ TextEncoding utf8_encoding;
+ TextEncoding utf8_hfsplus_encoding;
+ TextEncoding utf8_canon_encoding;
+ TextEncoding utf16_encoding;
+
+ utf8_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kTextEncodingDefaultVariant, kUnicodeUTF8Format);
+ utf8_hfsplus_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kUnicodeHFSPlusCompVariant, kUnicodeUTF8Format);
+ utf8_canon_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kUnicodeCanonicalCompVariant, kUnicodeUTF8Format);
+ utf16_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kTextEncodingDefaultVariant, kUnicode16BitFormat);
+
+ if (TECCreateConverter(&gPathConverter, utf8_encoding,
+ utf8_hfsplus_encoding) != noErr)
+ gPathConverter = NULL;
+
+ if (TECCreateConverter(&gUTF16ToUTF8Converter, utf16_encoding,
+ utf8_canon_encoding) != noErr)
+ gUTF16ToUTF8Converter = NULL;
+}
+
+/*
+ * Destroys text converters
+ */
+ void
+mac_conv_cleanup()
+{
+ if (gUTF16ToUTF8Converter)
+ {
+ TECDisposeConverter(gUTF16ToUTF8Converter);
+ gUTF16ToUTF8Converter = NULL;
+ }
+
+ if (gPathConverter)
+ {
+ TECDisposeConverter(gPathConverter);
+ gPathConverter = NULL;
+ }
+}
+
+/*
+ * Conversion from UTF-16 UniChars to 'encoding'
+ */
+ char_u *
+mac_utf16_to_enc(from, fromLen, actualLen)
+ UniChar *from;
+ size_t fromLen;
+ size_t *actualLen;
+{
+ /* Following code borrows somewhat from os_mswin.c */
+ vimconv_T conv;
+ size_t utf8_len;
+ char_u *utf8_str;
+ char_u *result = NULL;
+
+ /* Convert to utf-8 first, works better with iconv */
+ utf8_len = 0;
+ utf8_str = mac_utf16_to_utf8(from, fromLen, &utf8_len);
+
+ if (utf8_str)
+ {
+ /* We might be called before we have p_enc set up. */
+ conv.vc_type = CONV_NONE;
+
+ /* If encoding (p_enc) is any unicode, it is actually in utf-8 (vim
+ * internal unicode is always utf-8) so don't convert in such cases */
+
+ if ((enc_canon_props(p_enc) & ENC_UNICODE) == 0)
+ convert_setup(&conv, (char_u *)"utf-8",
+ p_enc? p_enc: (char_u *)"macroman");
+ if (conv.vc_type == CONV_NONE)
+ {
+ /* p_enc is utf-8, so we're done. */
+ result = utf8_str;
+ }
+ else
+ {
+ result = string_convert(&conv, utf8_str, (int *)&utf8_len);
+ vim_free(utf8_str);
+ }
+
+ convert_setup(&conv, NULL, NULL);
+
+ if (actualLen)
+ *actualLen = utf8_len;
+ }
+ else if (actualLen)
+ *actualLen = 0;
+
+ return result;
+}
+
+/*
+ * Conversion from 'encoding' to UTF-16 UniChars
+ */
+ UniChar *
+mac_enc_to_utf16(from, fromLen, actualLen)
+ char_u *from;
+ size_t fromLen;
+ size_t *actualLen;
+{
+ /* Following code borrows somewhat from os_mswin.c */
+ vimconv_T conv;
+ size_t utf8_len;
+ char_u *utf8_str;
+ UniChar *result = NULL;
+ Boolean should_free_utf8 = FALSE;
+
+ do
+ {
+ /* Use MacRoman by default, we might be called before we have p_enc
+ * set up. Convert to utf-8 first, works better with iconv(). Does
+ * nothing if 'encoding' is "utf-8". */
+ conv.vc_type = CONV_NONE;
+ if ((enc_canon_props(p_enc) & ENC_UNICODE) == 0 &&
+ convert_setup(&conv, p_enc ? p_enc : (char_u *)"macroman",
+ (char_u *)"utf-8") == FAIL)
+ break;
+
+ if (conv.vc_type != CONV_NONE)
+ {
+ utf8_len = fromLen;
+ utf8_str = string_convert(&conv, from, (int *)&utf8_len);
+ should_free_utf8 = TRUE;
+ }
+ else
+ {
+ utf8_str = from;
+ utf8_len = fromLen;
+ }
+
+ if (utf8_str == NULL)
+ break;
+
+ convert_setup(&conv, NULL, NULL);
+
+ result = mac_utf8_to_utf16(utf8_str, utf8_len, actualLen);
+
+ if (should_free_utf8)
+ vim_free(utf8_str);
+ return result;
+ }
+ while (0);
+
+ if (actualLen)
+ *actualLen = 0;
+
+ return result;
+}
+
+/*
+ * Converts from UTF-16 UniChars to CFString
+ */
+ CFStringRef
+mac_enc_to_cfstring(from, fromLen)
+ char_u *from;
+ size_t fromLen;
+{
+ UniChar *utf16_str;
+ size_t utf16_len;
+ CFStringRef result = NULL;
+
+ utf16_str = mac_enc_to_utf16(from, fromLen, &utf16_len);
+ if (utf16_str)
+ {
+ result = CFStringCreateWithCharacters(NULL, utf16_str, utf16_len/sizeof(UniChar));
+ vim_free(utf16_str);
+ }
+
+ return result;
+}
+
+/*
+ * Converts a decomposed HFS+ UTF-8 path to precomposed UTF-8
+ */
+ char_u *
+mac_precompose_path(decompPath, decompLen, precompLen)
+ char_u *decompPath;
+ size_t decompLen;
+ size_t *precompLen;
+{
+ char_u *result = NULL;
+ size_t actualLen = 0;
+
+ if (gPathConverter)
+ {
+ result = alloc(decompLen);
+ if (result)
+ {
+ if (TECConvertText(gPathConverter, decompPath,
+ decompLen, &decompLen, result,
+ decompLen, &actualLen) != noErr)
+ {
+ vim_free(result);
+ result = NULL;
+ }
+ }
+ }
+
+ if (precompLen)
+ *precompLen = actualLen;
+
+ return result;
+}
+
+/*
+ * Converts from UTF-16 UniChars to precomposed UTF-8
+ */
+ char_u *
+mac_utf16_to_utf8(from, fromLen, actualLen)
+ UniChar *from;
+ size_t fromLen;
+ size_t *actualLen;
+{
+ ByteCount utf8_len;
+ ByteCount inputRead;
+ char_u *result;
+
+ if (gUTF16ToUTF8Converter)
+ {
+ result = alloc(fromLen * 6 + 1);
+ if (result && TECConvertText(gUTF16ToUTF8Converter, (ConstTextPtr)from,
+ fromLen, &inputRead, result,
+ (fromLen*6+1)*sizeof(char_u), &utf8_len) == noErr)
+ {
+ TECFlushText(gUTF16ToUTF8Converter, result, (fromLen*6+1)*sizeof(char_u), &inputRead);
+ utf8_len += inputRead;
+ }
+ else
+ {
+ vim_free(result);
+ result = NULL;
+ }
+ }
+ else
+ {
+ result = NULL;
+ }
+
+ if (actualLen)
+ *actualLen = result ? utf8_len : 0;
+
+ return result;
+}
+
+/*
+ * Converts from UTF-8 to UTF-16 UniChars
+ */
+ UniChar *
+mac_utf8_to_utf16(from, fromLen, actualLen)
+ char_u *from;
+ size_t fromLen;
+ size_t *actualLen;
+{
+ CFStringRef utf8_str;
+ CFRange convertRange;
+ UniChar *result = NULL;
+
+ utf8_str = CFStringCreateWithBytes(NULL, from, fromLen,
+ kCFStringEncodingUTF8, FALSE);
+
+ if (utf8_str == NULL) {
+ if (actualLen)
+ *actualLen = 0;
+ return NULL;
+ }
+
+ convertRange = CFRangeMake(0, CFStringGetLength(utf8_str));
+ result = (UniChar *)alloc(convertRange.length * sizeof(UniChar));
+
+ CFStringGetCharacters(utf8_str, convertRange, result);
+
+ CFRelease(utf8_str);
+
+ if (actualLen)
+ *actualLen = convertRange.length * sizeof(UniChar);
+
+ return result;
+}
#endif /* FEAT_MBYTE */
diff --git a/src/po/Make_mvc.mak b/src/po/Make_mvc.mak
index b69b5abc5..c902614ac 100644
--- a/src/po/Make_mvc.mak
+++ b/src/po/Make_mvc.mak
@@ -6,9 +6,9 @@
# Please read README_mvc.txt before using this file.
#
-LANGUAGES = af ca cs de en_GB es fr it ja ko no pl ru sk sv uk zh_TW \
+LANGUAGES = af ca cs de en_GB es fr ga it ja ko no pl ru sk sv uk zh_TW \
zh_TW.UTF-8 zh_CN zh_CN.UTF-8
-MOFILES = af.mo ca.mo cs.mo de.mo en_GB.mo es.mo fr.mo it.mo ja.mo \
+MOFILES = af.mo ca.mo cs.mo de.mo en_GB.mo es.mo fr.mo ga.mo it.mo ja.mo \
ko.mo no.mo pl.mo ru.mo sk.mo sv.mo uk.mo \
zh_TW.mo zh_TW.UTF-8.mo zh_CN.mo zh_CN.UTF-8.mo
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index d85ab2ef0..b43003967 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -6,6 +6,9 @@ int *func_dbg_tick __ARGS((void *cookie));
int func_level __ARGS((void *cookie));
int current_func_returned __ARGS((void));
void set_internal_string_var __ARGS((char_u *name, char_u *value));
+int var_redir_start __ARGS((char_u *name, int append));
+void var_redir_str __ARGS((char_u *value, int len));
+void var_redir_stop __ARGS((void));
int eval_charconvert __ARGS((char_u *enc_from, char_u *enc_to, char_u *fname_from, char_u *fname_to));
int eval_printexpr __ARGS((char_u *fname, char_u *args));
void eval_diff __ARGS((char_u *origfile, char_u *newfile, char_u *outfile));
diff --git a/src/screen.c b/src/screen.c
index 6271b84c7..d3c9552e1 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -6847,18 +6847,6 @@ screen_start()
}
/*
- * Note that the cursor has gone down to the next line, column 0.
- * Used for Ex mode.
- */
- void
-screen_down()
-{
- screen_cur_col = 0;
- if (screen_cur_row < Rows - 1)
- ++screen_cur_row;
-}
-
-/*
* Move the cursor to position "row","col" in the screen.
* This tries to find the most efficient way to move, minimizing the number of
* characters sent to the terminal.
diff --git a/src/search.c b/src/search.c
index 8520282a9..c9773b587 100644
--- a/src/search.c
+++ b/src/search.c
@@ -4715,7 +4715,7 @@ show_pat_in_path(line, type, did_show, action, fp, lnum, count)
msg_puts_attr(IObuff, hl_attr(HLF_N));
MSG_PUTS(" ");
}
- msg_prt_line(line);
+ msg_prt_line(line, FALSE);
out_flush(); /* show one line at a time */
/* Definition continues until line that doesn't end with '\' */
diff --git a/src/structs.h b/src/structs.h
index 92a8428f1..71c692ad1 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -307,7 +307,8 @@ struct m_block
{
mblock_T *mb_next; /* pointer to next allocated block */
size_t mb_size; /* total size of all chunks in this block */
- minfo_T mb_info; /* head of free chuck list for this block */
+ size_t mb_maxsize; /* size of largest fee chunk */
+ minfo_T mb_info; /* head of free chunk list for this block */
};
/*
@@ -1211,6 +1212,7 @@ struct file_buffer
minfo_T *b_m_search; /* pointer to chunk before previously
allocated/freed chunk */
mblock_T *b_mb_current; /* block where m_search points in */
+
#ifdef FEAT_INS_EXPAND
int b_scanned; /* ^N/^P have scanned this buffer */
#endif
diff --git a/src/syntax.c b/src/syntax.c
index bf9360f47..5d08afac0 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -4397,8 +4397,19 @@ syn_cmd_keyword(eap, syncing)
add_keyword(kw, syn_id, syn_opt_arg.flags,
syn_opt_arg.cont_in_list,
syn_opt_arg.next_list);
- if (p == NULL || p[1] == NUL || p[1] == ']')
+ if (p == NULL)
break;
+ if (p[1] == NUL)
+ {
+ EMSG2(_("E747: Missing ']': %s"), kw);
+ kw = p + 2; /* skip over the NUL */
+ break;
+ }
+ if (p[1] == ']')
+ {
+ kw = p + 1; /* skip over the "]" */
+ break;
+ }
#ifdef FEAT_MBYTE
if (has_mbyte)
{
@@ -4418,6 +4429,8 @@ syn_cmd_keyword(eap, syncing)
}
vim_free(keyword_copy);
+ vim_free(syn_opt_arg.cont_in_list);
+ vim_free(syn_opt_arg.next_list);
}
}
@@ -4426,8 +4439,6 @@ syn_cmd_keyword(eap, syncing)
else
EMSG2(_(e_invarg2), arg);
- vim_free(syn_opt_arg.cont_in_list);
- vim_free(syn_opt_arg.next_list);
redraw_curbuf_later(NOT_VALID);
syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
}
diff --git a/src/term.c b/src/term.c
index 386b05cf5..12c506ab2 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1590,6 +1590,10 @@ set_termname(term)
char_u *error_msg = NULL;
char_u *bs_p, *del_p;
+ /* In silect mode (ex -s) we don't use the 'term' option. */
+ if (silent_mode)
+ return OK;
+
detected_8bit = FALSE; /* reset 8-bit detection */
if (term_is_builtin(term))
@@ -3146,10 +3150,6 @@ settmode(tmode)
if (full_screen)
{
- /* In Ex mode, never set to RAW */
- if (exmode_active == EXMODE_NORMAL)
- tmode = TMODE_COOK;
-
/*
* When returning after calling a shell we want to really set the
* terminal to raw mode, even though we think it already is, because
diff --git a/src/undo.c b/src/undo.c
index bdba903d8..4675d9972 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -41,24 +41,33 @@
* curbuf->b_u_curhead points to the header of the last undo (the next redo),
* or is NULL if nothing has been undone.
*
- * All data is allocated with u_alloc_line(), thus it will be freed as soon as
- * we switch files!
+ * All data is allocated with U_ALLOC_LINE(), it will be freed as soon as the
+ * buffer is unloaded.
*/
#include "vim.h"
+/* See below: use malloc()/free() for memory management. */
+#define U_USE_MALLOC 1
+
static u_entry_T *u_get_headentry __ARGS((void));
static void u_getbot __ARGS((void));
static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
static void u_doit __ARGS((int count));
static void u_undoredo __ARGS((void));
static void u_undo_end __ARGS((void));
-static void u_freelist __ARGS((struct u_header *));
+static void u_freelist __ARGS((buf_T *buf, struct u_header *));
static void u_freeentry __ARGS((u_entry_T *, long));
-static char_u *u_blockalloc __ARGS((long_u));
-static void u_free_line __ARGS((char_u *, int keep));
-static char_u *u_alloc_line __ARGS((unsigned));
+#ifdef U_USE_MALLOC
+# define U_FREE_LINE(ptr) vim_free(ptr)
+# define U_ALLOC_LINE(size) lalloc((long_u)((size) + 1), FALSE)
+#else
+static void u_free_line __ARGS((char_u *ptr, int keep));
+static char_u *u_alloc_line __ARGS((unsigned size));
+# define U_FREE_LINE(ptr) u_free_line((ptr), FALSE)
+# define U_ALLOC_LINE(size) u_alloc_line(size)
+#endif
static char_u *u_save_line __ARGS((linenr_T));
static long u_newcount, u_oldcount;
@@ -227,13 +236,13 @@ u_savecommon(top, bot, newbot)
* including curbuf->b_u_curhead
*/
while (curbuf->b_u_curhead != NULL)
- u_freelist(curbuf->b_u_newhead);
+ u_freelist(curbuf, curbuf->b_u_newhead);
/*
* free headers to keep the size right
*/
while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
- u_freelist(curbuf->b_u_oldhead);
+ u_freelist(curbuf, curbuf->b_u_oldhead);
if (p_ul < 0) /* no undo at all */
{
@@ -244,7 +253,7 @@ u_savecommon(top, bot, newbot)
/*
* make a new header entry
*/
- uhp = (struct u_header *)u_alloc_line((unsigned)
+ uhp = (struct u_header *)U_ALLOC_LINE((unsigned)
sizeof(struct u_header));
if (uhp == NULL)
goto nomem;
@@ -364,7 +373,7 @@ u_savecommon(top, bot, newbot)
/*
* add lines in front of entry list
*/
- uep = (u_entry_T *)u_alloc_line((unsigned)sizeof(u_entry_T));
+ uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
if (uep == NULL)
goto nomem;
@@ -384,9 +393,9 @@ u_savecommon(top, bot, newbot)
curbuf->b_u_newhead->uh_getbot_entry = uep;
}
- if (size)
+ if (size > 0)
{
- if ((uep->ue_array = (char_u **)u_alloc_line(
+ if ((uep->ue_array = (char_u **)U_ALLOC_LINE(
(unsigned)(sizeof(char_u *) * size))) == NULL)
{
u_freeentry(uep, 0L);
@@ -609,9 +618,9 @@ u_undoredo()
empty_buffer = FALSE;
/* delete the lines between top and bot and save them in newarray */
- if (oldsize)
+ if (oldsize > 0)
{
- if ((newarray = (char_u **)u_alloc_line(
+ if ((newarray = (char_u **)U_ALLOC_LINE(
(unsigned)(sizeof(char_u *) * oldsize))) == NULL)
{
do_outofmem_msg((long_u)(sizeof(char_u *) * oldsize));
@@ -654,9 +663,9 @@ u_undoredo()
ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
else
ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
- u_free_line(uep->ue_array[i], FALSE);
+ U_FREE_LINE(uep->ue_array[i]);
}
- u_free_line((char_u *)uep->ue_array, FALSE);
+ U_FREE_LINE((char_u *)uep->ue_array);
}
/* adjust marks */
@@ -870,7 +879,8 @@ u_getbot()
* u_freelist: free one entry list and adjust the pointers
*/
static void
-u_freelist(uhp)
+u_freelist(buf, uhp)
+ buf_T *buf;
struct u_header *uhp;
{
u_entry_T *uep, *nuep;
@@ -881,21 +891,21 @@ u_freelist(uhp)
u_freeentry(uep, uep->ue_size);
}
- if (curbuf->b_u_curhead == uhp)
- curbuf->b_u_curhead = NULL;
+ if (buf->b_u_curhead == uhp)
+ buf->b_u_curhead = NULL;
if (uhp->uh_next == NULL)
- curbuf->b_u_oldhead = uhp->uh_prev;
+ buf->b_u_oldhead = uhp->uh_prev;
else
uhp->uh_next->uh_prev = uhp->uh_prev;
if (uhp->uh_prev == NULL)
- curbuf->b_u_newhead = uhp->uh_next;
+ buf->b_u_newhead = uhp->uh_next;
else
uhp->uh_prev->uh_next = uhp->uh_next;
- u_free_line((char_u *)uhp, FALSE);
- --curbuf->b_u_numhead;
+ U_FREE_LINE((char_u *)uhp);
+ --buf->b_u_numhead;
}
/*
@@ -907,8 +917,8 @@ u_freeentry(uep, n)
long n;
{
while (n)
- u_free_line(uep->ue_array[--n], FALSE);
- u_free_line((char_u *)uep, FALSE);
+ U_FREE_LINE(uep->ue_array[--n]);
+ U_FREE_LINE((char_u *)uep);
}
/*
@@ -955,7 +965,7 @@ u_clearline()
{
if (curbuf->b_u_line_ptr != NULL)
{
- u_free_line(curbuf->b_u_line_ptr, FALSE);
+ U_FREE_LINE(curbuf->b_u_line_ptr);
curbuf->b_u_line_ptr = NULL;
curbuf->b_u_line_lnum = 0;
}
@@ -993,7 +1003,7 @@ u_undoline()
}
ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
changed_bytes(curbuf->b_u_line_lnum, 0);
- u_free_line(curbuf->b_u_line_ptr, FALSE);
+ U_FREE_LINE(curbuf->b_u_line_ptr);
curbuf->b_u_line_ptr = oldp;
t = curbuf->b_u_line_colnr;
@@ -1004,7 +1014,40 @@ u_undoline()
}
/*
- * storage allocation for the undo lines and blocks of the current file
+ * There are two implementations of the memory management for undo:
+ * 1. Use the standard malloc()/free() functions.
+ * This should be fast for allocating memory, but when a buffer is
+ * abandoned every single allocated chunk must be freed, which may be slow.
+ * 2. Allocate larger blocks of memory and keep track of chunks ourselves.
+ * This is fast for abandoning, but the use of linked lists is slow for
+ * finding a free chunk. Esp. when a lot of lines are changed or deleted.
+ * A bit of profiling showed that the first method is faster, especially when
+ * making a large number of changes, under the condition that malloc()/free()
+ * is implemented efficiently.
+ */
+#ifdef U_USE_MALLOC
+/*
+ * Version of undo memory allocation using malloc()/free()
+ *
+ * U_FREE_LINE() and U_ALLOC_LINE() are macros that invoke vim_free() and
+ * lalloc() directly.
+ */
+
+/*
+ * Free all allocated memory blocks for the buffer 'buf'.
+ */
+ void
+u_blockfree(buf)
+ buf_T *buf;
+{
+ while (buf->b_u_newhead != NULL)
+ u_freelist(buf, buf->b_u_newhead);
+}
+
+#else
+/*
+ * Storage allocation for the undo lines and blocks of the current file.
+ * Version where Vim keeps track of the available memory.
*/
/*
@@ -1071,6 +1114,8 @@ u_undoline()
# define M_OFFSET (sizeof(short_u))
#endif
+static char_u *u_blockalloc __ARGS((long_u));
+
/*
* Allocate a block of memory and link it in the allocated block list.
*/
@@ -1092,6 +1137,7 @@ u_blockalloc(size)
;
p->mb_next = next; /* link in block list */
p->mb_size = size;
+ p->mb_maxsize = 0; /* nothing free yet */
mp->mb_next = p;
p->mb_info.m_next = NULL; /* clear free list */
p->mb_info.m_size = 0;
@@ -1135,6 +1181,7 @@ u_free_line(ptr, keep)
minfo_T *mp;
mblock_T *nextb;
mblock_T *prevb;
+ long_u maxsize;
if (ptr == NULL || ptr == IObuff)
return; /* illegal address can happen in out-of-memory situations */
@@ -1212,11 +1259,13 @@ u_free_line(ptr, keep)
}
else
mp->m_next = next;
+ maxsize = mp->m_size;
/* if *curr and *mp are concatenated, join them */
if (prev != NULL && (char_u *)curr + curr->m_size == (char_u *)mp)
{
curr->m_size += mp->m_size;
+ maxsize = curr->m_size;
curr->m_next = mp->m_next;
curbuf->b_m_search = prev;
}
@@ -1244,6 +1293,8 @@ u_free_line(ptr, keep)
curbuf->b_mb_current = NULL;
curbuf->b_m_search = NULL;
}
+ else if (curbuf->b_mb_current->mb_maxsize < maxsize)
+ curbuf->b_mb_current->mb_maxsize = maxsize;
}
/*
@@ -1282,48 +1333,56 @@ u_alloc_line(size)
curbuf->b_m_search = &(curbuf->b_block_head.mb_info);
}
- /* search for space in free list */
- mprev = curbuf->b_m_search;
+ /* Search for a block with enough space. */
mbp = curbuf->b_mb_current;
- mp = curbuf->b_m_search->m_next;
- if (mp == NULL)
+ while (mbp->mb_maxsize < size_align)
{
- if (mbp->mb_next)
+ if (mbp->mb_next != NULL)
mbp = mbp->mb_next;
else
mbp = &curbuf->b_block_head;
- mp = curbuf->b_m_search = &(mbp->mb_info);
+ if (mbp == curbuf->b_mb_current)
+ {
+ int n = (size_align > (MEMBLOCKSIZE / 4)
+ ? size_align : MEMBLOCKSIZE);
+
+ /* Back where we started in block list: need to add a new block
+ * with enough space. */
+ mp = (minfo_T *)u_blockalloc((long_u)n);
+ if (mp == NULL)
+ return (NULL);
+ mp->m_size = n;
+ u_free_line((char_u *)mp + M_OFFSET, TRUE);
+ mbp = curbuf->b_mb_current;
+ break;
+ }
}
- while (mp->m_size < size)
+ if (mbp != curbuf->b_mb_current)
+ curbuf->b_m_search = &(mbp->mb_info);
+
+ /* In this block find a chunk with enough space. */
+ mprev = curbuf->b_m_search;
+ mp = curbuf->b_m_search->m_next;
+ while (1)
{
- if (mp == curbuf->b_m_search) /* back where we started in free
- chunk list */
+ if (mp == NULL) /* at end of the list */
+ mp = &(mbp->mb_info); /* wrap around to begin */
+ if (mp->m_size >= size)
+ break;
+ if (mp == curbuf->b_m_search)
{
- if (mbp->mb_next)
- mbp = mbp->mb_next;
- else
- mbp = &curbuf->b_block_head;
- mp = curbuf->b_m_search = &(mbp->mb_info);
- if (mbp == curbuf->b_mb_current) /* back where we started in
- block list */
- {
- int n = (size_align > (MEMBLOCKSIZE / 4)
- ? size_align : MEMBLOCKSIZE);
-
- mp = (minfo_T *)u_blockalloc((long_u)n);
- if (mp == NULL)
- return (NULL);
- mp->m_size = n;
- u_free_line((char_u *)mp + M_OFFSET, TRUE);
- mp = curbuf->b_m_search;
- mbp = curbuf->b_mb_current;
- }
+ /* back where we started in free chunk list: "cannot happen" */
+ EMSG2(_(e_intern2), "u_alloc_line()");
+ return NULL;
}
mprev = mp;
- if ((mp = mp->m_next) == NULL) /* at end of the list */
- mp = &(mbp->mb_info); /* wrap around to begin */
+ mp = mp->m_next;
}
+ /* when using the largest chunk adjust mb_maxsize */
+ if (mp->m_size >= mbp->mb_maxsize)
+ mbp->mb_maxsize = 0;
+
/* if the chunk we found is large enough, split it up in two */
if ((long)mp->m_size - size_align >= (long)(sizeof(minfo_T) + 1))
{
@@ -1340,11 +1399,18 @@ u_alloc_line(size)
curbuf->b_m_search = mprev;
curbuf->b_mb_current = mbp;
+ /* If using the largest chunk need to find the new largest chunk */
+ if (mbp->mb_maxsize == 0)
+ for (mp2 = &(mbp->mb_info); mp2 != NULL; mp2 = mp2->m_next)
+ if (mbp->mb_maxsize < mp2->m_size)
+ mbp->mb_maxsize = mp2->m_size;
+
mp = (minfo_T *)((char_u *)mp + M_OFFSET);
*(char_u *)mp = NUL; /* set the first byte to NUL */
return ((char_u *)mp);
}
+#endif
/*
* u_save_line(): allocate memory with u_alloc_line() and copy line 'lnum'
@@ -1360,7 +1426,7 @@ u_save_line(lnum)
src = ml_get(lnum);
len = (unsigned)STRLEN(src);
- if ((dst = u_alloc_line(len)) != NULL)
+ if ((dst = U_ALLOC_LINE(len)) != NULL)
mch_memmove(dst, src, (size_t)(len + 1));
return (dst);
}
diff --git a/src/version.h b/src/version.h
index 1925a60e6..f73c68e4f 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
#define VIM_VERSION_NODOT "vim70aa"
#define VIM_VERSION_SHORT "7.0aa"
#define VIM_VERSION_MEDIUM "7.0aa ALPHA"
-#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 12)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 12, compiled "
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 21)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 21, compiled "