How can I automatically fold a long C code in Vim? - c

I regularly run into C-codes without folding. It is irritating to read them if there is no folding, particularly with long files. How can I fold them?

To fold according to syntax
:set foldmethod=syntax
If you want to do it manually on the bits you want to fold away
:set foldmethod=manual
then create new folds by selecting / moving and pressing zf
e.g.
shift-v j j zf
(ignoring the spaces)
Edit: Also see the comments of this answer for indent and marker foldmethods.

I think you may have mixed the terminology. Do you need "wrapping" or "folding". Wrapping is the one where lines that wouldn't usually fit on screen due to their length, are wrapped, i.e. shown on several consecutive lines on screen (actually, it is one line, in several lines - hard to explain, best to see in practice).
In vim wrapping is set by
:set wrap
to turn it on, and
:set textwidth=80
to determine where vim should wrap the text (80 characters is usually a nice measure).
Folding on the other hand is a completely different matter. It is the one where vim folds several lines of code (for example, a function) into one line of code. It is useful for increasing readability of code. Vim has several folding methods, you can see all of them if you
:help folding
What you are looking for, I think would be, syntax folding, but I could be wrong. I recommend reading the help page, it is not long, and very useful.

Actually, there is another very straight forward and effective way, which is using foldmethod = marker and set foldmarker to be {,}. Then the fold result would looks like:
all of the functions fold-ed. Basically, it looks like the outline in IDE. (and you can also set foldlevel=1or more, if you do not want to fold everything at the beginning)
this is what a normal function looks like when you open it with level-1 via zo.
In addition, to do folding by syntax needs a bit of extra work, and here is a good tutorial about it. But I think fold by marker={,} is quite enough, and most importantly, it's simple and neat.

