Compare commits

...

21 Commits

Author SHA1 Message Date
Bram Moolenaar
d18cfb7dbf patch 7.4.1684
Problem:    README text is slightly outdated.
Solution:   Mention the READMEdir directory.
2016-03-29 22:29:18 +02:00
Bram Moolenaar
e609ad557c patch 7.4.1683
Problem:    Generated .bat files do not support --nofork.
Solution:   Add check for --nofork.  Also add "setlocal". (Kevin Cantú,
            closes #659)
2016-03-28 23:05:48 +02:00
Bram Moolenaar
72188e9aae patch 7.4.1682
Problem:    Coverity: no check for NULL.
Solution:   Add check for invalid argument to assert_match().
2016-03-28 22:48:29 +02:00
Bram Moolenaar
ef9d9b94a8 patch 7.4.1681
Problem:    Coverity warns for fixed size buffer length (false positive).
Solution:   Add a check for the name length.
2016-03-28 22:44:50 +02:00
Bram Moolenaar
925ccfde79 patch 7.4.1680
Problem:    Coverity warns for not checking name length (false positive).
Solution:   Only copy the characters we know are there.
2016-03-28 22:38:02 +02:00
Bram Moolenaar
7d2a5796d3 patch 7.4.1679
Problem:    Coverity: copying value of v_lock without initializing it.
Solution:   Init v_lock in rettv_list_alloc() and rettv_dict_alloc().
2016-03-28 22:30:50 +02:00
Bram Moolenaar
8b29aba019 patch 7.4.1678
Problem:    Warning for unused argument.
Solution:   Add UNUSED. (Dominique Pelle)
2016-03-28 22:17:16 +02:00
Bram Moolenaar
0b9e4d1224 patch 7.4.1677
Problem:    A reference to the removed file_select plugin remains.
Solution:   Remove it.
2016-03-28 22:05:47 +02:00
Bram Moolenaar
fead3ac9a3 patch 7.4.1676
Problem:    The shellmenu plugin has to be copied or sourced to be used.
Solution:   Turn it into a package.
2016-03-28 21:26:47 +02:00
Bram Moolenaar
e101204906 patch 7.4.1675
Problem:    The swapmous plugin has to be copied or sourced to be used.
Solution:   Turn it into the swapmouse package.
2016-03-28 21:10:49 +02:00
Bram Moolenaar
cf2d8dee51 patch 7.4.1674
Problem:    The editexisting plugin has to be copied or sourced to be used.
Solution:   Turn it into a package.
2016-03-28 21:04:37 +02:00
Bram Moolenaar
2946d0236d patch 7.4.1673
Problem:    The justify plugin has to be copied or sourced to be used.
Solution:   Turn it into a package.
2016-03-28 20:53:08 +02:00
Bram Moolenaar
e934e8f5c1 patch 7.4.1672
Problem:    The Dvorak support is a bit difficult to install.
Solution:   Turn it into an optional package.
2016-03-28 20:40:32 +02:00
Bram Moolenaar
61264d9969 patch 7.4.1671
Problem:    When help exists in multiple languages, adding @ab while "ab" is
            the default help language is unnecessary.
Solution:   Leave out "@ab" when not needed. (Ken Takata)
2016-03-28 19:59:02 +02:00
Bram Moolenaar
a32095fc8f patch 7.4.1670
Problem:    Completion doesn't work well for a variable containing "#".
Solution:   Recognize the "#". (Watiko)
2016-03-28 19:27:13 +02:00
Bram Moolenaar
8b877ac38e patch 7.4.1669
Problem:    When writing buffer lines to a pipe Vim may block.
Solution:   Avoid blocking, write more lines later.
2016-03-28 19:16:20 +02:00
Bram Moolenaar
ee1f7b3cb7 patch 7.4.1668
Problem:    channel_get_all() does multiple allocations.
Solution:   Compute the size and allocate once.
2016-03-28 14:42:14 +02:00
Bram Moolenaar
84e1d2b21a patch 7.4.1667
Problem:    Win32: waiting on a pipe with fixed sleep time.
Solution:   Start with a short delay and increase it when looping.
2016-03-28 14:20:41 +02:00
Bram Moolenaar
46c00a6565 patch 7.4.1666
Problem:    When reading JSON from a channel all readahead is used.
Solution:   Use the fill function to reduce overhead.
2016-03-28 14:11:42 +02:00
Bram Moolenaar
8038568722 patch 7.4.1665
Problem:    Crash when calling job_start() with a NULL string. (Dominique)
Solution:   Check for an invalid argument.
2016-03-27 19:13:35 +02:00
Bram Moolenaar
89c64d557d patch 7.4.1664
Problem:    Crash in :cgetexpr.
Solution:   Check for NULL pointer. (Dominique) Add a test.
2016-03-27 18:44:40 +02:00
31 changed files with 1322 additions and 873 deletions

View File

@@ -483,7 +483,6 @@ RT_ALL = \
runtime/ftoff.vim \
runtime/gvimrc_example.vim \
runtime/macros/README.txt \
runtime/macros/dvorak \
runtime/macros/editexisting.vim \
runtime/macros/hanoi/click.me \
runtime/macros/hanoi/hanoi.vim \
@@ -524,9 +523,16 @@ RT_ALL = \
runtime/tutor/tutor \
runtime/tutor/tutor.vim \
runtime/vimrc_example.vim \
runtime/pack/dist/opt/dvorak/plugin/dvorak.vim \
runtime/pack/dist/opt/dvorak/dvorak/enable.vim \
runtime/pack/dist/opt/dvorak/dvorak/disable.vim \
runtime/pack/dist/opt/editexisting/plugin/editexisting.vim \
runtime/pack/dist/opt/justify/plugin/justify.vim \
runtime/pack/dist/opt/matchit/plugin/matchit.vim \
runtime/pack/dist/opt/matchit/doc/matchit.txt \
runtime/pack/dist/opt/matchit/doc/tags \
runtime/pack/dist/opt/shellmenu/plugin/shellmenu.vim \
runtime/pack/dist/opt/swapmouse/plugin/swapmouse.vim \
# runtime files for all distributions without CR-NL translation
RT_ALL_BIN = \

View File

@@ -7,21 +7,23 @@
## What is Vim? ##
Vim is an almost compatible version of the UNIX editor Vi. Many new features
have been added: multi-level undo, syntax highlighting, command line history,
on-line help, spell checking, filename completion, block operations, etc.
There is also a Graphical User Interface (GUI) available. See
`runtime/doc/vi_diff.txt` for differences with Vi.
Vim is a greatly improved version of the good old UNIX editor Vi. Many new
features have been added: multi-level undo, syntax highlighting, command line
history, on-line help, spell checking, filename completion, block operations,
script language, etc. There is also a Graphical User Interface (GUI)
available. Still, Vi compatibility is maintained, those who have Vi "in the
fingers" will feel at home. See `runtime/doc/vi_diff.txt` for differences with
Vi.
This editor is very useful for editing programs and other plain text files.
All commands are given with normal keyboard characters, so those who can type
with ten fingers can work very fast. Additionally, function keys can be
defined by the user, and the mouse can be used.
mapped to commands by the user, and the mouse can be used.
Vim runs under MS-DOS, MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh,
VMS and almost all flavours of UNIX. Porting to other systems should not be
very difficult. Older versions of Vim run on MS-Windows 95/98/Me, Amiga DOS,
Atari MiNT, BeOS, RISC OS and OS/2. These are no longer maintained.
Vim runs under MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh, VMS and
almost all flavours of UNIX. Porting to other systems should not be very
difficult. Older versions of Vim run on MS-DOS, MS-Windows 95/98/Me, Amiga
DOS, Atari MiNT, BeOS, RISC OS and OS/2. These are no longer maintained.
## Distribution ##
@@ -39,9 +41,31 @@ want or must compile it yourself. Check http://www.vim.org/download.php for
an overview of currently available distributions.
## Compiling ##
If you obtained a binary distribution you don't need to compile Vim. If you
obtained a source distribution, all the stuff for compiling Vim is in the
`src` directory. See `src/INSTALL` for instructions.
## Installation ##
See one of these files for system-specific instructions. Either in the
READMEdir directory (in the repository) or the top directory (if you unpack an
archive):
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
There are other `README_*.txt` files, depending on the distribution you used.
## Documentation ##
The vim tutor is a one hour training course for beginners. Mostly it can be
The Vim tutor is a one hour training course for beginners. Often it can be
started as `vimtutor`. See `:help tutor` for more information.
The best is to use `:help` in Vim. If you don't have an executable yet, read
@@ -77,26 +101,6 @@ For the most recent information about sponsoring look on the Vim web site:
http://www.vim.org/sponsor/
## Compiling ##
If you obtained a binary distribution you don't need to compile Vim. If you
obtained a source distribution, all the stuff for compiling Vim is in the
`src` directory. See `src/INSTALL` for instructions.
## Installation ##
See one of these files for system-specific instructions:
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
There are more `README_*.txt` files, depending on the distribution you used.
## Contributing ##
If you would like to help making Vim better, see the [CONTRIBUTING.md](https://github.com/vim/vim/blob/master/CONTRIBUTING.md) file.

View File

@@ -3,21 +3,23 @@ README.txt for version 7.4 of Vim: Vi IMproved.
WHAT IS VIM?
Vim is an almost compatible version of the UNIX editor Vi. Many new features
have been added: multi-level undo, syntax highlighting, command line history,
on-line help, spell checking, filename completion, block operations, etc.
There is also a Graphical User Interface (GUI) available. See
"runtime/doc/vi_diff.txt" for differences with Vi.
Vim is a greatly improved version of the good old UNIX editor Vi. Many new
features have been added: multi-level undo, syntax highlighting, command line
history, on-line help, spell checking, filename completion, block operations,
script language, etc. There is also a Graphical User Interface (GUI)
available. Still, Vi compatibility is maintained, those who have Vi "in the
fingers" will feel at home. See "runtime/doc/vi_diff.txt" for differences with
Vi.
This editor is very useful for editing programs and other plain text files.
All commands are given with normal keyboard characters, so those who can type
with ten fingers can work very fast. Additionally, function keys can be
defined by the user, and the mouse can be used.
mapped to commands by the user, and the mouse can be used.
Vim runs under MS-DOS, MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh,
VMS and almost all flavours of UNIX. Porting to other systems should not be
very difficult. Older versions of Vim run on MS-Windows 95/98/Me, Amiga DOS,
Atari MiNT, BeOS, RISC OS and OS/2. These are no longer maintained.
Vim runs under MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh, VMS and
almost all flavours of UNIX. Porting to other systems should not be very
difficult. Older versions of Vim run on MS-DOS, MS-Windows 95/98/Me, Amiga
DOS, Atari MiNT, BeOS, RISC OS and OS/2. These are no longer maintained.
DISTRIBUTION
@@ -35,9 +37,31 @@ want or must compile it yourself. Check "http://www.vim.org/download.php" for
an overview of currently available distributions.
COMPILING
If you obtained a binary distribution you don't need to compile Vim. If you
obtained a source distribution, all the stuff for compiling Vim is in the
"src" directory. See src/INSTALL for instructions.
INSTALLATION
See one of these files for system-specific instructions. Either in the
READMEdir directory (in the repository) or the top directory (if you unpack an
archive):
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
There are more README_*.txt files, depending on the distribution you used.
DOCUMENTATION
The vim tutor is a one hour training course for beginners. Mostly it can be
The Vim tutor is a one hour training course for beginners. Often it can be
started as "vimtutor". See ":help tutor" for more information.
The best is to use ":help" in Vim. If you don't have an executable yet, read
@@ -74,23 +98,9 @@ For the most recent information about sponsoring look on the Vim web site:
http://www.vim.org/sponsor/
COMPILING
CONTRIBUTING
If you obtained a binary distribution you don't need to compile Vim. If you
obtained a source distribution, all the stuff for compiling Vim is in the
"src" directory. See src/INSTALL for instructions.
INSTALLATION
See one of these files for system-specific instructions:
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
There are more README_*.txt files, depending on the distribution you used.
If you would like to help making Vim better, see the CONTRIBUTING.md file.
INFORMATION

View File

@@ -8,25 +8,26 @@ maze Macros that solve a maze (amazing!).
urm Macros that simulate a simple computer: "Universal Register Machine"
The other files contain some handy utilities. They also serve as examples for
how to use Vi and Vim functionality.
dvorak for when you use a Dvorak keyboard
justify.vim user function for justifying text
less.sh + less.vim make Vim work like less (or more)
shellmenu.vim menus for editing shell scripts in the GUI version
swapmous.vim swap left and right mouse buttons
editexisting.vim when editing a file that is already edited with
another Vim instance
The following have been moved to an optional package. Add the command to your
vimrc file to use the package:
This one is only for Unix.
file_select.vim macros that make a handy file selector
packadd! dvorak " Dvorak keyboard support; adds mappings
The matchit plugin has been moved to an optional package. To load it put this
line in your vimrc file:
:packadd matchit
packadd! editexisting " when editing a file that is already edited with
" another Vim instance, go to that Vim instance
packadd! justify " justifying text.
packadd! matchit " makes the % command work better
packadd! shellmenu " menus for editing shell scripts in the GUI version
packadd! swapmouse " swap left and right mouse buttons

View File

@@ -1,164 +0,0 @@
When using a dvorak keyboard this file may be of help to you.
These mappings have been made by Lawrence Kesteloot <kesteloo@cs.unc.edu>.
What they do is that the most often used keys, like hjkl, are put in a more
easy to use position.
It may take some time to learn using this.
Put these lines in your .vimrc:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
" Key to go into dvorak mode:
map ,d :source ~/.dvorak
" Key to get out of dvorak mode:
map ,q :source ~/.qwerty
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
write these lines into the file ~/.dvorak:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
" Dvorak keyboard, only in insert mode and ex mode.
" You may want to add a list of map's too.
imap! a a
imap! b x
imap! c j
imap! d e
imap! e .
imap! f u
imap! g i
imap! h d
imap! i c
imap! j h
imap! k t
imap! l n
imap! m m
imap! n b
imap! o r
imap! p l
imap! q '
imap! r p
imap! s o
imap! t y
imap! u g
imap! v k
imap! w ,
imap! x q
imap! y f
imap! z ;
imap! ; s
imap! ' -
imap! " _
imap! , w
imap! . v
imap! / z
imap! A A
imap! B X
imap! C J
imap! D E
imap! E >
imap! F U
imap! G I
imap! H D
imap! I C
imap! J H
imap! K T
imap! L N
imap! M M
imap! N B
imap! O R
imap! P L
imap! Q "
imap! R P
imap! S O
imap! T Y
imap! U G
imap! V K
imap! W <
imap! X Q
imap! Y F
imap! Z :
imap! < W
imap! > V
imap! ? Z
imap! : S
imap! [ /
imap! ] =
imap! { ?
imap! } +
imap! - [
imap! _ {
imap! = ]
imap! + }
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
write these lines into the file ~/.qwerty
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
" Qwerty keyboard
unmap! a
unmap! b
unmap! c
unmap! d
unmap! e
unmap! f
unmap! g
unmap! h
unmap! i
unmap! j
unmap! k
unmap! l
unmap! m
unmap! n
unmap! o
unmap! p
unmap! q
unmap! r
unmap! s
unmap! t
unmap! u
unmap! v
unmap! w
unmap! x
unmap! y
unmap! z
unmap! ;
unmap! '
unmap! \"
unmap! ,
unmap! .
unmap! /
unmap! A
unmap! B
unmap! C
unmap! D
unmap! E
unmap! F
unmap! G
unmap! H
unmap! I
unmap! J
unmap! K
unmap! L
unmap! M
unmap! N
unmap! O
unmap! P
unmap! Q
unmap! R
unmap! S
unmap! T
unmap! U
unmap! V
unmap! W
unmap! X
unmap! Y
unmap! Z
unmap! <
unmap! >
unmap! ?
unmap! :
unmap! [
unmap! ]
unmap! {
unmap! }
unmap! -
unmap! _
unmap! =
unmap! +
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

View File

@@ -1,119 +1,3 @@
" Vim Plugin: Edit the file with an existing Vim if possible
" Maintainer: Bram Moolenaar
" Last Change: 2014 Dec 06
" This is a plugin, drop it in your (Unix) ~/.vim/plugin or (Win32)
" $VIM/vimfiles/plugin directory. Or make a symbolic link, so that you
" automatically use the latest version.
" This plugin serves two purposes:
" 1. On startup, if we were invoked with one file name argument and the file
" is not modified then try to find another Vim instance that is editing
" this file. If there is one then bring it to the foreground and exit.
" 2. When a file is edited and a swap file exists for it, try finding that
" other Vim and bring it to the foreground. Requires Vim 7, because it
" uses the SwapExists autocommand event.
if v:version < 700
finish
endif
" Function that finds the Vim instance that is editing "filename" and brings
" it to the foreground.
func s:EditElsewhere(filename)
let fname_esc = substitute(a:filename, "'", "''", "g")
let servers = serverlist()
while servers != ''
" Get next server name in "servername"; remove it from "servers".
let i = match(servers, "\n")
if i == -1
let servername = servers
let servers = ''
else
let servername = strpart(servers, 0, i)
let servers = strpart(servers, i + 1)
endif
" Skip ourselves.
if servername ==? v:servername
continue
endif
" Check if this server is editing our file.
if remote_expr(servername, "bufloaded('" . fname_esc . "')")
" Yes, bring it to the foreground.
if has("win32")
call remote_foreground(servername)
endif
call remote_expr(servername, "foreground()")
if remote_expr(servername, "exists('*EditExisting')")
" Make sure the file is visible in a window (not hidden).
" If v:swapcommand exists and is set, send it to the server.
if exists("v:swapcommand")
let c = substitute(v:swapcommand, "'", "''", "g")
call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')")
else
call remote_expr(servername, "EditExisting('" . fname_esc . "', '')")
endif
endif
if !(has('vim_starting') && has('gui_running') && has('gui_win32'))
" Tell the user what is happening. Not when the GUI is starting
" though, it would result in a message box.
echomsg "File is being edited by " . servername
sleep 2
endif
return 'q'
endif
endwhile
return ''
endfunc
" When the plugin is loaded and there is one file name argument: Find another
" Vim server that is editing this file right now.
if argc() == 1 && !&modified
if s:EditElsewhere(expand("%:p")) == 'q'
quit
endif
endif
" Setup for handling the situation that an existing swap file is found.
try
au! SwapExists * let v:swapchoice = s:EditElsewhere(expand("<afile>:p"))
catch
" Without SwapExists we don't do anything for ":edit" commands
endtry
" Function used on the server to make the file visible and possibly execute a
" command.
func! EditExisting(fname, command)
" Get the window number of the file in the current tab page.
let winnr = bufwinnr(a:fname)
if winnr <= 0
" Not found, look in other tab pages.
let bufnr = bufnr(a:fname)
for i in range(tabpagenr('$'))
if index(tabpagebuflist(i + 1), bufnr) >= 0
" Make this tab page the current one and find the window number.
exe 'tabnext ' . (i + 1)
let winnr = bufwinnr(a:fname)
break
endif
endfor
endif
if winnr > 0
exe winnr . "wincmd w"
elseif exists('*fnameescape')
exe "split " . fnameescape(a:fname)
else
exe "split " . escape(a:fname, " \t\n*?[{`$\\%#'\"|!<")
endif
if a:command != ''
exe "normal! " . a:command
endif
redraw
endfunc
" Load the editexisting package.
" For those users who were loading the editexisting plugin from here.
packadd editexisting

View File

@@ -1,316 +1,3 @@
" Function to left and right align text.
"
" Written by: Preben "Peppe" Guldberg <c928400@student.dtu.dk>
" Created: 980806 14:13 (or around that time anyway)
" Revised: 001103 00:36 (See "Revisions" below)
" function Justify( [ textwidth [, maxspaces [, indent] ] ] )
"
" Justify() will left and right align a line by filling in an
" appropriate amount of spaces. Extra spaces are added to existing
" spaces starting from the right side of the line. As an example, the
" following documentation has been justified.
"
" The function takes the following arguments:
" textwidth argument
" ------------------
" If not specified, the value of the 'textwidth' option is used. If
" 'textwidth' is zero a value of 80 is used.
"
" Additionally the arguments 'tw' and '' are accepted. The value of
" 'textwidth' will be used. These are handy, if you just want to specify
" the maxspaces argument.
" maxspaces argument
" ------------------
" If specified, alignment will only be done, if the longest space run
" after alignment is no longer than maxspaces.
"
" An argument of '' is accepted, should the user like to specify all
" arguments.
"
" To aid user defined commands, negative values are accepted aswell.
" Using a negative value specifies the default behaviour: any length of
" space runs will be used to justify the text.
" indent argument
" ---------------
" This argument specifies how a line should be indented. The default is
" to keep the current indentation.
"
" Negative values: Keep current amount of leading whitespace.
" Positive values: Indent all lines with leading whitespace using this
" amount of whitespace.
"
" Note that the value 0, needs to be quoted as a string. This value
" leads to a left flushed text.
"
" Additionally units of 'shiftwidth'/'sw' and 'tabstop'/'ts' may be
" added. In this case, if the value of indent is positive, the amount of
" whitespace to be added will be multiplied by the value of the
" 'shiftwidth' and 'tabstop' settings. If these units are used, the
" argument must be given as a string, eg. Justify('','','2sw').
"
" If the values of 'sw' or 'tw' are negative, they are treated as if
" they were 0, which means that the text is flushed left. There is no
" check if a negative number prefix is used to change the sign of a
" negative 'sw' or 'ts' value.
"
" As with the other arguments, '' may be used to get the default
" behaviour.
" Notes:
"
" If the line, adjusted for space runs and leading/trailing whitespace,
" is wider than the used textwidth, the line will be left untouched (no
" whitespace removed). This should be equivalent to the behaviour of
" :left, :right and :center.
"
" If the resulting line is shorter than the used textwidth it is left
" untouched.
"
" All space runs in the line are truncated before the alignment is
" carried out.
"
" If you have set 'noexpandtab', :retab! is used to replace space runs
" with whitespace using the value of 'tabstop'. This should be
" conformant with :left, :right and :center.
"
" If joinspaces is set, an extra space is added after '.', '?' and '!'.
" If 'cpooptions' include 'j', extra space is only added after '.'.
" (This may on occasion conflict with maxspaces.)
" Related mappings:
"
" Mappings that will align text using the current text width, using at
" most four spaces in a space run and keeping current indentation.
nmap _j :%call Justify('tw',4)<CR>
vmap _j :call Justify('tw',4)<CR>
"
" Mappings that will remove space runs and format lines (might be useful
" prior to aligning the text).
nmap ,gq :%s/\s\+/ /g<CR>gq1G
vmap ,gq :s/\s\+/ /g<CR>gvgq
" User defined command:
"
" The following is an ex command that works as a shortcut to the Justify
" function. Arguments to Justify() can be added after the command.
com! -range -nargs=* Justify <line1>,<line2>call Justify(<f-args>)
"
" The following commands are all equivalent:
"
" 1. Simplest use of Justify():
" :call Justify()
" :Justify
"
" 2. The _j mapping above via the ex command:
" :%Justify tw 4
"
" 3. Justify visualised text at 72nd column while indenting all
" previously indented text two shiftwidths
" :'<,'>call Justify(72,'','2sw')
" :'<,'>Justify 72 -1 2sw
"
" This documentation has been justified using the following command:
":se et|kz|1;/^" function Justify(/+,'z-g/^" /s/^" //|call Justify(70,3)|s/^/" /
" Revisions:
" 001103: If 'joinspaces' was set, calculations could be wrong.
" Tabs at start of line could also lead to errors.
" Use setline() instead of "exec 's/foo/bar/' - safer.
" Cleaned up the code a bit.
"
" Todo: Convert maps to the new script specific form
" Error function
function! Justify_error(message)
echohl Error
echo "Justify([tw, [maxspaces [, indent]]]): " . a:message
echohl None
endfunction
" Now for the real thing
function! Justify(...) range
if a:0 > 3
call Justify_error("Too many arguments (max 3)")
return 1
endif
" Set textwidth (accept 'tw' and '' as arguments)
if a:0 >= 1
if a:1 =~ '^\(tw\)\=$'
let tw = &tw
elseif a:1 =~ '^\d\+$'
let tw = a:1
else
call Justify_error("tw must be a number (>0), '' or 'tw'")
return 2
endif
else
let tw = &tw
endif
if tw == 0
let tw = 80
endif
" Set maximum number of spaces between WORDs
if a:0 >= 2
if a:2 == ''
let maxspaces = tw
elseif a:2 =~ '^-\d\+$'
let maxspaces = tw
elseif a:2 =~ '^\d\+$'
let maxspaces = a:2
else
call Justify_error("maxspaces must be a number or ''")
return 3
endif
else
let maxspaces = tw
endif
if maxspaces <= 1
call Justify_error("maxspaces should be larger than 1")
return 4
endif
" Set the indentation style (accept sw and ts units)
let indent_fix = ''
if a:0 >= 3
if (a:3 == '') || a:3 =~ '^-[1-9]\d*\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = -1
elseif a:3 =~ '^-\=0\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = 0
elseif a:3 =~ '^\d\+\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = substitute(a:3, '\D', '', 'g')
elseif a:3 =~ '^\(shiftwidth\|sw\|tabstop\|ts\)$'
let indent = 1
else
call Justify_error("indent: a number with 'sw'/'ts' unit")
return 5
endif
if indent >= 0
while indent > 0
let indent_fix = indent_fix . ' '
let indent = indent - 1
endwhile
let indent_sw = 0
if a:3 =~ '\(shiftwidth\|sw\)'
let indent_sw = &sw
elseif a:3 =~ '\(tabstop\|ts\)'
let indent_sw = &ts
endif
let indent_fix2 = ''
while indent_sw > 0
let indent_fix2 = indent_fix2 . indent_fix
let indent_sw = indent_sw - 1
endwhile
let indent_fix = indent_fix2
endif
else
let indent = -1
endif
" Avoid substitution reports
let save_report = &report
set report=1000000
" Check 'joinspaces' and 'cpo'
if &js == 1
if &cpo =~ 'j'
let join_str = '\(\. \)'
else
let join_str = '\([.!?!] \)'
endif
endif
let cur = a:firstline
while cur <= a:lastline
let str_orig = getline(cur)
let save_et = &et
set et
exec cur . "retab"
let &et = save_et
let str = getline(cur)
let indent_str = indent_fix
let indent_n = strlen(indent_str)
" Shall we remember the current indentation
if indent < 0
let indent_orig = matchstr(str_orig, '^\s*')
if strlen(indent_orig) > 0
let indent_str = indent_orig
let indent_n = strlen(matchstr(str, '^\s*'))
endif
endif
" Trim trailing, leading and running whitespace
let str = substitute(str, '\s\+$', '', '')
let str = substitute(str, '^\s\+', '', '')
let str = substitute(str, '\s\+', ' ', 'g')
let str_n = strdisplaywidth(str)
" Possible addition of space after punctuation
if exists("join_str")
let str = substitute(str, join_str, '\1 ', 'g')
endif
let join_n = strdisplaywidth(str) - str_n
" Can extraspaces be added?
" Note that str_n may be less than strlen(str) [joinspaces above]
if strdisplaywidth(str) <= tw - indent_n && str_n > 0
" How many spaces should be added
let s_add = tw - str_n - indent_n - join_n
let s_nr = strlen(substitute(str, '\S', '', 'g') ) - join_n
let s_dup = s_add / s_nr
let s_mod = s_add % s_nr
" Test if the changed line fits with tw
if 0 <= (str_n + (maxspaces - 1)*s_nr + indent_n) - tw
" Duplicate spaces
while s_dup > 0
let str = substitute(str, '\( \+\)', ' \1', 'g')
let s_dup = s_dup - 1
endwhile
" Add extra spaces from the end
while s_mod > 0
let str = substitute(str, '\(\(\s\+\S\+\)\{' . s_mod . '}\)$', ' \1', '')
let s_mod = s_mod - 1
endwhile
" Indent the line
if indent_n > 0
let str = substitute(str, '^', indent_str, '' )
endif
" Replace the line
call setline(cur, str)
" Convert to whitespace
if &et == 0
exec cur . 'retab!'
endif
endif " Change of line
endif " Possible change
let cur = cur + 1
endwhile
norm ^
let &report = save_report
endfunction
" EOF vim: tw=78 ts=8 sw=4 sts=4 noet ai
" Load the justify package.
" For those users who were loading the justify plugin from here.
packadd justify

View File

@@ -1,94 +1,3 @@
" When you're writing shell scripts and you are in doubt which test to use,
" which shell environment variables are defined, what the syntax of the case
" statement is, and you need to invoke 'man sh'?
"
" Your problems are over now!
"
" Attached is a Vim script file for turning gvim into a shell script editor.
" It may also be used as an example how to use menus in Vim.
"
" Written by: Lennart Schultz <les@dmi.min.dk>
imenu Stmts.for for in
do
doneki kk0elli
imenu Stmts.case case in
) ;;
esacbki k0elli
imenu Stmts.if if
then
fiki kk0elli
imenu Stmts.if-else if
then
else
fiki kki kk0elli
imenu Stmts.elif elif
then
ki kk0elli
imenu Stmts.while while
do
doneki kk0elli
imenu Stmts.break break
imenu Stmts.continue continue
imenu Stmts.function () {
}ki k0i
imenu Stmts.return return
imenu Stmts.return-true return 0
imenu Stmts.return-false return 1
imenu Stmts.exit exit
imenu Stmts.shift shift
imenu Stmts.trap trap
imenu Test.existence [ -e ]hi
imenu Test.existence - file [ -f ]hi
imenu Test.existence - file (not empty) [ -s ]hi
imenu Test.existence - directory [ -d ]hi
imenu Test.existence - executable [ -x ]hi
imenu Test.existence - readable [ -r ]hi
imenu Test.existence - writable [ -w ]hi
imenu Test.String is empty [ x = "x$" ]hhi
imenu Test.String is not empty [ x != "x$" ]hhi
imenu Test.Strings is equal [ "" = "" ]hhhhhhhi
imenu Test.Strings is not equal [ "" != "" ]hhhhhhhhi
imenu Test.Values is greater than [ -gt ]hhhhhhi
imenu Test.Values is greater equal [ -ge ]hhhhhhi
imenu Test.Values is equal [ -eq ]hhhhhhi
imenu Test.Values is not equal [ -ne ]hhhhhhi
imenu Test.Values is less than [ -lt ]hhhhhhi
imenu Test.Values is less equal [ -le ]hhhhhhi
imenu ParmSub.Substitute word if parm not set ${:-}hhi
imenu ParmSub.Set parm to word if not set ${:=}hhi
imenu ParmSub.Substitute word if parm set else nothing ${:+}hhi
imenu ParmSub.If parm not set print word and exit ${:?}hhi
imenu SpShVars.Number of positional parameters ${#}
imenu SpShVars.All positional parameters (quoted spaces) ${*}
imenu SpShVars.All positional parameters (unquoted spaces) ${@}
imenu SpShVars.Flags set ${-}
imenu SpShVars.Return code of last command ${?}
imenu SpShVars.Process number of this shell ${$}
imenu SpShVars.Process number of last background command ${!}
imenu Environ.HOME ${HOME}
imenu Environ.PATH ${PATH}
imenu Environ.CDPATH ${CDPATH}
imenu Environ.MAIL ${MAIL}
imenu Environ.MAILCHECK ${MAILCHECK}
imenu Environ.PS1 ${PS1}
imenu Environ.PS2 ${PS2}
imenu Environ.IFS ${IFS}
imenu Environ.SHACCT ${SHACCT}
imenu Environ.SHELL ${SHELL}
imenu Environ.LC_CTYPE ${LC_CTYPE}
imenu Environ.LC_MESSAGES ${LC_MESSAGES}
imenu Builtins.cd cd
imenu Builtins.echo echo
imenu Builtins.eval eval
imenu Builtins.exec exec
imenu Builtins.export export
imenu Builtins.getopts getopts
imenu Builtins.hash hash
" Load the shellmenu package.
" For those users who were loading the shellmenu plugin from here.
packadd shellmenu

View File

@@ -1,22 +1,3 @@
" These macros swap the left and right mouse buttons (for left handed)
" Don't forget to do ":set mouse=a" or the mouse won't work at all
noremap <LeftMouse> <RightMouse>
noremap <2-LeftMouse> <2-RightMouse>
noremap <3-LeftMouse> <3-RightMouse>
noremap <4-LeftMouse> <4-RightMouse>
noremap <LeftDrag> <RightDrag>
noremap <LeftRelease> <RightRelease>
noremap <RightMouse> <LeftMouse>
noremap <2-RightMouse> <2-LeftMouse>
noremap <3-RightMouse> <3-LeftMouse>
noremap <4-RightMouse> <4-LeftMouse>
noremap <RightDrag> <LeftDrag>
noremap <RightRelease> <LeftRelease>
noremap g<LeftMouse> <C-RightMouse>
noremap g<RightMouse> <C-LeftMouse>
noremap! <LeftMouse> <RightMouse>
noremap! <LeftDrag> <RightDrag>
noremap! <LeftRelease> <RightRelease>
noremap! <RightMouse> <LeftMouse>
noremap! <RightDrag> <LeftDrag>
noremap! <RightRelease> <LeftRelease>
" Load the swapmouse package.
" For those users who were loading the swapmous plugin from here.
packadd swapmouse

View File

@@ -0,0 +1,72 @@
" Back to Qwerty keyboard after using Dvorak.
iunmap a
iunmap b
iunmap c
iunmap d
iunmap e
iunmap f
iunmap g
iunmap h
iunmap i
iunmap j
iunmap k
iunmap l
iunmap m
iunmap n
iunmap o
iunmap p
iunmap q
iunmap r
iunmap s
iunmap t
iunmap u
iunmap v
iunmap w
iunmap x
iunmap y
iunmap z
iunmap ;
iunmap '
iunmap "
iunmap ,
iunmap .
iunmap /
iunmap A
iunmap B
iunmap C
iunmap D
iunmap E
iunmap F
iunmap G
iunmap H
iunmap I
iunmap J
iunmap K
iunmap L
iunmap M
iunmap N
iunmap O
iunmap P
iunmap Q
iunmap R
iunmap S
iunmap T
iunmap U
iunmap V
iunmap W
iunmap X
iunmap Y
iunmap Z
iunmap <
iunmap >
iunmap ?
iunmap :
iunmap [
iunmap ]
iunmap {
iunmap }
iunmap -
iunmap _
iunmap =
iunmap +

View File

@@ -0,0 +1,77 @@
" Dvorak keyboard, only in Insert mode.
"
" Change "inoremap" to "map!" to also use in Ex mode.
" Also change disable.vim then: "iunmap" to "unmap!".
"
" You may want to add a list of map's too.
inoremap a a
inoremap b x
inoremap c j
inoremap d e
inoremap e .
inoremap f u
inoremap g i
inoremap h d
inoremap i c
inoremap j h
inoremap k t
inoremap l n
inoremap m m
inoremap n b
inoremap o r
inoremap p l
inoremap q '
inoremap r p
inoremap s o
inoremap t y
inoremap u g
inoremap v k
inoremap w ,
inoremap x q
inoremap y f
inoremap z ;
inoremap ; s
inoremap ' -
inoremap " _
inoremap , w
inoremap . v
inoremap / z
inoremap A A
inoremap B X
inoremap C J
inoremap D E
inoremap E >
inoremap F U
inoremap G I
inoremap H D
inoremap I C
inoremap J H
inoremap K T
inoremap L N
inoremap M M
inoremap N B
inoremap O R
inoremap P L
inoremap Q "
inoremap R P
inoremap S O
inoremap T Y
inoremap U G
inoremap V K
inoremap W <
inoremap X Q
inoremap Y F
inoremap Z :
inoremap < W
inoremap > V
inoremap ? Z
inoremap : S
inoremap [ /
inoremap ] =
inoremap { ?
inoremap } +
inoremap - [
inoremap _ {
inoremap = ]
inoremap + }

View File

@@ -0,0 +1,16 @@
" When using a dvorak keyboard this file may be of help to you.
" These mappings have been made by Lawrence Kesteloot <kesteloo@cs.unc.edu>.
" What they do is that the most often used keys, like hjkl, are put in a more
" easy to use position.
" It may take some time to learn using this.
if exists("g:loaded_dvorak_plugin")
finish
endif
let g:loaded_dvorak_plugin = 1
" Key to go into dvorak mode:
map ,d :runtime dvorak/enable.vim<CR>
" Key to get out of dvorak mode:
map ,q :runtime dvorak/disable.vim<CR>

View File

@@ -0,0 +1,114 @@
" Vim Plugin: Edit the file with an existing Vim if possible
" Maintainer: Bram Moolenaar
" Last Change: 2016 Mar 28
" To use add ":packadd! editexisting" in your vimrc file.
" This plugin serves two purposes:
" 1. On startup, if we were invoked with one file name argument and the file
" is not modified then try to find another Vim instance that is editing
" this file. If there is one then bring it to the foreground and exit.
" 2. When a file is edited and a swap file exists for it, try finding that
" other Vim and bring it to the foreground. Requires Vim 7, because it
" uses the SwapExists autocommand event.
" Function that finds the Vim instance that is editing "filename" and brings
" it to the foreground.
func s:EditElsewhere(filename)
let fname_esc = substitute(a:filename, "'", "''", "g")
let servers = serverlist()
while servers != ''
" Get next server name in "servername"; remove it from "servers".
let i = match(servers, "\n")
if i == -1
let servername = servers
let servers = ''
else
let servername = strpart(servers, 0, i)
let servers = strpart(servers, i + 1)
endif
" Skip ourselves.
if servername ==? v:servername
continue
endif
" Check if this server is editing our file.
if remote_expr(servername, "bufloaded('" . fname_esc . "')")
" Yes, bring it to the foreground.
if has("win32")
call remote_foreground(servername)
endif
call remote_expr(servername, "foreground()")
if remote_expr(servername, "exists('*EditExisting')")
" Make sure the file is visible in a window (not hidden).
" If v:swapcommand exists and is set, send it to the server.
if exists("v:swapcommand")
let c = substitute(v:swapcommand, "'", "''", "g")
call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')")
else
call remote_expr(servername, "EditExisting('" . fname_esc . "', '')")
endif
endif
if !(has('vim_starting') && has('gui_running') && has('gui_win32'))
" Tell the user what is happening. Not when the GUI is starting
" though, it would result in a message box.
echomsg "File is being edited by " . servername
sleep 2
endif
return 'q'
endif
endwhile
return ''
endfunc
" When the plugin is loaded and there is one file name argument: Find another
" Vim server that is editing this file right now.
if argc() == 1 && !&modified
if s:EditElsewhere(expand("%:p")) == 'q'
quit
endif
endif
" Setup for handling the situation that an existing swap file is found.
try
au! SwapExists * let v:swapchoice = s:EditElsewhere(expand("<afile>:p"))
catch
" Without SwapExists we don't do anything for ":edit" commands
endtry
" Function used on the server to make the file visible and possibly execute a
" command.
func! EditExisting(fname, command)
" Get the window number of the file in the current tab page.
let winnr = bufwinnr(a:fname)
if winnr <= 0
" Not found, look in other tab pages.
let bufnr = bufnr(a:fname)
for i in range(tabpagenr('$'))
if index(tabpagebuflist(i + 1), bufnr) >= 0
" Make this tab page the current one and find the window number.
exe 'tabnext ' . (i + 1)
let winnr = bufwinnr(a:fname)
break
endif
endfor
endif
if winnr > 0
exe winnr . "wincmd w"
elseif exists('*fnameescape')
exe "split " . fnameescape(a:fname)
else
exe "split " . escape(a:fname, " \t\n*?[{`$\\%#'\"|!<")
endif
if a:command != ''
exe "normal! " . a:command
endif
redraw
endfunc

View File

@@ -0,0 +1,316 @@
" Function to left and right align text.
"
" Written by: Preben "Peppe" Guldberg <c928400@student.dtu.dk>
" Created: 980806 14:13 (or around that time anyway)
" Revised: 001103 00:36 (See "Revisions" below)
" function Justify( [ textwidth [, maxspaces [, indent] ] ] )
"
" Justify() will left and right align a line by filling in an
" appropriate amount of spaces. Extra spaces are added to existing
" spaces starting from the right side of the line. As an example, the
" following documentation has been justified.
"
" The function takes the following arguments:
" textwidth argument
" ------------------
" If not specified, the value of the 'textwidth' option is used. If
" 'textwidth' is zero a value of 80 is used.
"
" Additionally the arguments 'tw' and '' are accepted. The value of
" 'textwidth' will be used. These are handy, if you just want to specify
" the maxspaces argument.
" maxspaces argument
" ------------------
" If specified, alignment will only be done, if the longest space run
" after alignment is no longer than maxspaces.
"
" An argument of '' is accepted, should the user like to specify all
" arguments.
"
" To aid user defined commands, negative values are accepted aswell.
" Using a negative value specifies the default behaviour: any length of
" space runs will be used to justify the text.
" indent argument
" ---------------
" This argument specifies how a line should be indented. The default is
" to keep the current indentation.
"
" Negative values: Keep current amount of leading whitespace.
" Positive values: Indent all lines with leading whitespace using this
" amount of whitespace.
"
" Note that the value 0, needs to be quoted as a string. This value
" leads to a left flushed text.
"
" Additionally units of 'shiftwidth'/'sw' and 'tabstop'/'ts' may be
" added. In this case, if the value of indent is positive, the amount of
" whitespace to be added will be multiplied by the value of the
" 'shiftwidth' and 'tabstop' settings. If these units are used, the
" argument must be given as a string, eg. Justify('','','2sw').
"
" If the values of 'sw' or 'tw' are negative, they are treated as if
" they were 0, which means that the text is flushed left. There is no
" check if a negative number prefix is used to change the sign of a
" negative 'sw' or 'ts' value.
"
" As with the other arguments, '' may be used to get the default
" behaviour.
" Notes:
"
" If the line, adjusted for space runs and leading/trailing whitespace,
" is wider than the used textwidth, the line will be left untouched (no
" whitespace removed). This should be equivalent to the behaviour of
" :left, :right and :center.
"
" If the resulting line is shorter than the used textwidth it is left
" untouched.
"
" All space runs in the line are truncated before the alignment is
" carried out.
"
" If you have set 'noexpandtab', :retab! is used to replace space runs
" with whitespace using the value of 'tabstop'. This should be
" conformant with :left, :right and :center.
"
" If joinspaces is set, an extra space is added after '.', '?' and '!'.
" If 'cpooptions' include 'j', extra space is only added after '.'.
" (This may on occasion conflict with maxspaces.)
" Related mappings:
"
" Mappings that will align text using the current text width, using at
" most four spaces in a space run and keeping current indentation.
nmap _j :%call Justify('tw',4)<CR>
vmap _j :call Justify('tw',4)<CR>
"
" Mappings that will remove space runs and format lines (might be useful
" prior to aligning the text).
nmap ,gq :%s/\s\+/ /g<CR>gq1G
vmap ,gq :s/\s\+/ /g<CR>gvgq
" User defined command:
"
" The following is an ex command that works as a shortcut to the Justify
" function. Arguments to Justify() can be added after the command.
com! -range -nargs=* Justify <line1>,<line2>call Justify(<f-args>)
"
" The following commands are all equivalent:
"
" 1. Simplest use of Justify():
" :call Justify()
" :Justify
"
" 2. The _j mapping above via the ex command:
" :%Justify tw 4
"
" 3. Justify visualised text at 72nd column while indenting all
" previously indented text two shiftwidths
" :'<,'>call Justify(72,'','2sw')
" :'<,'>Justify 72 -1 2sw
"
" This documentation has been justified using the following command:
":se et|kz|1;/^" function Justify(/+,'z-g/^" /s/^" //|call Justify(70,3)|s/^/" /
" Revisions:
" 001103: If 'joinspaces' was set, calculations could be wrong.
" Tabs at start of line could also lead to errors.
" Use setline() instead of "exec 's/foo/bar/' - safer.
" Cleaned up the code a bit.
"
" Todo: Convert maps to the new script specific form
" Error function
function! Justify_error(message)
echohl Error
echo "Justify([tw, [maxspaces [, indent]]]): " . a:message
echohl None
endfunction
" Now for the real thing
function! Justify(...) range
if a:0 > 3
call Justify_error("Too many arguments (max 3)")
return 1
endif
" Set textwidth (accept 'tw' and '' as arguments)
if a:0 >= 1
if a:1 =~ '^\(tw\)\=$'
let tw = &tw
elseif a:1 =~ '^\d\+$'
let tw = a:1
else
call Justify_error("tw must be a number (>0), '' or 'tw'")
return 2
endif
else
let tw = &tw
endif
if tw == 0
let tw = 80
endif
" Set maximum number of spaces between WORDs
if a:0 >= 2
if a:2 == ''
let maxspaces = tw
elseif a:2 =~ '^-\d\+$'
let maxspaces = tw
elseif a:2 =~ '^\d\+$'
let maxspaces = a:2
else
call Justify_error("maxspaces must be a number or ''")
return 3
endif
else
let maxspaces = tw
endif
if maxspaces <= 1
call Justify_error("maxspaces should be larger than 1")
return 4
endif
" Set the indentation style (accept sw and ts units)
let indent_fix = ''
if a:0 >= 3
if (a:3 == '') || a:3 =~ '^-[1-9]\d*\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = -1
elseif a:3 =~ '^-\=0\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = 0
elseif a:3 =~ '^\d\+\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = substitute(a:3, '\D', '', 'g')
elseif a:3 =~ '^\(shiftwidth\|sw\|tabstop\|ts\)$'
let indent = 1
else
call Justify_error("indent: a number with 'sw'/'ts' unit")
return 5
endif
if indent >= 0
while indent > 0
let indent_fix = indent_fix . ' '
let indent = indent - 1
endwhile
let indent_sw = 0
if a:3 =~ '\(shiftwidth\|sw\)'
let indent_sw = &sw
elseif a:3 =~ '\(tabstop\|ts\)'
let indent_sw = &ts
endif
let indent_fix2 = ''
while indent_sw > 0
let indent_fix2 = indent_fix2 . indent_fix
let indent_sw = indent_sw - 1
endwhile
let indent_fix = indent_fix2
endif
else
let indent = -1
endif
" Avoid substitution reports
let save_report = &report
set report=1000000
" Check 'joinspaces' and 'cpo'
if &js == 1
if &cpo =~ 'j'
let join_str = '\(\. \)'
else
let join_str = '\([.!?!] \)'
endif
endif
let cur = a:firstline
while cur <= a:lastline
let str_orig = getline(cur)
let save_et = &et
set et
exec cur . "retab"
let &et = save_et
let str = getline(cur)
let indent_str = indent_fix
let indent_n = strlen(indent_str)
" Shall we remember the current indentation
if indent < 0
let indent_orig = matchstr(str_orig, '^\s*')
if strlen(indent_orig) > 0
let indent_str = indent_orig
let indent_n = strlen(matchstr(str, '^\s*'))
endif
endif
" Trim trailing, leading and running whitespace
let str = substitute(str, '\s\+$', '', '')
let str = substitute(str, '^\s\+', '', '')
let str = substitute(str, '\s\+', ' ', 'g')
let str_n = strdisplaywidth(str)
" Possible addition of space after punctuation
if exists("join_str")
let str = substitute(str, join_str, '\1 ', 'g')
endif
let join_n = strdisplaywidth(str) - str_n
" Can extraspaces be added?
" Note that str_n may be less than strlen(str) [joinspaces above]
if strdisplaywidth(str) <= tw - indent_n && str_n > 0
" How many spaces should be added
let s_add = tw - str_n - indent_n - join_n
let s_nr = strlen(substitute(str, '\S', '', 'g') ) - join_n
let s_dup = s_add / s_nr
let s_mod = s_add % s_nr
" Test if the changed line fits with tw
if 0 <= (str_n + (maxspaces - 1)*s_nr + indent_n) - tw
" Duplicate spaces
while s_dup > 0
let str = substitute(str, '\( \+\)', ' \1', 'g')
let s_dup = s_dup - 1
endwhile
" Add extra spaces from the end
while s_mod > 0
let str = substitute(str, '\(\(\s\+\S\+\)\{' . s_mod . '}\)$', ' \1', '')
let s_mod = s_mod - 1
endwhile
" Indent the line
if indent_n > 0
let str = substitute(str, '^', indent_str, '' )
endif
" Replace the line
call setline(cur, str)
" Convert to whitespace
if &et == 0
exec cur . 'retab!'
endif
endif " Change of line
endif " Possible change
let cur = cur + 1
endwhile
norm ^
let &report = save_report
endfunction
" EOF vim: tw=78 ts=8 sw=4 sts=4 noet ai

View File

@@ -0,0 +1,94 @@
" When you're writing shell scripts and you are in doubt which test to use,
" which shell environment variables are defined, what the syntax of the case
" statement is, and you need to invoke 'man sh'?
"
" Your problems are over now!
"
" Attached is a Vim script file for turning gvim into a shell script editor.
" It may also be used as an example how to use menus in Vim.
"
" Written by: Lennart Schultz <les@dmi.min.dk>
imenu Stmts.for for in
do
doneki kk0elli
imenu Stmts.case case in
) ;;
esacbki k0elli
imenu Stmts.if if
then
fiki kk0elli
imenu Stmts.if-else if
then
else
fiki kki kk0elli
imenu Stmts.elif elif
then
ki kk0elli
imenu Stmts.while while
do
doneki kk0elli
imenu Stmts.break break
imenu Stmts.continue continue
imenu Stmts.function () {
}ki k0i
imenu Stmts.return return
imenu Stmts.return-true return 0
imenu Stmts.return-false return 1
imenu Stmts.exit exit
imenu Stmts.shift shift
imenu Stmts.trap trap
imenu Test.existence [ -e ]hi
imenu Test.existence - file [ -f ]hi
imenu Test.existence - file (not empty) [ -s ]hi
imenu Test.existence - directory [ -d ]hi
imenu Test.existence - executable [ -x ]hi
imenu Test.existence - readable [ -r ]hi
imenu Test.existence - writable [ -w ]hi
imenu Test.String is empty [ x = "x$" ]hhi
imenu Test.String is not empty [ x != "x$" ]hhi
imenu Test.Strings is equal [ "" = "" ]hhhhhhhi
imenu Test.Strings is not equal [ "" != "" ]hhhhhhhhi
imenu Test.Values is greater than [ -gt ]hhhhhhi
imenu Test.Values is greater equal [ -ge ]hhhhhhi
imenu Test.Values is equal [ -eq ]hhhhhhi
imenu Test.Values is not equal [ -ne ]hhhhhhi
imenu Test.Values is less than [ -lt ]hhhhhhi
imenu Test.Values is less equal [ -le ]hhhhhhi
imenu ParmSub.Substitute word if parm not set ${:-}hhi
imenu ParmSub.Set parm to word if not set ${:=}hhi
imenu ParmSub.Substitute word if parm set else nothing ${:+}hhi
imenu ParmSub.If parm not set print word and exit ${:?}hhi
imenu SpShVars.Number of positional parameters ${#}
imenu SpShVars.All positional parameters (quoted spaces) ${*}
imenu SpShVars.All positional parameters (unquoted spaces) ${@}
imenu SpShVars.Flags set ${-}
imenu SpShVars.Return code of last command ${?}
imenu SpShVars.Process number of this shell ${$}
imenu SpShVars.Process number of last background command ${!}
imenu Environ.HOME ${HOME}
imenu Environ.PATH ${PATH}
imenu Environ.CDPATH ${CDPATH}
imenu Environ.MAIL ${MAIL}
imenu Environ.MAILCHECK ${MAILCHECK}
imenu Environ.PS1 ${PS1}
imenu Environ.PS2 ${PS2}
imenu Environ.IFS ${IFS}
imenu Environ.SHACCT ${SHACCT}
imenu Environ.SHELL ${SHELL}
imenu Environ.LC_CTYPE ${LC_CTYPE}
imenu Environ.LC_MESSAGES ${LC_MESSAGES}
imenu Builtins.cd cd
imenu Builtins.echo echo
imenu Builtins.eval eval
imenu Builtins.exec exec
imenu Builtins.export export
imenu Builtins.getopts getopts
imenu Builtins.hash hash

View File

@@ -0,0 +1,22 @@
" These macros swap the left and right mouse buttons (for left handed)
" Don't forget to do ":set mouse=a" or the mouse won't work at all
noremap <LeftMouse> <RightMouse>
noremap <2-LeftMouse> <2-RightMouse>
noremap <3-LeftMouse> <3-RightMouse>
noremap <4-LeftMouse> <4-RightMouse>
noremap <LeftDrag> <RightDrag>
noremap <LeftRelease> <RightRelease>
noremap <RightMouse> <LeftMouse>
noremap <2-RightMouse> <2-LeftMouse>
noremap <3-RightMouse> <3-LeftMouse>
noremap <4-RightMouse> <4-LeftMouse>
noremap <RightDrag> <LeftDrag>
noremap <RightRelease> <LeftRelease>
noremap g<LeftMouse> <C-RightMouse>
noremap g<RightMouse> <C-LeftMouse>
noremap! <LeftMouse> <RightMouse>
noremap! <LeftDrag> <RightDrag>
noremap! <LeftRelease> <RightRelease>
noremap! <RightMouse> <LeftMouse>
noremap! <RightDrag> <LeftDrag>
noremap! <RightRelease> <LeftRelease>

View File

@@ -434,7 +434,6 @@ channel_read_fd(int fd)
/*
* Read a command from netbeans.
* TODO: instead of channel ID use the FD.
*/
#ifdef FEAT_GUI_X11
static void
@@ -974,6 +973,7 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options)
/* Special mode: send last-but-one line when appending a line
* to the buffer. */
in_part->ch_buffer->b_write_to_channel = TRUE;
in_part->ch_buf_append = TRUE;
in_part->ch_buf_top =
in_part->ch_buffer->b_ml.ml_line_count + 1;
}
@@ -1048,6 +1048,8 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
channel->ch_part[PART_OUT].ch_timeout = opt->jo_out_timeout;
if (opt->jo_set & JO_ERR_TIMEOUT)
channel->ch_part[PART_ERR].ch_timeout = opt->jo_err_timeout;
if (opt->jo_set & JO_BLOCK_WRITE)
channel->ch_part[PART_IN].ch_block_write = 1;
if (opt->jo_set & JO_CALLBACK)
{
@@ -1184,7 +1186,6 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
int len = (int)STRLEN(line);
char_u *p;
/* TODO: check if channel can be written to, do not block on write */
if ((p = alloc(len + 2)) == NULL)
return;
STRCPY(p, line);
@@ -1194,10 +1195,79 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
vim_free(p);
}
/*
* Return TRUE if "channel" can be written to.
* Returns FALSE if the input is closed or the write would block.
*/
static int
can_write_buf_line(channel_T *channel)
{
chanpart_T *in_part = &channel->ch_part[PART_IN];
if (in_part->ch_fd == INVALID_FD)
return FALSE; /* pipe was closed */
/* for testing: block every other attempt to write */
if (in_part->ch_block_write == 1)
in_part->ch_block_write = -1;
else if (in_part->ch_block_write == -1)
in_part->ch_block_write = 1;
/* TODO: Win32 implementation, probably using WaitForMultipleObjects() */
#ifndef WIN32
{
# if defined(HAVE_SELECT)
struct timeval tval;
fd_set wfds;
int ret;
FD_ZERO(&wfds);
FD_SET((int)in_part->ch_fd, &wfds);
tval.tv_sec = 0;
tval.tv_usec = 0;
for (;;)
{
ret = select((int)in_part->ch_fd + 1, NULL, &wfds, NULL, &tval);
# ifdef EINTR
SOCK_ERRNO;
if (ret == -1 && errno == EINTR)
continue;
# endif
if (ret <= 0 || in_part->ch_block_write == 1)
{
if (ret > 0)
ch_log(channel, "FAKED Input not ready for writing");
else
ch_log(channel, "Input not ready for writing");
return FALSE;
}
break;
}
# else
struct pollfd fds;
fds.fd = in_part->ch_fd;
fds.events = POLLOUT;
if (poll(&fds, 1, 0) <= 0)
{
ch_log(channel, "Input not ready for writing");
return FALSE;
}
if (in_part->ch_block_write == 1)
{
ch_log(channel, "FAKED Input not ready for writing");
return FALSE;
}
# endif
}
#endif
return TRUE;
}
/*
* Write any lines to the input channel.
*/
void
static void
channel_write_in(channel_T *channel)
{
chanpart_T *in_part = &channel->ch_part[PART_IN];
@@ -1205,21 +1275,20 @@ channel_write_in(channel_T *channel)
buf_T *buf = in_part->ch_buffer;
int written = 0;
if (buf == NULL)
return;
if (buf == NULL || in_part->ch_buf_append)
return; /* no buffer or using appending */
if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL)
{
/* buffer was wiped out or unloaded */
in_part->ch_buffer = NULL;
return;
}
if (in_part->ch_fd == INVALID_FD)
/* pipe was closed */
return;
for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot
&& lnum <= buf->b_ml.ml_line_count; ++lnum)
{
if (!can_write_buf_line(channel))
break;
write_buf_line(buf, lnum, channel);
++written;
}
@@ -1230,6 +1299,37 @@ channel_write_in(channel_T *channel)
ch_logn(channel, "written %d lines to channel", written);
in_part->ch_buf_top = lnum;
if (lnum > buf->b_ml.ml_line_count)
{
/* Writing is done, no longer need the buffer. */
in_part->ch_buffer = NULL;
ch_log(channel, "Finished writing all lines to channel");
}
else
ch_logn(channel, "Still %d more lines to write",
buf->b_ml.ml_line_count - lnum + 1);
}
/*
* Write any lines waiting to be written to a channel.
*/
void
channel_write_any_lines()
{
channel_T *channel;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
{
chanpart_T *in_part = &channel->ch_part[PART_IN];
if (in_part->ch_buffer != NULL)
{
if (in_part->ch_buf_append)
channel_write_new_lines(in_part->ch_buffer);
else
channel_write_in(channel);
}
}
}
/*
@@ -1249,15 +1349,16 @@ channel_write_new_lines(buf_T *buf)
linenr_T lnum;
int written = 0;
if (in_part->ch_buffer == buf)
if (in_part->ch_buffer == buf && in_part->ch_buf_append)
{
if (in_part->ch_fd == INVALID_FD)
/* pipe was closed */
continue;
continue; /* pipe was closed */
found_one = TRUE;
for (lnum = in_part->ch_buf_bot; lnum < buf->b_ml.ml_line_count;
++lnum)
{
if (!can_write_buf_line(channel))
break;
write_buf_line(buf, lnum, channel);
++written;
}
@@ -1266,6 +1367,9 @@ channel_write_new_lines(buf_T *buf)
ch_logn(channel, "written line %d to channel", (int)lnum - 1);
else if (written > 1)
ch_logn(channel, "written %d lines to channel", written);
if (lnum < buf->b_ml.ml_line_count)
ch_logn(channel, "Still %d more lines to write",
buf->b_ml.ml_line_count - lnum);
in_part->ch_buf_bot = lnum;
}
@@ -1325,11 +1429,34 @@ channel_get(channel_T *channel, int part)
static char_u *
channel_get_all(channel_T *channel, int part)
{
/* Concatenate everything into one buffer.
* TODO: avoid multiple allocations. */
while (channel_collapse(channel, part) == OK)
;
return channel_get(channel, part);
readq_T *head = &channel->ch_part[part].ch_head;
readq_T *node = head->rq_next;
long_u len = 1;
char_u *res;
char_u *p;
/* If there is only one buffer just get that one. */
if (head->rq_next == NULL || head->rq_next->rq_next == NULL)
return channel_get(channel, part);
/* Concatenate everything into one buffer. */
for (node = head->rq_next; node != NULL; node = node->rq_next)
len += (long_u)STRLEN(node->rq_buffer);
res = lalloc(len, TRUE);
if (res == NULL)
return NULL;
*res = NUL;
for (node = head->rq_next; node != NULL; node = node->rq_next)
STRCAT(res, node->rq_buffer);
/* Free all buffers */
do
{
p = channel_get(channel, part);
vim_free(p);
} while (p != NULL);
return res;
}
/*
@@ -1365,10 +1492,12 @@ channel_collapse(channel_T *channel, int part)
/*
* Store "buf[len]" on "channel"/"part".
* When "prepend" is TRUE put in front, otherwise append at the end.
* Returns OK or FAIL.
*/
static int
channel_save(channel_T *channel, int part, char_u *buf, int len, char *lead)
channel_save(channel_T *channel, int part, char_u *buf, int len,
int prepend, char *lead)
{
readq_T *node;
readq_T *head = &channel->ch_part[part].ch_head;
@@ -1400,14 +1529,28 @@ channel_save(channel_T *channel, int part, char_u *buf, int len, char *lead)
node->rq_buffer[len] = NUL;
}
/* append node to the tail of the queue */
node->rq_next = NULL;
node->rq_prev = head->rq_prev;
if (head->rq_prev == NULL)
if (prepend)
{
/* preend node to the head of the queue */
node->rq_next = head->rq_next;
node->rq_prev = NULL;
if (head->rq_next == NULL)
head->rq_prev = node;
else
head->rq_next->rq_prev = node;
head->rq_next = node;
}
else
head->rq_prev->rq_next = node;
head->rq_prev = node;
{
/* append node to the tail of the queue */
node->rq_next = NULL;
node->rq_prev = head->rq_prev;
if (head->rq_prev == NULL)
head->rq_next = node;
else
head->rq_prev->rq_next = node;
head->rq_prev = node;
}
if (log_fd != NULL && lead != NULL)
{
@@ -1420,6 +1563,42 @@ channel_save(channel_T *channel, int part, char_u *buf, int len, char *lead)
return OK;
}
static int
channel_fill(js_read_T *reader)
{
channel_T *channel = (channel_T *)reader->js_cookie;
int part = reader->js_cookie_arg;
char_u *next = channel_get(channel, part);
int unused;
int len;
char_u *p;
if (next == NULL)
return FALSE;
unused = reader->js_end - reader->js_buf - reader->js_used;
if (unused > 0)
{
/* Prepend unused text. */
len = (int)STRLEN(next);
p = alloc(unused + len + 1);
if (p == NULL)
{
vim_free(next);
return FALSE;
}
mch_memmove(p, reader->js_buf + reader->js_used, unused);
mch_memmove(p + unused, next, len + 1);
vim_free(next);
next = p;
}
vim_free(reader->js_buf);
reader->js_buf = next;
reader->js_used = 0;
return TRUE;
}
/*
* Use the read buffer of "channel"/"part" and parse a JSON message that is
* complete. The messages are added to the queue.
@@ -1439,19 +1618,17 @@ channel_parse_json(channel_T *channel, int part)
if (channel_peek(channel, part) == NULL)
return FALSE;
/* TODO: make reader work properly */
/* reader.js_buf = channel_peek(channel, part); */
reader.js_buf = channel_get_all(channel, part);
reader.js_buf = channel_get(channel, part);
reader.js_used = 0;
reader.js_fill = NULL;
/* reader.js_fill = channel_fill; */
reader.js_fill = channel_fill;
reader.js_cookie = channel;
reader.js_cookie_arg = part;
/* When a message is incomplete we wait for a short while for more to
* arrive. After the delay drop the input, otherwise a truncated string
* or list will make us hang. */
status = json_decode(&reader, &listtv,
chanpart->ch_mode == MODE_JS ? JSON_JS : 0);
chanpart->ch_mode == MODE_JS ? JSON_JS : 0);
if (status == OK)
{
/* Only accept the response when it is a list with at least two
@@ -1552,10 +1729,10 @@ channel_parse_json(channel_T *channel, int part)
}
else if (reader.js_buf[reader.js_used] != NUL)
{
/* Put the unread part back into the channel.
* TODO: insert in front */
/* Put the unread part back into the channel. */
channel_save(channel, part, reader.js_buf + reader.js_used,
(int)(reader.js_end - reader.js_buf) - reader.js_used, NULL);
(int)(reader.js_end - reader.js_buf) - reader.js_used,
TRUE, NULL);
ret = status == MAYBE ? FALSE: TRUE;
}
else
@@ -2107,11 +2284,11 @@ channel_status(channel_T *channel)
channel_part_info(channel_T *channel, dict_T *dict, char *name, int part)
{
chanpart_T *chanpart = &channel->ch_part[part];
char namebuf[20];
char namebuf[20]; /* longest is "sock_timeout" */
size_t tail;
char *s = "";
STRCPY(namebuf, name);
vim_strncpy((char_u *)namebuf, (char_u *)name, 4);
STRCAT(namebuf, "_");
tail = STRLEN(namebuf);
@@ -2307,6 +2484,57 @@ channel_free_all(void)
/* Buffer size for reading incoming messages. */
#define MAXMSGSIZE 4096
#if defined(HAVE_SELECT)
/*
* Add write fds where we are waiting for writing to be possible.
*/
static int
channel_fill_wfds(int maxfd_arg, fd_set *wfds)
{
int maxfd = maxfd_arg;
channel_T *ch;
for (ch = first_channel; ch != NULL; ch = ch->ch_next)
{
chanpart_T *in_part = &ch->ch_part[PART_IN];
if (in_part->ch_fd != INVALID_FD && in_part->ch_buffer != NULL)
{
FD_SET((int)in_part->ch_fd, wfds);
if ((int)in_part->ch_fd >= maxfd)
maxfd = (int)in_part->ch_fd + 1;
}
}
return maxfd;
}
#else
/*
* Add write fds where we are waiting for writing to be possible.
*/
static int
channel_fill_poll_write(int nfd_in, struct pollfd *fds)
{
int nfd = nfd_in;
channel_T *ch;
for (ch = first_channel; ch != NULL; ch = ch->ch_next)
{
chanpart_T *in_part = &ch->ch_part[PART_IN];
if (in_part->ch_fd != INVALID_FD && in_part->ch_buffer != NULL)
{
in_part->ch_poll_idx = nfd;
fds[nfd].fd = in_part->ch_fd;
fds[nfd].events = POLLOUT;
++nfd;
}
else
in_part->ch_poll_idx = -1;
}
return nfd;
}
#endif
/*
* Check for reading from "fd" with "timeout" msec.
* Return FAIL when there is nothing to read.
@@ -2321,8 +2549,9 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
if (fd != channel->CH_SOCK_FD)
{
DWORD nread;
int diff;
int sleep_time;
DWORD deadline = GetTickCount() + timeout;
int delay = 1;
/* reading from a pipe, not a socket */
while (TRUE)
@@ -2330,12 +2559,21 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
if (PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL)
&& nread > 0)
return OK;
diff = deadline - GetTickCount();
if (diff <= 0)
/* perhaps write some buffer lines */
channel_write_any_lines();
sleep_time = deadline - GetTickCount();
if (sleep_time <= 0)
break;
/* Wait for 5 msec.
* TODO: increase the sleep time when looping more often */
Sleep(5);
/* Wait for a little while. Very short at first, up to 10 msec
* after looping a few times. */
if (sleep_time > delay)
sleep_time = delay;
Sleep(sleep_time);
delay = delay * 2;
if (delay > 10)
delay = 10;
}
}
else
@@ -2344,31 +2582,56 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
#if defined(HAVE_SELECT)
struct timeval tval;
fd_set rfds;
int ret;
fd_set wfds;
int ret;
int maxfd;
FD_ZERO(&rfds);
FD_SET((int)fd, &rfds);
tval.tv_sec = timeout / 1000;
tval.tv_usec = (timeout % 1000) * 1000;
for (;;)
{
ret = select((int)fd + 1, &rfds, NULL, NULL, &tval);
FD_ZERO(&rfds);
FD_SET((int)fd, &rfds);
/* Write lines to a pipe when a pipe can be written to. Need to
* set this every time, some buffers may be done. */
maxfd = (int)fd + 1;
FD_ZERO(&wfds);
maxfd = channel_fill_wfds(maxfd, &wfds);
ret = select(maxfd, &rfds, &wfds, NULL, &tval);
# ifdef EINTR
SOCK_ERRNO;
if (ret == -1 && errno == EINTR)
continue;
# endif
if (ret > 0)
return OK;
{
if (FD_ISSET(fd, &rfds))
return OK;
channel_write_any_lines();
continue;
}
break;
}
#else
struct pollfd fds;
for (;;)
{
struct pollfd fds[MAX_OPEN_CHANNELS + 1];
int nfd = 1;
fds.fd = fd;
fds.events = POLLIN;
if (poll(&fds, 1, timeout) > 0)
return OK;
fds[0].fd = fd;
fds[0].events = POLLIN;
nfd = channel_fill_poll_write(nfd, fds);
if (poll(fds, nfd, timeout) > 0)
{
if (fds[0].revents & POLLIN)
return OK;
channel_write_any_lines();
continue;
}
break;
}
#endif
}
return FAIL;
@@ -2419,7 +2682,7 @@ channel_read(channel_T *channel, int part, char *func)
break; /* error or nothing more to read */
/* Store the read message in the queue. */
channel_save(channel, part, buf, len, "RECV ");
channel_save(channel, part, buf, len, FALSE, "RECV ");
readlen += len;
if (len < MAXMSGSIZE)
break; /* did read everything that's available */
@@ -2446,11 +2709,10 @@ channel_read(channel_T *channel, int part, char *func)
if (channel->ch_part[part].ch_mode == MODE_RAW
|| channel->ch_part[part].ch_mode == MODE_NL)
channel_save(channel, part, (char_u *)DETACH_MSG_RAW,
(int)STRLEN(DETACH_MSG_RAW), "PUT ");
(int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT ");
/* TODO: When reading from stdout is not possible, should we try to
* keep stdin and stderr open? Probably not, assume the other side
* has died. */
/* When reading from stdout is not possible, assume the other side has
* died. */
channel_close(channel, TRUE);
if (channel->ch_nb_close_cb != NULL)
(*channel->ch_nb_close_cb)();
@@ -2933,10 +3195,12 @@ channel_poll_setup(int nfd_in, void *fds_in)
{
for (part = PART_SOCK; part < PART_IN; ++part)
{
if (channel->ch_part[part].ch_fd != INVALID_FD)
chanpart_T *ch_part = &channel->ch_part[part];
if (ch_part->ch_fd != INVALID_FD)
{
channel->ch_part[part].ch_poll_idx = nfd;
fds[nfd].fd = channel->ch_part[part].ch_fd;
ch_part->ch_poll_idx = nfd;
fds[nfd].fd = ch_part->ch_fd;
fds[nfd].events = POLLIN;
nfd++;
}
@@ -2945,6 +3209,8 @@ channel_poll_setup(int nfd_in, void *fds_in)
}
}
nfd = channel_fill_poll_write(nfd, fds);
return nfd;
}
@@ -2958,19 +3224,35 @@ channel_poll_check(int ret_in, void *fds_in)
channel_T *channel;
struct pollfd *fds = fds_in;
int part;
int idx;
chanpart_T *in_part;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
{
for (part = PART_SOCK; part < PART_IN; ++part)
{
int idx = channel->ch_part[part].ch_poll_idx;
idx = channel->ch_part[part].ch_poll_idx;
if (ret > 0 && idx != -1 && fds[idx].revents & POLLIN)
if (ret > 0 && idx != -1 && (fds[idx].revents & POLLIN))
{
channel_read(channel, part, "channel_poll_check");
--ret;
}
}
in_part = &channel->ch_part[PART_IN];
idx = in_part->ch_poll_idx;
if (ret > 0 && idx != -1 && (fds[idx].revents & POLLOUT))
{
if (in_part->ch_buf_append)
{
if (in_part->ch_buffer != NULL)
channel_write_new_lines(in_part->ch_buffer);
}
else
channel_write_in(channel);
--ret;
}
}
return ret;
@@ -2979,14 +3261,15 @@ channel_poll_check(int ret_in, void *fds_in)
# if (!defined(WIN32) && defined(HAVE_SELECT)) || defined(PROTO)
/*
* The type of "rfds" is hidden to avoid problems with the function proto.
* The "fd_set" type is hidden to avoid problems with the function proto.
*/
int
channel_select_setup(int maxfd_in, void *rfds_in)
channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in)
{
int maxfd = maxfd_in;
channel_T *channel;
fd_set *rfds = rfds_in;
fd_set *wfds = wfds_in;
int part;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
@@ -3004,19 +3287,23 @@ channel_select_setup(int maxfd_in, void *rfds_in)
}
}
maxfd = channel_fill_wfds(maxfd, wfds);
return maxfd;
}
/*
* The type of "rfds" is hidden to avoid problems with the function proto.
* The "fd_set" type is hidden to avoid problems with the function proto.
*/
int
channel_select_check(int ret_in, void *rfds_in)
channel_select_check(int ret_in, void *rfds_in, void *wfds_in)
{
int ret = ret_in;
channel_T *channel;
fd_set *rfds = rfds_in;
fd_set *wfds = wfds_in;
int part;
chanpart_T *in_part;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
{
@@ -3030,6 +3317,20 @@ channel_select_check(int ret_in, void *rfds_in)
--ret;
}
}
in_part = &channel->ch_part[PART_IN];
if (ret > 0 && in_part->ch_fd != INVALID_FD
&& FD_ISSET(in_part->ch_fd, wfds))
{
if (in_part->ch_buf_append)
{
if (in_part->ch_buffer != NULL)
channel_write_new_lines(in_part->ch_buffer);
}
else
channel_write_in(channel);
--ret;
}
}
return ret;
@@ -3531,6 +3832,13 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "block_write") == 0)
{
if (!(supported & JO_BLOCK_WRITE))
break;
opt->jo_set |= JO_BLOCK_WRITE;
opt->jo_block_write = get_tv_number(item);
}
else
break;
--todo;
@@ -3750,8 +4058,8 @@ job_start(typval_T *argvars)
clear_job_options(&opt);
opt.jo_mode = MODE_NL;
if (get_job_options(&argvars[1], &opt,
JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL
+ JO_STOPONEXIT + JO_EXIT_CB + JO_OUT_IO) == FAIL)
JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
+ JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL)
return job;
/* Check that when io is "file" that there is a file name. */
@@ -3812,6 +4120,11 @@ job_start(typval_T *argvars)
{
/* Command is a string. */
cmd = argvars[0].vval.v_string;
if (cmd == NULL || *cmd == NUL)
{
EMSG(_(e_invarg));
return job;
}
#ifdef USE_ARGV
if (mch_parse_cmd(cmd, FALSE, &argv, &argc) == FAIL)
return job;

View File

@@ -762,6 +762,7 @@ install_bat_choice(int idx)
fprintf(fd, "@echo off\n");
fprintf(fd, "rem -- Run Vim --\n");
fprintf(fd, "\n");
fprintf(fd, "setlocal\n");
/* Don't use double quotes for the "set" argument, also when it
* contains a space. The quotes would be included in the value
@@ -793,6 +794,9 @@ install_bat_choice(int idx)
fprintf(fd, "if .%%1==. goto loopend\n");
if (*exename == 'g')
{
fprintf(fd, "if NOT .%%1==.--nofork goto noforklongarg\n");
fprintf(fd, "set VIMNOFORK=1\n");
fprintf(fd, ":noforklongarg\n");
fprintf(fd, "if NOT .%%1==.-f goto noforkarg\n");
fprintf(fd, "set VIMNOFORK=1\n");
fprintf(fd, ":noforkarg\n");

View File

@@ -933,6 +933,11 @@ eval_init(void)
for (i = 0; i < VV_LEN; ++i)
{
p = &vimvars[i];
if (STRLEN(p->vv_name) > 16)
{
EMSG("INTERNAL: name too long, increase size of dictitem16_T");
getout(1);
}
STRCPY(p->vv_di.di_key, p->vv_name);
if (p->vv_flags & VV_RO)
p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
@@ -3399,6 +3404,12 @@ set_context_for_expression(
got_eq = TRUE;
xp->xp_context = EXPAND_EXPRESSION;
}
else if (c == '#'
&& xp->xp_context == EXPAND_EXPRESSION)
{
/* Autoload function/variable contains '#'. */
break;
}
else if ((c == '<' || c == '#')
&& xp->xp_context == EXPAND_FUNCTIONS
&& vim_strchr(xp->xp_pattern, '(') == NULL)
@@ -6021,6 +6032,7 @@ rettv_list_alloc(typval_T *rettv)
rettv->vval.v_list = l;
rettv->v_type = VAR_LIST;
rettv->v_lock = 0;
++l->lv_refcount;
return OK;
}
@@ -7271,6 +7283,7 @@ rettv_dict_alloc(typval_T *rettv)
rettv->vval.v_dict = d;
rettv->v_type = VAR_DICT;
rettv->v_lock = 0;
++d->dv_refcount;
return OK;
}
@@ -9567,7 +9580,9 @@ f_assert_match(typval_T *argvars, typval_T *rettv UNUSED)
char_u *pat = get_tv_string_buf_chk(&argvars[0], buf1);
char_u *text = get_tv_string_buf_chk(&argvars[1], buf2);
if (!pattern_match(pat, text, FALSE))
if (pat == NULL || text == NULL)
EMSG(_(e_invarg));
else if (!pattern_match(pat, text, FALSE))
{
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],

