html indenting in vim - html

I don't know if this is possible, but does anyone know of an indent script that will support this scenario?
(| is cursor)
given
<div>|<div>
if I press enter, I want to see
<div>
|
</div>
instead of
<div>
|<div>

delimitMate will take care of this for you.
You will however, need two additional settings...
add the >:< pair to the list of html files:
au FileType html let delimitMate_matchpairs = "(:),[:],{:},>:<"
and tell it what pattern you'd like to add after inserting a
au FileType html let b:delimitMate_expand_cr = "\<CR>\<CR>\<Up>\<Tab>"
(this will, instead of inserting two a , insert two s, press up, then insert a tab)

Ended up going with brian Carpers answer, only modified very slightly
"fancy html indenting
function! NewlineInTag()
let lnum = getline('.')
let cnum = col('.')
let chars = strpart(lnum, cnum - 2, 3)
if chars =~ '></'
return "\<CR>\<ESC>\<UP>$o"
else
return "\<CR>"
endif
endfunction
autocmd FileType eruby,html imap <CR> <C-R>=NewlineInTag()<CR>

You could do something like this:
function! NewlineInTag()
let lnum = getline('.')
let cnum = col('.')
let chars = strpart(lnum, cnum - 2, 2)
if chars =~ '><'
return "\<CR>\<ESC>\<UP>$o"
else
return "\<CR>"
endif
endfunction
imap <CR> <C-R>=NewlineInTag()<CR>

Related

Turn vimscript key mapping into function

