Using AStyle in Vim - vim

I am trying to get AStyle working with Vim so that I can use the "=" key to re-indent various sections of code. For example, I'd like to be able to type my usual =iB to indent the current block of code using AStyle rather than the built in indenter.
I tried just setting equalprg=astyle in my vimrc, but the problem is that astyle only receives the selected block but thinks that it's receiving a whole file. Therefore, the indentation is completely off when I try to only indent a nested class.
I know that I can always reformat an entire file at once, but is there a way to use astyle in vim which completely replicates the original formatting behavior of vim (all my =-movement commands work - and bonus points for autoindent using astyle as well!)?

Unless there is a version of AStyle that has a partial file formatting option, you'll need to apply the extra indentation after you run AStyle.
I'm not sure how you can do this with motions.
With visual selection, you could grab the indentation from the first line, pass the code to equalprg, and then add that indentation to all of the lines:
vnoremap = <Esc>`<dwgv=`<<C-v>`>I<C-r>"<Esc>
Breaking it down:
vnoremap -- so we can use = for equalprg
<Esc>`< -- stop selecting and go to beginning of line at beginning of selection
dw -- grab the initial indentation
gv= -- reselect and indent as normal
`<<C-v>`> -- block select the selection
I<C-r>"<Esc> -- insert the initial indentation
Maybe you can do something similar with motions?

It only works for formatters that have a partial file formatting option, like idbrii already pointed out. An example of a formatter that does this is clang-format.
One way to integrate this into vim is by using vim-autoformat. Using this plugin you can viB and then press your self-defined format key, like <F3>. This will then only format the selected inner code block.

Related

What's wrong with gVim copy paste between windows?

I'm new to vim and I'm using gVim on Windows. I have two windows open in the same gvim instance and I'm just trying to copy some code from one to another. For some reason when it pastes it replaces the contents of some code with literally this:
list.forEach(function(name){...}------------------------------------------
Obviously, my real code does not have ... or a ton of dashes. What the hell is happening?
The dashes (----------) give it away: The block of code has been folded. (You probably also see the line with different colors (depending on your colorscheme).) Depending on the filetype, folding can be manual or automatic. For your (JavaScript?) code, it's the latter. So when you paste a block of code, Vim automatically detects the block and folds it.
There's a whole lot of commands and options around folding. Read more about it at :help folding. If you find this too confusing (for now), turn it off via
:set nofoldenable
Just press zo on the dashes(-----)
Aside: Use zf on selected (v) lines to fold lines.
zo - Open
zo - Fold

vim: end comments and retain indentation

I'd like to be able to end a run of comments but retain the current indentation. Is this possible either through an existing command or with a function?
I have formatoptions -=o and autoindent so I normally get by using o from normal mode - the cursor is on the next line, the indentation is correct and I'm in insert mode. I'm only worrying about single line comments (eg '#'s - as for shell, python etc).
I'm interested in how I can make this more general (particularly not dependent on my formatoptions). I'd like to have an imap for ;; but I can't seem to find a straight forward way if I want to call a function (for example, to check whether I'm currently on a comment line).
I've played around with <expr> mappings and the expression register but either I lose the indentation (cursor ends up in the first column) or the comment continues. It seems like there might be a better alternative to either reimplementing the autoindent logic or trying to delete the extra comment characters. I've also tried saving/restoring formatoptions while using normal o but leaving insert mode when there's no other content on the line deletes the indentation.
I appreciate suggestions about how I should approach this.

Disable what ever causes Vim LaTexSuite from automatically entering braces

I'm working on a paper using LaTex, and my preferred text editor is Vim. When using the LaTeX plugin from https://github.com/gerw/vim-latex-suite gives me just about everything I need when working with LaTeX.
Sadly there is one thing about the Suite that is driving me nuts. I have a habit when type braces (or quotes) to start by typing the pair (for example \text{}|) and then pressing <esc>i to place my cursor in between them \text{|}. Somewhere in the LaTeX suite there is some script or macro that automatically puts the cursor in between when I type the pair. After my muscle memory that usually leaves me with the cursor infront of the pair \text|{}.
How do I disable this 'feature'?
If I understand correctly (see my comment) you'll need to comment (or remove) from main.vim:
call IMAP ('{}','{<++>}<++>',"tex")
or change
call IMAP ('{}','{}<++>',"tex")
or you can call the line above from ~/.vimrc (or texrc or similar) - in this case the latexsuite's definition will override.

How to create a syntax file for text files?

