mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-05-28 00:21:57 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -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 = \
|
||||
|
||||
+14
-13
@@ -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
|
||||
|
||||
@@ -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! +
|
||||
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
@@ -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
|
||||
|
||||
+3
-316
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+72
@@ -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 +
|
||||
+77
@@ -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 + }
|
||||
+16
@@ -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>
|
||||
@@ -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
|
||||
+316
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
+374
-66
@@ -437,7 +437,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
|
||||
@@ -993,6 +992,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;
|
||||
}
|
||||
@@ -1067,6 +1067,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)
|
||||
{
|
||||
@@ -1203,7 +1205,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);
|
||||
@@ -1213,10 +1214,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];
|
||||
@@ -1224,21 +1294,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;
|
||||
}
|
||||
@@ -1249,6 +1318,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1268,15 +1368,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;
|
||||
}
|
||||
@@ -1285,6 +1386,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;
|
||||
}
|
||||
@@ -1344,11 +1448,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1384,10 +1511,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;
|
||||
@@ -1419,14 +1548,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)
|
||||
{
|
||||
@@ -1439,6 +1582,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.
|
||||
@@ -1458,19 +1637,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
|
||||
@@ -1571,10 +1748,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
|
||||
@@ -2126,11 +2303,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);
|
||||
|
||||
@@ -2326,6 +2503,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.
|
||||
@@ -2340,8 +2568,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)
|
||||
@@ -2349,12 +2578,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
|
||||
@@ -2363,31 +2601,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;
|
||||
@@ -2438,7 +2701,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 */
|
||||
@@ -2465,11 +2728,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)();
|
||||
@@ -2952,10 +3214,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++;
|
||||
}
|
||||
@@ -2964,6 +3228,8 @@ channel_poll_setup(int nfd_in, void *fds_in)
|
||||
}
|
||||
}
|
||||
|
||||
nfd = channel_fill_poll_write(nfd, fds);
|
||||
|
||||
return nfd;
|
||||
}
|
||||
|
||||
@@ -2977,19 +3243,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;
|
||||
@@ -2998,14 +3280,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)
|
||||
@@ -3023,19 +3306,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)
|
||||
{
|
||||
@@ -3049,6 +3336,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;
|
||||
@@ -3550,6 +3851,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;
|
||||
@@ -3769,8 +4077,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. */
|
||||
|
||||
@@ -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");
|
||||
|
||||
+16
-1
@@ -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],
|
||||
|
||||
+24
-2
@@ -4502,7 +4502,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);
|
||||
|
||||
@@ -4511,11 +4513,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". */
|
||||
@@ -4525,7 +4544,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+3
-1
@@ -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;
|
||||
|
||||
@@ -6236,6 +6236,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
|
||||
|
||||
+7
-5
@@ -5561,7 +5561,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;
|
||||
@@ -5674,7 +5675,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;
|
||||
|
||||
@@ -5707,6 +5708,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__)
|
||||
@@ -5747,10 +5749,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;
|
||||
@@ -5832,7 +5834,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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
+7
-1
@@ -1386,12 +1386,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;
|
||||
@@ -1460,7 +1463,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 \
|
||||
@@ -1502,6 +1506,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];
|
||||
@@ -2990,6 +2995,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;
|
||||
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -763,6 +763,42 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1683,
|
||||
/**/
|
||||
1682,
|
||||
/**/
|
||||
1681,
|
||||
/**/
|
||||
1680,
|
||||
/**/
|
||||
1679,
|
||||
/**/
|
||||
1678,
|
||||
/**/
|
||||
1677,
|
||||
/**/
|
||||
1676,
|
||||
/**/
|
||||
1675,
|
||||
/**/
|
||||
1674,
|
||||
/**/
|
||||
1673,
|
||||
/**/
|
||||
1672,
|
||||
/**/
|
||||
1671,
|
||||
/**/
|
||||
1670,
|
||||
/**/
|
||||
1669,
|
||||
/**/
|
||||
1668,
|
||||
/**/
|
||||
1667,
|
||||
/**/
|
||||
1666,
|
||||
/**/
|
||||
1665,
|
||||
/**/
|
||||
|
||||
@@ -494,13 +494,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
|
||||
|
||||
Reference in New Issue
Block a user