View File

@@ -4491,7 +4491,9 @@ expand_cmdline(
#ifdef FEAT_MULTI_LANG
/*
* Cleanup matches for help tags: remove "@en" if "en" is the only language.
* Cleanup matches for help tags:
* Remove "@ab" if the top of 'helplang' is "ab" and the language of the first
* tag matches it. Otherwise remove "@en" if "en" is the only language.
*/
static void cleanup_help_tags(int num_file, char_u **file);
@@ -4500,11 +4502,28 @@ cleanup_help_tags(int num_file, char_u **file)
{
int i, j;
int len;
char_u buf[4];
char_u *p = buf;
if (p_hlg[0] != NUL)
{
*p++ = '@';
*p++ = p_hlg[0];
*p++ = p_hlg[1];
}
*p = NUL;
for (i = 0; i < num_file; ++i)
{
len = (int)STRLEN(file[i]) - 3;
if (len > 0 && STRCMP(file[i] + len, "@en") == 0)
if (len <= 0)
continue;
if (i == 0 && STRCMP(file[i] + len, buf) == 0)
{
file[i][len] = NUL;
break;
}
else if (STRCMP(file[i] + len, "@en") == 0)
{
/* Sorting on priority means the same item in another language may
* be anywhere. Search all items for a match up to the "@en". */
@@ -4514,7 +4533,10 @@ cleanup_help_tags(int num_file, char_u **file)
&& STRNCMP(file[i], file[j], len + 1) == 0)
break;
if (j == num_file)
{
file[i][len] = NUL;
break;
}
}
}
}

