Is there a way to reformat braces automatically with Vim? - formatting

I would like to reformat some code which looks like this :
if (cond) {
foo;
}
to
if (cond)
{
foo;
}
Since this is C code, I have been looking at cindent/cinoptions to use with = but it seems it does not deal with multiline rules.
I have been looking at formatoptionsto use with gq, and it does not seem to be possible either.
So is it possible using default Vim options or should I use a specific plugin or function ?

:%s/^\(\s*\).*\zs{\s*$/\r\1{/
Breakdown:
^\(\s*\) = capture the whitespace at the beginning of the line
.* = everything else
\zs = start replacement after this
{ = open curly brace
\s*$ = trailing whitespace before line end
\r\1{ = newline, captured whitespace, brace

I don't know if this completely solves your problem, but if this is a one-shot operation, you might want to try regular expressions:
:%s/^\(\s*\)\(.*)\)\s*{\s*$/\1\2^M\1{/
Note that ^M is a control character that is usually generated (depending on your terminal) by pressing CTRL-V followed by ENTER.
EDIT: As pointed out in the comments by Jay and Zyx, \r is a better way of inserting a line break into the replaced string. I wasn't aware of that, many thanks for the hint.

If you install Artistic Style you can do something like:
:set formatprg=astyle\ -b
Then use gq to reformat chunks of code.emphasized text
If you want this enabled every time you edit a C file,
you can add the following to your .vimrc file.
autocmd BufNewFile,BufRead *.c set formatprg=astyle\ -b

I don't know if you can do it within vim itself, but you can try the BSD indent command with the -bl option. With the cursor on the first {, you can type !%indent -blEnter.

Related

How do I replace part of a string with a lua filter in Pandoc, to convert from .md to .pdf?

I am writing markdown files in Obsidian.md and trying to convert them via Pandoc and LaTeX to PDF. Text itself works fine doing this, howerver, in Obsidian I use ==equal signs== to highlight something, however this doesn't work in LaTeX.
So I'd like to create a filter that either removes the equal signs entirely, or replaces it with something LaTeX can render, e.g. \hl{something}. I think this would be the same process.
I have a filter that looks like this:
return {
{
Str = function (elem)
if elem.text == "hello" then
return pandoc.Emph {pandoc.Str "hello"}
else
return elem
end
end,
}
}
this works, it replaces any instance of "hello" with an italicized version of the word. HOWEVER, it only works with whole words. e.g. if "hello" were part of a word, it wouldn't touch it. Since the equal signs are read as part of one word, it won't touch those.
How do I modify this (or, please, suggest another filter) so that it CAN replace and change parts of a word?
Thank you!
this works, it replaces any instance of "hello" with an italicized version of the word. HOWEVER, it only works with whole words. e.g. if "hello" were part of a word, it wouldn't touch it. Since the equal signs are read as part of one word, it won't touch those.
How do I modify this (or, please, suggest another filter) so that it CAN replace and change parts of a word?
Thank you!
A string like Hello, World! becomes a list of inlines in pandoc: [ Str "Hello,", Space, Str "World!" ]. Lua filters don't make matching on that particularly convenient: the best method is currently to write a filter for Inlines and then iterate over the list to find matching items.
For a complete example, see https://gist.github.com/tarleb/a0646da1834318d4f71a780edaf9f870.
Assuming we already found the highlighted text and converted it to a Span with with class mark. Then we can convert that to LaTeX with
function Span (span)
if span.classes:includes 'mark' then
return {pandoc.RawInline('latex', '\\hl{')} ..
span.content ..
{pandoc.RawInline('latex', '}')}
end
end
Note that the current development version of pandoc, which will become pandoc 3 at some point, supports highlighted text out of the box when called with
pandoc --from=markdown+mark ...
E.g.,
echo '==Hi Mom!==' | pandoc -f markdown+mark -t latex
⇒ \hl{Hi Mom!}

What vimrc settings control syntax highlighting of indented awk code in markdown?

I cannot get indented code to highlight in GAWK in vim markdown model
Context: I doing some literature programming in gawk. Comments are markdown syntax and code is GAWK, indented by a tab spaces.
Problem: I followed the doc at https://github.com/plasticboy/vim-markdown#options. The markdown highlights as it should but the indented code remains white and bland:
What I did: The first line of my source code is
# vim: nospell filetype=markdown :
My .vimrc contains the line
let g:vim_markdown_fenced_languages = ['awk=awk']
Which, according to the doc at SHOULD be enough to make that syntax highlight happen
Help?
That information is not enough to get vim to understand how to highlight your block of code. "Fenced" refers to code that is bounded by triple backticks as follows:
```awk
this is some awk code that would be highlighted
```
This, when combined with the let g:vim_markdown_fenced_languages = ['awk', 'sh', 'make'] etc lists, lets vim know exactly which highlighting syntax to use in a particular block.
You should also note that you don't need that particular vim plugin to get this to work; this is native vim functionality.
Edit: If you really want indentation, you can just indent the code block with the fencing:
```awk
some awk code surrounded by indented fencing would be highlighted
```
If you were really hard-pressed to avoid the fencing entirely, the only way I know of would be to go into the actual vim syntax files:
cd $(vim -Nesc '!echo $VIMRUNTIME' -c qa)
vim syntax/markdown.vim
and try to figure out a way to force a default of awk highlighting on indented code, but I wouldn't recommend it.

Remove first 4 whitespaces from line

I inherited a script I want to refactor.
for some reason the script is intended with four whitespaces.
I would like to remove leading four whitespaces from each line.
Is there any handy and fast way to do it?
Message "Try to get Package Lock..."
if waitForPackageLock("300","false")
comment "UCS: Extra check if package lock is available."
endif
Cheers
That was a difficult one.
sed 's/^ //'
Or edit your script with an editor.
vim file
:%<
: execute a command
% apply to all lines
< remove one indent

AIX: remove the last symbols (CRLF) from a file

There is a large file where the last symbols are \r\n. I need to remove them. It seems to be equivalent to removing the last line(?).
UPD: no, it's not: a file have only one line, which ends with \r\n.
I know two ways, but both don't work for AIX:
sed 's/\r\n$//' file # I don't why it doesn't work
head -c-2 # head doesn't work with negative numbers
Is there any solution for AIX? A lot of large files must be processed, so performance is important.
Usually, if you need to edit a file via a script in place, I use ed due to historical reasons. For example:
ed - /tmp/foo.txt <<EOF
g/^$/d
w
q
EOF
ed is more than a bit cantankerous. Note also that you did not really remove the empty lines at the bottom of the file but rather all of the empty lines. With ed and some practice you can probably achieve deleting only the empty lines at the bottom of the file. e.g. go to the bottom of the file, search up for a non-empty line, then move down a line and delete from that point to the end of the file. ed command scripts act (pretty much) as you would expect.
Also, if they really do have \r\n, then those are not going to be considered empty lines but rather lines with a control-M (\r) in them. You may need to adjust your pattern if that is the case.
My answer https://stackoverflow.com/a/46083912/3220113 to the duplicate question should work here too. Another solution is using
awk ' (NR>1) { print s }
{s=$0}
END { printf("%s",substr($2, 1, length($2)-1) ) }
' inputfile

Does mIRC Scripting have an escape character?

I'm trying to write a simple multi-line Alias that says several predefined strings of characters in mIRC. The problem is that the strings can contain:
{
}
|
which are all used in the scripting language to group sections of code/commands. So I was wondering if there was an escape character I could use.
In lack of that, is there a method, or alternative way to be able to "say" multiple lines of these strings, so that this:
alias test1 {
/msg # samplestring}contains_chars|
/msg # _that|break_continuity}{
}
Outputs this on typing /test1 on a channel:
<MyName> samplestring}contains_chars|
<MyName> _that|break_continuity}{
It doesn't have to use the /msg command specifically, either, as long as the output is the same.
So basically:
Is there an escape character of sorts I can use to differentiate code from a string in mIRC scripting?
Is there a way to tell a script to evaluate all characters in a string as a literal? Think " " quotes in languages like Java.
Is the above even possible using only mIRC scripting?
"In lack of that, is there a method, or alternative way to be able to "say" multiple lines of these strings, so that this:..."
I think you have to have to use msg # every time when you want to message a channel. Alterativelty you can use the /say command to message the active window.
Regarding the other 3 questions:
Yes, for example you can use $chr(123) instead of a {, $chr(125) instead of a } and $chr(124) instead of a | (pipe). For a full list of numbers you can go to http://www.atwebresults.com/ascii-codes.php?type=2. The code for a dot is 46 so $chr(46) will represent a dot.
I don't think there is any 'simple' way to do this. To print identifiers as plain text you have to add a ! after the $. For example '$!time' will return the plain text '$time' as $time will return the actual value of $time.
Yes.