I've rolled up a fold plugin for C and C++. It goes beyond what is done with syntax folding (may be it could be improved, I don't know), and leaves less noisy and not really useful things unfolded, compared to indentation and marker based folding.
The caveat: in order to have decent reaction times, I had to make some simplifications, and sometimes the result is quite messed-up (we have to type zx to fix it).
Here is a little screencast to see how the plugin folds a correctly balanced C++ source code, which is not currently being modified :(

In vi (as opposed to vim) the answer was:
:set wm=1
This sets the wrap margin to one character before the end of the line. This isn't the world's best specification with variable sized windows (it made sense with green screens when it was hard to change the size).
That means there is also an alternative way to do it in vim:
:set textwidth=30
See: VimDoc User Manual Section 25.1

The you probably want the setting
:set foldmethod=syntax
But don't put that in manually! Thats missing out on one of Vims biggest features which is having custom settings for hundreds of file types already builtin. To get that, add this to your ~/.vimrc
filetype plugin on
filetype indent on
filetype detection is mostly based on extension, in this case *.c files. See :help :filetype for more info. You can also customize these filetype based settings.

Related

Using C I would like to format my output such that the output in the terminal stops once it hits the edge of the window

If you type ps aux into your terminal and make the window really small, the output of the command will not wrap and the format is still very clear.
When I use printf and output my 5 or 6 strings, sometimes the length of my output exceeds that of the terminal window and the strings wrap to the next line which totally screws up the format. How can I write my program such that the output continues to the edge of the window but no further?
I've tried searching for an answer to this question but I'm having trouble narrowing it down and thus my search results never have anything to do with it so it seems.
Thanks!
There are functions that can let you know information about the terminal window, and some others that will allow you to manipulate it. Look up the "ncurses" or the "termcap" library.
A simple approach for solving your problem will be to get the terminal window size (specially the width), and then format your output accordingly.
There are two possible answers to fix your problem.
Turn off line wrapping in your terminal emulator(if it supports it).
Look into the Curses library. Applications like top or vim use the Curses library for screen formatting.
You can find, or at least guess, the width of the terminal using methods that other answers describe. That's only part of the problem however -- the tricky bit is formatting the output to fit the console. I don't believe there's any alternative to reading the text word by word, and moving the output to the next line when a word would overflow the width. You'll need to implement a method to detect where the white-space is, allowing for the fact that there could be multiple white spaces in a row. You'll need to decide how to handle line-breaking white-space, like CR/LF, if you have any. You'll need to decide whether you can break a word on punctuation (e.g, a hyphen). My approach is to use a simple finite-state machine, where the states are "At start of line", "in a word", "in whitespace", etc., and the characters (or, rather character classes) encountered are the events that change the state.
A particular complication when working in C is that there is little-to-no built-in support for multi-byte characters. That's fine for text which you are certain will only ever be in English, and use only the ASCII punctuation symbols, but with any kind of internationalization you need to be more careful. I've found that it's easiest to convert the text into some wide format, perhaps UTF-32, and then work with arrays of 32-bit integers to represent the characters. If your text is UTF-8, there are various tricks you can use to avoid having to do this conversion, but they are a bit ugly.
I have some code I could share, but I don't claim it is production quality, or even comprehensible. This simple-seeming problem is actually far more complicated than first impressions suggest. It's easy to do badly, but difficult to do well.

Parsing shell commands in c: string cutting with respect to its contents

I'm currently creating Linux shell to learn more about system calls.
I've already figured out most of the things. Parser, token generation, passing appropriate things to appropriate system calls - works.
The thing is, that even before I start making tokens, I split whole command string into separate words. It's based on array of separators, and it works surprisingly good. Except that I'm struggling with adding additional functionality to it, like escape sequences or quotes. I can't really live without it, since even people using basic grep commands use arguments with quotes. I'll need to add functionality for:
' ' - ignore every other separator, operator or double quotes found between those two, pass this as one string, don't include these quotation marks into resulting word,
" "- same as above, but ignore single quotes,
\\ - escape this into single backslash,
\(space) - escape this into space, do not parse resulting space as separator
\", \' - analogously to the above.
Many other things that I haven't figured out I need yet
and every single one of them seems like an exception on its own. Each of them must operate on diversity of possible positions in commands, being included into result or not, having influence on the rest of the parsing. It makes my code look like big ball of mud.
Is there a better approach to do this? Is there a more general algorithm for that purpose?
You are trying to solve a classic problem in program analysis (of lexing and parsing) using a nontraditional structure for lexer ( I split whole command string into separate words... ). OK, then you will have non-traditional troubles with getting the lexer "right".
That doesn't mean that way is doomed to failure, and without seeing specific instances of your problem, (you list a set of constructs you want to handle, but don't say why these are hard to process), it is hard to provide any specific advice. It also doesn't mean that way will lead to success; splitting the line may break tokens that shouldn't be broken (usually by getting confused about what has been escaped).
The point of using a standard lexer (such as Flex or any of the 1000 variants you can get) is that they provide a proven approach to complex lexing problems, based generally on the idea that one can use regular expressions to describe the shape of individual lexemes. Thus, you get one regexp per lexeme type, thus an ocean of them but each one is pretty easy to specify by itself.
I've done ~~40 languages using strong lexers and parsers (using one of the ones in that list). I assure you the standard approach is empirically pretty effective. The types of surprises are well understood and manageable. A nonstandard approach always has the risk that it will surprise you in a bad way.
Last remark: shell languages for Unix have had people adding crazy stuff for 40 years. Expect the job to be at least medium hard, and don't expect it to be pretty like Wirth's original Pascal.

Easy file format for niche text printing