View File

@@ -1073,7 +1073,7 @@ load_base_module(void *data)
}
static Scheme_Object *
load_base_module_on_error(void *data)
load_base_module_on_error(void *data UNUSED)
{
load_base_module_failed = TRUE;
return scheme_null;

View File

@@ -350,8 +350,10 @@ json_skip_white(js_read_T *reader)
if (reader->js_fill != NULL && c == NUL)
{
if (reader->js_fill(reader))
{
reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
continue;
continue;
}
}
if (c == NUL || c > ' ')
break;

View File

@@ -6230,6 +6230,9 @@ parse_queued_messages(void)
netbeans_parse_messages();
# endif
# ifdef FEAT_JOB_CHANNEL
/* Write any buffer lines still to be written. */
channel_write_any_lines();
/* Process the messages queued on channels. */
channel_parse_messages();
# endif

View File

@@ -5539,7 +5539,8 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *break_loop)
# endif
#endif
#ifndef HAVE_SELECT
struct pollfd fds[6 + MAX_OPEN_CHANNELS];
/* each channel may use in, out and err */
struct pollfd fds[6 + 3 * MAX_OPEN_CHANNELS];
int nfd;
# ifdef FEAT_XCLIPBOARD
int xterm_idx = -1;
@@ -5652,7 +5653,7 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *break_loop)
struct timeval tv;
struct timeval *tvp;
fd_set rfds, efds;
fd_set rfds, wfds, efds;
int maxfd;
long towait = msec;
@@ -5685,6 +5686,7 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *break_loop)
*/
select_eintr:
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
FD_SET(fd, &rfds);
# if !defined(__QNX__) && !defined(__CYGWIN32__)
@@ -5725,10 +5727,10 @@ select_eintr:
}
# endif
# ifdef FEAT_JOB_CHANNEL
maxfd = channel_select_setup(maxfd, &rfds);
maxfd = channel_select_setup(maxfd, &rfds, &wfds);
# endif
ret = select(maxfd + 1, &rfds, NULL, &efds, tvp);
ret = select(maxfd + 1, &rfds, &wfds, &efds, tvp);
result = ret > 0 && FD_ISSET(fd, &rfds);
if (result)
--ret;
@@ -5810,7 +5812,7 @@ select_eintr:
# endif
#ifdef FEAT_JOB_CHANNEL
if (ret > 0)
ret = channel_select_check(ret, &rfds);
ret = channel_select_check(ret, &rfds, &wfds);
#endif
#endif /* HAVE_SELECT */

