How do I enable folding on system verilog keywords in Gvim ?
For example
function
Code
....
....
endfunction
I would like Gvim to create a fold from function to endfunction. How do I do that ?
Here is a custom foldexpression that should do what you want. It starts a fold on the line following each "function", and ends it on the line preceding each "endfunction", and otherwise inherits the foldlevel of the previous line.
function! VimFunctionFoldExpr()
if getline(v:lnum-1) =~ '^\s*function'
return '>1'
elseif getline(v:lnum+1) =~ '^\s*endfunction'
return '<1'
else
return '='
endif
endfunction
To tell Vim to use this function, set the following:
set foldmethod=expr
set foldexpr=VimFunctionFoldExpr()
You might also want to tweak your foldtext setting so that it respects the intent level. Here is a SE question about how to do that.
Related
I'm having a hard time finding the documentation for this. How do I read/write text from the current buffer in my vim functions?
More concretely, if my buffer contains the words foo bar how would write a function to overwrite the word bar with cat so that in the end my buffer contains foo cat?
You can use the substitute ex command inside a function. For example
function! ReplaceBar()
:%s/bar/cat/g
endfunction
This defines a function. The % character means operate on the entire buffer. This searches for bar, replaces it with cat, and the g flag replaces every instance on a line, not just the first.
You can run this function by typing :call ReplaceBar() and hitting enter. Often it's convenient to define a function that does this kind of work, then define a command that calls it:
command! -nargs=0 Bar call ReplaceBar()
That command can be run by typing :Bar.
To access line(s), you can use the getline() function. setline() updates those lines in the buffer. Likewise, new lines are inserted via append().
The latter can also be done with :put ={variable or expression}, and replacements with :substitute. What is better depends on the particular use case. The benefit of the former, lower-level functions is that they don't clobber stuff like the expression register, last used search pattern, search history, etc.
In neovim, they have nvim_put. A few examples:
:call nvim_put(['cat'], 'c', v:false, v:true) ; insert 'cat' right where the cursor is, as if you typed `:normal! icat`
:call nvim_put(['cat'], 'l', v:true, v:true) ; insert 'cat' on the next line
Others have covered the use of :put pretty well, so I won't cover it myself.
I'm trying to create a script what permits me to select a few lines and create a virtualedit block around it; 1 column after the longest line.
This is my code
function! VirtualEdit()
let EndLine = line("'>")
set virtualedit = all
let maxlength = max(map(range(line("'<"), line("'>")), "virtcol([v:val, '$'])"))-1
call cursor(1,maxlength+1)
normal "^Q".EndLine."jc<space><ESC>"
set virtualedit = ''
endfunction
What it must do is
1) Control the longest line in my selection (maxlength).
2) Put the cursor on the first line in the selection at the column of the longest line +1 column.
3) Than Activate Visual Block selection (on my windows pc the command is C-Q)
4) Extend the visual block till the last line in the selection (the command on my pc for moving down = "j").
5) Than use the "c" key to insert a "space" character and ESC to exit the insert mode in order to fill the virtual block column with spaces.
However I can't find out how to use a variable (Endline) in a normal command.
I noted also that keys as and don't work in my above example.
What did I wrong?
You have many errors here:
:set does not let you have spaces around =
:set does not accept expressions, thus set ve='' is let &ve="''", not let &ve='' which is :set ve=.
:normal command also does not accept expressions, it accepts strings that are just executed. Thus :normal "^ is trying to use register ^, fails (no such register) and stops processing the rest of the line. Use :execute to pass expressions to :normal.
:normal command does not accept <Key> syntax. Neither do viml expressions, they have "\<Key>" instead (note: only double quotes and with backslash). ^Q syntax is not accepted by anybody and having raw control codes (displayed by vim as ^Q) inside a text file is not the best idea.
Don’t use :normal without a bang. Most of time you don’t need it (you need to replace ^Q with \<C-v> in this case though because it is a mapping).
Don’t hardcode virtualedit value. Instead of
set ve=all
<...>
set ve=
use
let savedve=&ve
set ve=all
try
<...>
finally
let &ve=savedve
endtry
{N}j means “N lines down”, not “go to N’th line”. “Go to N’th line” is {N}gg or {N}G.
You have let maxlen=<...>-1 and the on only line where maxlen is used you have maxlen+1. It is strange.
If you fix this you can proceed, but you don’t need adjusting virtualedit and using :normal at all:
function AddSpaces()
let [lstart, lend]=[line("'<"), line("'>")]
if lstart>lend
let [lstart, lend]=[lend, lstart]
endif
let maxcol=max(map(range(lstart, lend), "virtcol([v:val, '$'])"))
let newlines=map(range(lstart, lend), 'printf("%-'.maxcol.'s", getline(v:val))')
call setline(lstart, newlines)
endfunction
In Pascal, I have write and writeln. Apparently Lua's print is similar to writeln of Pascal. Do we have something similar to write of Pascal? How can consecutive print commands send their output to the same line?
print("Hello")
print("World")
Output:
Hello
world
I want to have this:
Hello world
Use io.write instead print, which is meant for simple uses, like debugging, anyway.
Expanding on lhf's correct answer, the io library is preferred for production use.
The print function in the base library is implemented as a primitive capability. It allows for quick and dirty scripts that compute something and print an answer, with little control over its presentation. Its principle benefits are that it coerces all arguments to string and that it separates each argument in the output with tabs and supplies a newline.
Those advantages quickly become defects when detailed control of the output is required. For that, you really need to use io.write. If you mix print and io.write in the same program, you might trip over another defect. print uses the C stdout file handle explicitly. This means that if you use io.output to change the output file handle, io.write will do what you expect but print won't.
A good compromise can be to implement a replacement for print in terms of io.write. It could look as simple as this untested sample where I've tried to write clearly rather than optimally and still handle nil arguments "correctly":
local write = io.write
function print(...)
local n = select("#",...)
for i = 1,n do
local v = tostring(select(i,...))
write(v)
if i~=n then write'\t' end
end
write'\n'
end
Once you are implementing your own version of print, then it can be tempting to improve it in other ways for your application. Using something with more formatting control than offered by tostring() is one good idea. Another is considering a separator other than a tab character.
As an alternative, just build up your string then write it out with a single print
You may not always have access to the io library.
You could use variables for "Hello" and "World". Then concatenate them later. Like this:
local h = "Hello"
local w = "World"
print(h..w)
It will be display, in this case, as "HelloWorld". But that's easy to fix. Hope this helped!
Adding on to #Searous's answer, try the following.
local h = "hello"
local w = "world"
print(h.." "..w)
You can concatenate both together, just concatenate a space between both variables.
local h = "Hello"
local w = "World!"
print(h, w)
I am using TeXnicCenter to edit a LaTeX document.
I now want to remove a certain tag (say, emph{blabla}} which occurs multiple times in my document , but not tag's content (so in this example, I want to remove all emphasization).
What is the easiest way to do so?
May also be using another program easily available on Windows 7.
Edit: In response to regex suggestions, it is important that it can deal with nested tags.
Edit 2: I really want to remove the tag from the text file, not just disable it.
Using a regular expression do something like s/\\emph\{([^\}]*)\}/\1/g. If you are not familiar with regular expressions this says:
s -- replace
/ -- begin match section
\\emph\{ -- match \emph{
( -- begin capture
[^\}]* -- match any characters except (meaning up until) a close brace because:
[] a group of characters
^ means not or "everything except"
\} -- the close brace
and * means 0 or more times
) -- end capture, because this is the first (in this case only) capture, it is number 1
\} -- match end brace
/ -- begin replace section
\1 -- replace with captured section number 1
/ -- end regular expression, begin extra flags
g -- global flag, meaning do this every time the match is found not just the first time
This is with Perl syntax, as that is what I am familiar with. The following perl "one-liners" will accomplish two tasks
perl -pe 's/\\emph\{([^\}]*)\}/\1/g' filename will "test" printing the file to the command line
perl -pi -e 's/\\emph\{([^\}]*)\}/\1/g' filename will change the file in place.
Similar commands may be available in your editor, but if not this will (should) work.
Crowley should have added this as an answer, but I will do that for him, if you replace all \emph{ with { you should be able to do this without disturbing the other content. It will still be in braces, but unless you have done some odd stuff it shouldn't matter.
The regex would be a simple s/\\emph\{/\{/g but the search and replace in your editor will do that one too.
Edit: Sorry, used the wrong brace in the regex, fixed now.
\renewcommand{\emph}[1]{#1}
any reasonably advanced editor should let you do a search/replace using regular expressions, replacing emph{bla} by bla etc.
I'm trying to set up Vim to detect when a .tex file contains the command '\usepackage{sagemath}', and run a command accordingly. I've gotten to
:au BufReadPost,BufWritePost *.tex TTarget sagepdf
but that will fire for all .tex files, which isn't what I want.
Theres an example in my filetype.vim on how to destinguish html types. You can easily modify to suit your logic. Note the getline(n) =~ lines
" HTML (.shtml and .stm for server side)
au BufNewFile,BufRead *.html,*.htm,*.shtml,*.stm call s:FThtml()
" Distinguish between HTML, XHTML and Django
fun! s:FThtml()
let n = 1
while n < 10 && n < line("$")
if getline(n) =~ '\<DTD\s\+XHTML\s'
setf xhtml
return
endif
if getline(n) =~ '{%\s*\(extends\|block\)\>'
setf html.django_template
" setf htmldjango
return
endif
let n = n + 1
endwhile
setf html
endfun
First, you should consider using a modeline.
If you can't get what you want with a modeline, you can use your own function in autocmd, like this:
function! MyFunction()
...
endfunction
autocmd BufReadPost,BufWritePost *.tex call MyFunction()
and you probably can write a function that checks whether a certain pattern matches, and then runs whatever you want.