I have ahead of me a fairly specific task, and I was hoping someone on this site can give me the benefit of their experience
I have a text file somewhere with some 17000 lines of text. This text will need to be printed very specifically on around 80 double sided pages. These pages will then be cut into several pieces, and bound into small books (hey, it's a hobby!) This means I need to have text placed very specifically on the page. (I am also toying with the idea of having text cut off mid letter in one place and continued elsewhere)
Note that I have done this before, by manually placing text using a word processor. However, the sheer magnitude of this project really requires programming. I have thought about making some PNG files (which is easy enough to do), but I do not know how nicely they will look when printed. I have also briefly looked at some standard document file formats (like doc and pdf) and it looks like it'll take a long time before I can learn these last.
Does anyone happen to have any helpful tips, or at least know the best file format to use for such a project?
Thanks
The best recommendation I'd give is to use C to parse the input and generate a latex document, which is in turn used to generate a pdf for printing. Although it might seem more complicated, latex is much more flexible when it comes to typesetting placing manually the text in a bmp file for example (basically, latex is a language that consist of a set of rules to specify where and how a text should be printed).
Paul92 mentioned LaTex which is one option I'd consider. The learning curve can be quite steep but it will undoubtedly do a nice job with your text if you're willing to fuss with it.
If you're feeling a bit more 'rough and ready' you might consider markdown. It will keep the source text a bit more readable, and there are some reasonable options for getting from markdown to a nice print out.

Accurately count number of keywords "if", "while" in a c file

Are there any libraries out there that I can pass my .c files through and will count the visible number of, of example, "if" statements?
We don't have to worry about "if" statement in other files called by the current file, just count of the current file.
I can do a simple grep or regex but wanted to check if there is something better (but still simple)
If you want to be sure it's done right, I'd probably make use of clang and walk the ast. A URL to get you started:
http://clang.llvm.org/docs/IntroductionToTheClangAST.html
First off, there is no way to use regular expressions or grep to give you the correct answer you are looking for. There are lots of ways that you would find those strings, but they could be buried in any amount of escape characters, quotations, comments, etc.
As some commenters have stated, you will need to use a parser/lexer that understands the C language. You want something simple, you said, so you won't be writing this yourself :)
This seems like it might be usable for you:
http://wiki.tcl.tk/3891
From the page:
lexes a string containing C source into a list of tokens
That will probably get you what you want, but even then it's not going to be trivial.
What everyone has said so far is correct; it seems a lot easier to just grep the shit out of your file. The performance hit of this is neglagible compared to the alternative which is to go get the gcc source code (or whichever compiler you're using), and then go through the parsing code and hook in what you want to do while it parses the syntax tree. This seems like a pain in the ass, especially when all you're worried about is the conditional statements. If you actually care about the branches, you could actually just take a look at the object code and count the number of if statements in the assembly, which would correctly tell you the number of branches (rather than just relying on how many times you typed a conditional, which will not translate exactly to the branching of the program).

Is there any reason why c blocks always have the { directly after the ^ and not on a new line?

My coding style is to always put an opening brace on a new line:
int aBoringCFunction()
{
...
Apple used to follow this style but changed to have the { on the same line as the function. When using blocks Apple code always has the { directly after the ^:
dispatch_async(dispatch_get_main_queue(), ^{
...
Is there any reason why using my style with blocks would be problematic? For example:
dispatch_async(dispatch_get_main_queue(), ^
{
...
I prefer my style but if it causes problems with blocks then I will have to reconsider it.
Clarification
This question is regarding the Blocks extension to the C language. It is not a general question about braces. The questions is whether the Blocks extension has any ramifications on code style.
Both styles are perfectly correct; it's a matter of style and preference. The only way it will be problematic is that you might be expected to adhere to Apple's convention depending on who your code is for. Hence you might have to go back and change the formatting slightly before your work is accepted.
I think the block samples are mimicking Apple's standard, that's all. You can put your braces wherever you like. Suggest a thought about switching since samples online are likely to follow Apple. And it works pretty well.
This is one of the style-related things that people have argued the most about, and at the same time one that matters the least.
Having the brace on the same line is the "K&R" style, the style that was used in C from the very beginning. Having it on a separate line is perhaps the most common nowadays.
But there is no evidence that one of the two styles are better than the other for clarity. If someone argues over one style over the other, ask then for scientific research on the matter. I have yet to see such.
The only thing that's important is that the code style is consistent throughout your programs. If working as a programmer in a team, the whole team should be using the same style.
The c complier doesn't care where you put your braces. Its style I personal hate K&R style but what really matters is the coding standards where you write your code. If its just for personal use do whatever makes the code more readable for you.
Traditionally programmers have tried to use as few lines as possible because you can only see 24 at a time on the terminals that were being used. Putting the { on its own line just wasted screen space.
Nowadays with large high resolution monitors I think this is less of an issue and I, like you, put the braces on their own line for neatness.
Different people have very different coding tastes. In general, larger projects come with coding style guidelines. KDE, for example, likes it like you do: the { on the next line. They also like spaces in if statements:
if ( this_var > 42 )
Which personally I don't see the need for. I had a co-worker once that liked to have 5 blank lines after every function. For him the visual separation was important. For me, however, I like to get as much on the screen at once as I can.
There is no wrong. There is only white-space.
My most favorite commit-log I ever wrote for a project after we agreed on a common style (that has now lasted for coming up on 10 years):
2002-04-20 00:07 hardaker
* everything:
White space, oh glorious white space.
How great our though?
The code is fine.
We agree on functionality easily.
What really troubles us?
Something we can't see.
Something between the code.
We bow down to your magnificence,
For you are everywhere,
Between everything.
Pretty nothingness you are.

Resources