View File

@@ -13,7 +13,7 @@ void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
void channel_set_job(channel_T *channel, job_T *job, jobopt_T *options);
void channel_set_options(channel_T *channel, jobopt_T *opt);
void channel_set_req_callback(channel_T *channel, int part, char_u *callback, partial_T *partial, int id);
void channel_write_in(channel_T *channel);
void channel_write_any_lines(void);
void channel_write_new_lines(buf_T *buf);
char_u *channel_get(channel_T *channel, int part);
int channel_collapse(channel_T *channel, int part);
@@ -37,8 +37,8 @@ void ch_expr_common(typval_T *argvars, typval_T *rettv, int eval);
void ch_raw_common(typval_T *argvars, typval_T *rettv, int eval);
int channel_poll_setup(int nfd_in, void *fds_in);
int channel_poll_check(int ret_in, void *fds_in);
int channel_select_setup(int maxfd_in, void *rfds_in);
int channel_select_check(int ret_in, void *rfds_in);
int channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in);
int channel_select_check(int ret_in, void *rfds_in, void *wfds_in);
int channel_parse_messages(void);
int set_ref_in_channel(int copyID);
int channel_part_send(channel_T *channel);

View File

@@ -532,7 +532,8 @@ qf_init_ext(
else if (tv->v_type == VAR_LIST)
{
/* Get the next line from the supplied list */
while (p_li && p_li->li_tv.v_type != VAR_STRING)
while (p_li && (p_li->li_tv.v_type != VAR_STRING
|| p_li->li_tv.vval.v_string == NULL))
p_li = p_li->li_next; /* Skip non-string items */
if (!p_li) /* End of the list */

View File

@@ -1383,12 +1383,15 @@ typedef struct {
#else
struct timeval ch_deadline;
#endif
int ch_block_write; /* for testing: 0 when not used, -1 when write
* does not block, 1 simulate blocking */
cbq_T ch_cb_head; /* dummy node for per-request callbacks */
char_u *ch_callback; /* call when a msg is not handled */
partial_T *ch_partial;
buf_T *ch_buffer; /* buffer to read from or write to */
int ch_buf_append; /* write appended lines instead top-bot */
linenr_T ch_buf_top; /* next line to send */
linenr_T ch_buf_bot; /* last line to send */
} chanpart_T;
@@ -1457,7 +1460,8 @@ struct channel_S {
#define JO_ERR_BUF 0x2000000 /* "err_buf" (JO_OUT_BUF << 1) */
#define JO_IN_BUF 0x4000000 /* "in_buf" (JO_OUT_BUF << 2) */
#define JO_CHANNEL 0x8000000 /* "channel" */
#define JO_ALL 0xfffffff
#define JO_BLOCK_WRITE 0x10000000 /* "block_write" */
#define JO_ALL 0x7fffffff
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
#define JO_CB_ALL \
@@ -1499,6 +1503,7 @@ typedef struct
int jo_timeout;
int jo_out_timeout;
int jo_err_timeout;
int jo_block_write; /* for testing only */
int jo_part;
int jo_id;
char_u jo_soe_buf[NUMBUFLEN];
@@ -2971,6 +2976,7 @@ struct js_reader
/* function to fill the buffer or NULL;
* return TRUE when the buffer was filled */
void *js_cookie; /* can be used by js_fill */
int js_cookie_arg; /* can be used by js_fill */
};
typedef struct js_reader js_read_T;

View File

@@ -791,7 +791,7 @@ func Run_test_pipe_from_buffer(use_name)
sp pipe-input
call setline(1, ['echo one', 'echo two', 'echo three'])
let options = {'in_io': 'buffer'}
let options = {'in_io': 'buffer', 'block_write': 1}
if a:use_name
let options['in_name'] = 'pipe-input'
else
@@ -885,7 +885,8 @@ func Test_pipe_io_two_buffers()
let job = job_start(s:python . " test_channel_pipe.py",
\ {'in_io': 'buffer', 'in_name': 'pipe-input', 'in_top': 0,
\ 'out_io': 'buffer', 'out_name': 'pipe-output'})
\ 'out_io': 'buffer', 'out_name': 'pipe-output',
\ 'block_write': 1})
call assert_equal("run", job_status(job))
try
exe "normal Gaecho hello\<CR>"
@@ -920,7 +921,8 @@ func Test_pipe_io_one_buffer()
let job = job_start(s:python . " test_channel_pipe.py",
\ {'in_io': 'buffer', 'in_name': 'pipe-io', 'in_top': 0,
\ 'out_io': 'buffer', 'out_name': 'pipe-io'})
\ 'out_io': 'buffer', 'out_name': 'pipe-io',
\ 'block_write': 1})
call assert_equal("run", job_status(job))
try
exe "normal Goecho hello\<CR>"
@@ -1201,5 +1203,10 @@ func Test_close_callback()
call s:run_server('s:test_close_callback')
endfunc
func Test_job_start_invalid()
call assert_fails('call job_start($x)', 'E474:')
call assert_fails('call job_start("")', 'E474:')
endfunc
" Uncomment this to see what happens, output is in src/testdir/channellog.
" call ch_logfile('channellog', 'w')

View File

@@ -692,3 +692,8 @@ func Test_caddbuffer_to_empty()
endtry
quit!
endfunc
func Test_cgetexpr_works()
" this must not crash Vim
cgetexpr [$x]
endfunc

View File

@@ -748,6 +748,48 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1684,
/**/
1683,
/**/
1682,
/**/
1681,
/**/
1680,
/**/
1679,
/**/
1678,
/**/
1677,
/**/
1676,
/**/
1675,
/**/
1674,
/**/
1673,
/**/
1672,
/**/
1671,
/**/
1670,
/**/
1669,
/**/
1668,
/**/
1667,
/**/
1666,
/**/
1665,
/**/
1664,
/**/
1663,
/**/

View File

@@ -493,13 +493,11 @@ typedef unsigned long u8char_T; /* long should be 32 bits or more */
#ifndef HAVE_SELECT
# ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
# define HAVE_POLL
# elif defined(WIN32)
# define HAVE_SELECT
# else
# ifdef HAVE_POLL_H
# include <poll.h>
# define HAVE_POLL
# endif
# endif
#endif