I am trying to make a function in vimscript that will activate on every cursor movement in visual mode, i.e. it will automatically highlight all the matches of the current visual selection.
The mapping from https://vi.stackexchange.com/questions/20077/automatically-highlight-all-occurrences-of-the-selected-text-in-visual-mode:
xnoremap <silent> <cr> "*y:silent! let searchTerm = '\V'.substitute(escape(#*, '\/'), "\n", '\\n', "g") <bar> let #/ = searchTerm <bar> echo '/'.#/ <bar> call histadd("search", searchTerm) <bar> set hls<cr>
works perfectly for me but I am failing to implement it into function. This is what I tried:
function! HighlightVisual(mode)
if mode()=~#"^[vV\<C-v>]"
call feedkeys('"*y')
let searchTerm = '\V'.substitute(escape(#*, '\/'), "\n", '\\n', "g")
let #/ = searchTerm
echo '/'.#/
call histadd("search", searchTerm)
set hls
endif
endfunction
autocmd CursorMoved * call HighlightVisual(mode())
However, it is not working.
What am I doing wrong? I think the function is terminated each time a call is invoked but have no idea how to workaround that.
I have made it work. Firstly, I found from https://vi.stackexchange.com/questions/28404/vim-does-not-call-functions-correctly-when-wrapped-in-another-function that "Vim doesn't like updating Screen too often" so redraw was necessary after set hls. And secondly, y was forcing normal mode and gv was moving cursor triggering the autocmd CursorMoved inside the function thus making an infinite loop. I made a workaround by set eventignore=CursorMoved and resetting it back at the end of function. I am saving selected word to register h (as in highlight) but you can choose any by changing "hy and #h. Moreover, I added highlight toggle when not needed. So, if somebody wants to use the feature of automatically highlighting visual matches, here is the code:
function! HighlightVisual(mode)
if mode()=~#"^[vV\<C-v>]"
set eventignore=CursorMoved
normal "hy
normal gv
let searchTerm = '\V'.substitute(escape(#h, '\/'), "\n", '\\n', "g")
let #/ = searchTerm
call histadd("search", searchTerm)
set hls
redraw
set eventignore=""
endif
endfunction
autocmd CursorMoved * :call HighlightVisual(mode())
vnoremap <silent> <ESC> :<C-u>set nohlsearch<CR>
; just copy-paste it in your .vimrc/init.vim.
Big thanks to trusktr as I used his answer in https://vi.stackexchange.com/questions/20077/automatically-highlight-all-occurrences-of-the-selected-text-in-visual-mode to build my function I wanted for sooo long.
Happy coding!

Open variable in readonly split window in vim?

Here is the current code that i am using in vim
function! NpmDocs()
let package_name = input('Package name: ')
if package_name != ''
let url = 'https://registry.npmjs.org/' . package_name
let res = webapi#http#get(url)
let obj =webapi#json#decode(res.content)
echo obj.readme
endif
endfunction
The problem is the echo part. Basically i want to open the output in a new split window like the one we get in help page. Can someone please help me out with how to go with it?

vim keep cursor position when counting matches

I have a function to count and return the number of matches of some text:
function! count_matches()
redir => matches_cnt
silent! %s/\[\d*\]//gn
redir END
return split(matches_cnt)[0]
endfunction
I created a map to insert the return value of count_matches() at the current position:
noremap <C-A> Go[foo<C-R>=count_matches()<CR>]
However the cursor jumps to the beginning of the line after executing the silent %s/[\d*]//gn command. So when I press control+a vim inserts "[foo", then the function is being executed, the search command resets the cursor position and the return value is inserted at the beginning of the line resulting in "1][foo" instead of "[foo1]".
Can I somehow prevent count from changing the cursor position, or reset the cursor position after counting the matches?
The script also leads to an error, if the pattern is not found. How can I get the function to return 1 without an error for zero matches?
Even better then just to save the cursor position, is to save the complete viewport. (But that only works, if you do not change the window layout)
See :help winsaveview()
let wsv = winsaveview()
MoveTheCursorAround
call winrestview(wsv)
In your particular case, I would take another approach:
inoremap <expr> <f3> len(split(join(getline(1,'$'),"\n"), '\[\d\+\]',1))
Which takes the whole text, and splits it on the pattern \[\d\+\] and then counts how many elements there are. Or if you like to add some text:
inoremap <expr> <f3> '['.len(split(join(getline(1,'$'),"\n"), '\[\d\+\]',1)).']'
This will add the [ in front and ] after the number. Adjust the mapping key and text to your personal taste. (Note, you do not need the winsaveview() function, cause the cursor won't move).
It is perhaps not such a good idea to use that function on a multi MB text size. ;)
This is the same function, reworked to return 1 when there's no match:
function! count_matches()
redir => matches_cnt
try
silent! %s/\[\d*\]//gn
catch
echo 1
endtry
redir END
return split(matches_cnt)[0]
endfunction
See :help getpos()
let save_cursor = getpos(".")
MoveTheCursorAround
call setpos('.', save_cursor)
My solution:
function! CountWithCursorKeep(...)
let currentCursor = getcurpos()
let pattern = expand('<cword>')
if a:0 > 0 | let pattern = a:1 | endif
execute(':%s#' . pattern . '##gn')
call setpos('.', currentCursor)
endfunction
nmap ,ns :call CountWithCursorKeep(<C-R>/)<cr>
nmap ,nw :call CountWithCursorKeep(expand('<cword>'))<cr>
nmap ,nW :call CountWithCursorKeep(expand('<cWORD>'))<cr>
command! -nargs=? -bar -complete=tag CountMatch call CountWithCursorKeep(<f-args>)
You can use :CountMatch pattern to get how many times pattern occurs in current file.

How to parse HTML tags in Matlab using regexp?

I'm short on time and specifically wanted to extract a string like the one below. Problem is the tag isn't of the form <a> data </a>.
Given,
s = <em style="font-size:medium"> 5,888 </em>
how to extract out just 5,888 in matlab?
You will find useful info here, or here, or here, all of which are google-first-page results and would have been faster than asking a question here.
Anyway, quick-'n-dirty way: You can filter on the <> symbols:
>> s = '<em style="font-size:medium"> 5,888 </em> <sometag> test </sometag>'
>> a = regexp(s, '[<>]');
>> s( cell2mat(arrayfun(#(x,y)x:y, a(2:2:end-1)+1, a(3:2:end)-1, 'uni',false)) )
ans =
5,888 test
Or, slightly more robust and much cleaner, replace everything between any tags (including the tags) with emptyness:
>> s = regexprep(s, '<.*?>', '')
ans =
5,888 test
Thanks folks for your help. I'm basically trying to get the population of a US county on Matlab. Thought I'l share my code, though not the most elegant. Might help some soul. :)
county = 'morris';
state = 'ks';
county = strrep(county, ' ' , '+');
str = sprintf('https://www.google.com/search?&q=population+%s+%s',county,state);
s = urlread(str);
pop = regexp(s,'<em[^>]*>(.*?)</em>', 'tokens');
pop = char(pop{:});
pop = strrep(pop, ',' , '');
pop = str2num(pop);

Skipping a window in VIM with Ctrl-W_W

When I have several windows open in VIM, I'd like to always skip one of them (the one containing my project using Aric Blumer's Project plugin), whenever I press Ctrl-W_W.
In other words I'd like to cycle through my document windows as if the Project window wasn't one of them. When I actually do want to go into the project window, I'll use the mapping I created especially for this purpose.
Is there a way to mark a window so that it's skipped by Ctrl-W_W or would I need a script? I'm loving Vim but am still in the steep part of the learning curve.
You would have to write a function (it's easier to maintain) that cycles to the next window, and skip it if it matches the name of the windows you don't want to go into.
Something like:
function! s:NextWindowBut(skip,dir)
let w0 = winnr()
let nok = 1
while nok
" exe "normal! \<c-W>w"
" or better
exe 'wincmd '.a:dir
let w = winnr()
let n = bufname('%')
let nok = (n=~a:skip) && (w != w0)
" echo "skip(".n."):".(n=~a:skip)." w!=w0:".(w != w0)." --> ".nok
endwhile
if w == w0
echomsg "No other acceptable window"
endif
endfunction
nnoremap <silent> <C-W>w :call <sid>NextWindowBut('thepattern','w')<cr>
nnoremap <silent> <C-W>W :call <sid>NextWindowBut('thepattern','W')<cr>