I wish I could format pieces of text in standard text files.
I would like to select a phrase or a word, invoke a simple command, and format it with these formatting:
bold
italic
underline
red font color
yellow background color
Is that possible?
(something like syntax highlighting in vim files but in my case with selected text)
I know there is a Txtfmt plugin in vim, I tried it 2 times the last years but uninstalled it every time.
This is why:
There is no way to visual select text and format it, you have to insert a begin code in the command-line write the text and insert an end code in the command-line.
You cannot copy the text because Txtfmt plugin inserts hidden formatting codes in the text
It is too complicate to insert a begin code and end code in the command line (after invoking a general command) and the codes are too complicated
There needs to be a kind of markup inserted into your text. Vim operates on plain text, it has no separate meta data layer like a word processor. With syntax highlighting and the new conceal feature, you can partially make Vim appear to be WYSIWYG, but actually you're still operating on the raw text.
If you're fine with that limitation and want to stick with Vim for your editing tasks, I'd suggest to use an existing markup solution instead of inventing a new one from scratch. By now, there are several syntaxes to choose from, with Markdown probably a favorite. (It's used here on Stack Overflow, too!) With an existing syntax, you can leverage all the existing plugins / mappings / commands, and even some external tools (e.g. for converting to HTML).
Here is probably the simplest possible implementation of what I believe you want. It allows custom strings to be highlighted in the current buffer using the colour/style you describe. The custom strings you choose to be highlighted cannot be saved between Vim sessions.
Firstly, define the highlight group SpecialTxt for your bespoke highlighting:
au ColorScheme * hi SpecialTxt guibg=yellow guifg=red gui=bold,underline,italic
(note that this has to be done via an autocmd so that loading a new colourscheme doesn't overwrite it).
Now you can select any regular expression to inherit this colour using:
call matchadd( 'SpecialTxt', [YOUR_REGEX], 1 )
Or you could write a simple command to set the match:
command! -nargs=1 Special :call matchadd('SpecialTxt',"<args>",1)
Or create a map so that double clicking on a word sets it to this colouring:
nnoremap <silent> <2-LeftMouse> :call matchadd('SpecialTxt',expand('<cword>'),1)<CR>
Hope that helps. Apologies if it is not quite what you are after.

How do I fix the indentation of an entire file in Vi?

In Vim, what is the command to correct the indentation of all the lines?
Often times I'll copy and paste code into a remote terminal and have the whole thing messed up. I want to fix this in one fell swoop.
=, the indent command can take motions. So, gg to get the start of the file, = to indent, G to the end of the file, gg=G.
Before pasting into the terminal, try :set paste and then :set nopaste after you're done. This will turn off the auto-indent, line-wrap and other features that are messing up your paste.
edit: Also, I should point out that a much better result than = indenting can usually be obtained by using an external program. For example, I run :%!perltidy all the time. astyle, cindent, etc. can also be used. And, of course, you can map those to a key stroke, and map different ones to the same keystroke depending on file type.
The master of all commands is
gg=G
This indents the entire file!
And below are some of the simple and elegant commands used to indent lines quickly in Vim or gVim.
To indent the all the lines below the current line
=G
To indent the current line
==
To indent n lines below the current line
n==
For example, to indent 4 lines below the current line
4==
To indent a block of code, go to one of the braces and use command
=%
If you want to reindent the block you're in without having to type any chords, you can do:
[[=]]
You can use tidy application/utility to indent HTML & XML files and it works pretty well in indenting those files.
Prettify an XML file
:!tidy -mi -xml %
Prettify an HTML file
:!tidy -mi -html %
press escape and then type below combinations fast:
gg=G
1G=G. That should indent all the lines in the file. 1G takes you the first line, = will start the auto-indent and the final G will take you the last line in the file.
if you do not want to use :set paste, middle-click, set nopaste, you can also paste the content of the clipboard:
"*p
"+p
That way you don't have to leave normal mode.
if you have to paste + or * depends on how you selected the text, see :help quoteplus.
In Vim, use :insert. This will keep all your formatting and not do autoindenting. For more information help :insert.
:set paste is your friend I use putty and end up copying code between windows. Before I was turned on to :set paste (and :set nopaste) copy/paste gave me fits for that very reason.
For complex C++ files vim does not always get the formatting right when using vim's = filter command. So for a such situations it is better to use an external C++ formatter like astyle (or uncrustify) e.g.:
:%!astyle
Vim's '=' function uses its internal formatter by default (which doesn't always gets things right) but one can also set it use an external formatter, like astyle, by setting it up appropriately as discussed in this question.
vim-autoformat formats your source files using external programs specific for your language, e.g. the "rbeautify" gem for Ruby files, "js-beautify" npm package for JavaScript.
For XML files, I use this command
:1,$!xmllint --format --recover - 2>/dev/null
You need to have xmllint installed (package libxml2-utils)
(Source : http://ku1ik.com/2011/09/08/formatting-xml-in-vim-with-indent-command.html )
You can create a mapping to do this for you.
This one will auto indent the whole file and still keep your cursor in the position you are:
nmap <leader>ai mzgg=G`z
Just go to visual mode in vim , and select from up to down lines after selecting just press = , All the selected line will be indented.
For vi Editor, use :insert. This will keep all your formatting and not insert auto-indenting.Once done press escape to view the actual formatted file otherwise you'l see some garbage characters. like ^I
e.g:
public static void main(String[] args) {
^I
^I System.out.println("Some Garbage printed upon using :insert");
}

Resources