auto fold for C++ sources and headers - c++

I have heard that Vim has a built-in support of folding for the files written in various programming languages. Particularly I'm interested in cpp, h, hpp files. I would like to achieve such a behavior of Vim when all the function definitions are folded by default in every newly opened source file. I don't want to create every fold manually with zF.
I added the following lines to the end of ~/.vimrc file (which was inherited from spf13-vim distribution):
set foldenable
autocmd FileType c,cpp,h,hpp setlocal foldmethod=syntax
Unfortunately that did not resulted to the desired behaviour. All the files look just the same, and my attempt to hide the function with zc combo leads to error:
E490: No fold found
I would be glad if someone could explain how to enable folding by default in Vim 7.4.
UPD: The code above works good, but there is still an issue with the recently opened files. Say we work on the project called 'sc-client-server' and we've just appended those two lines to ~/.vimrc and now ready to get back to the last edited file:
$ vim ~/.vimrc //Modify config
$ reboot
$ vim ~/progs/sc-client-server/src/st.cpp //No fold found. BUT:
$ cp ~/progs/sc-client-server/src/st.cpp /tmp
$ vim /tmp/st.cpp //Auto fold works fine. OR:
$ cd ~/progs/sc-client-server/src/ && mv src source
$ vim ~/progs/sc-client-server/source/st.cpp //Auto fold works fine.
Is there any kind of cache or memory inside of Vim that prevents the desired file representation?
Answer
Remove all (or specific for you) files from ~/.vimviews folder.
To the off-topic voters https://meta.stackexchange.com/questions/25925/vim-questions-do-they-belong-to-stack-overflow-or-super-user/25930#25930?newreg=00a4918bba924cfa8b1d6a3e82061672

Related

Is there a way for changing text file names in a folder using C++

I am working with a bunch of txt files(thousands) on my project. Each txt file has 'csv' information on it. The problem is that each txt file has a random name and I cannot create a code for loading them in my project due to it. So, I want to rename them in a particular pattern to make easier the loading of the files in my work. I will use C++ for accomplish this task.
I put all the txt files in a folder but I cannot see a way of renaming them using C++. How can I do this? is there a way to do it? Can someone help me?
You can use std::filesystem::directory_iterator and std::filesystem::rename (c++17), as documented here.
Disclaimer
This answer validity is based on a comment where the author precised they were not bound to the C++ language (it may be worth editing the question, the C++ tag, and the OS). This solution may work for UNIX systems supporting bash, that is most Linux distributions and all releases of Apple's macOS prior to macOS Catalina (correct me if I'm wrong).
Bash command line
Using the following bash command should rename all the files in a folder with increasing numbers, that is:
toto.csv -> 1.csv
titi.csv -> 2.csv etc
It assumes the ordering is not important.
a=1; for i in *; do mv -n "$i" "$a.csv" ; let "a +=1"; done
To test it, you can prepare a test folder by opening a terminal and typing:
mkdir test
cd test
touch toto.csv titi.csv tata.csv
ls
Output:
tata.csv titi.csv toto.csv
Then you can run the following command:
a=1; for i in *; do mv -n "$i" "$a.csv" ; let "a +=1"; done
ls
Output:
1.csv 2.csv 3.csv
Explication:
a=1 declare a variable
for i in *; begin to iterate over all files in the folder
do mv will move (rename) a file of the list (that is, the variable $i) to a new name called a.csv
and we increment the counter a, and close the loop.
the option -n will make sure no file gets overwritten by the command mv
I assumed there was no specific criterion to rename the files. If there is a specific structure (pattern) in the renaming, the bash command can probably accommodate it, but the question should then give more details about these requirements :)

hg: how to exclude "*.xll" file but not xll directory

In my .hgignore file, I am trying to ignore all generated xll files. I (unfortunately) have a directory called "xll" within the domain of the repository, and I do not want to ignore the directory itself.
I have tried:
syntax: regex
\.xll$
which I thought should mean "match all that ends in '.xll'"
and
syntax: regex
*.\.xll$
which I thought should mean "match all that have at least one arbitrary character, followed by '.xll'".
With either of the above, the directory is not ignored (yay) but neither is a file foobar.xll (darn). If I use a bare "xll" with regex, or "*.xll" with glob, both the directory and the file are ignored.
This is in linux (Ubuntu 10.04.4) with hg 2.6 (TortoiseHG 2.8) (I'm observing the effect in Nautilus via the presence or absence of "X" icons).
Thanks in advance!
EDIT
(adding comments in here as they are too long to fit in a comment...)
Thanks for all the responses. Turns out I was misinterpreting some things. So:
- because I used "regex" instead of "regexp" (and I had "glob" at top of file), whatever I put on the line that referred to "xll" was being interpreted by "glob", so the line did have an effect (which made me think, incorrectly, that the "syntax: regex" line was doing what I thought it was
- by coincidence, all the files in my "xll" directory were filtered out (as they should have been) by other lines in .hgignore, and not by the "*.xll" line
- consequently, in Nautilus, the xll directory was marked as "ignored", not because the filter ignoring the entire directory, but instead because other filters were filtering all files within that directory
Bottom line, the *.xll I had under "syntax: glob" was actually filtering out files exactly as desired. The feedback in Nautilus was just different than I expected.
It's .*\.xll$, not *.\.xll$.
Using glob syntax works well for me:
syntax: glob
*.xll
When I create a directory named xll with an untracked file, I still see the file in the output from hg status:
$ mkdir xll
$ touch a.xll x.txt xll/b.xll xll/y.txt
$ echo 'syntax: glob\n*.xll' > .hgignore
$ hg status
? .hgignore
? x.txt
? xll/y.txt
Using \.xll$ with syntax: regexp also works great for me.

Using two asterisks to add a file in git

I want to add a file which has a unique file name but a long preceding path (e.g. a/b/c/d/filename.java). Normally I would add this to my repository by doing
git add *filename.java.
However I have also done this before:
git add a/b/c/d/filename*
So I tried to combine the two:
git add *filename*
but this does something weird. It adds every untracked file. I can see possible reasons for failure but they all should occur in one of the previous two commands so I don't know why this is happening.
My question isn't so much about how to add a file to a git repository with just its file name (although that would be useful).
My question is what is my misunderstanding of the * operation which makes me think the above should work.
Info:
I am using Git Bash for Windows, which is based on minGW.
You're looking at globs
(not regular expressions, which are a different pattern-matching language), and they're expanded by your shell, not by git.
If you want to see how they're going to match, just pass the same glob to another command, eg.
$ ls -d *filename.java
vs
$ ls -d *filename*
(I've just added the -d so ls doesn't show the contents of any directories that match)
Since you're using git bash, and it's possible that glob expansion behaves differently from a regular shell, try
$ git add --dry-run --verbose -- *filename*
for example: this should show you how it really expands the glob and what effect that has.
Note the -- ... if you're using globs that might match a filename with a leading -, it's important to make sure git knows it's a filename and not an option.
Unfortunately, this will only show you the files which both match the glob, and have some difference between the index and working copy.
Answer from author:
The dry run helped a lot, here is what I found:
I was forgetting about the bin folder which I haven't added, so when I performed the dry run I realised it was finding two matches: filename.java and filename.class. When I changed the glob to *filename.j* it worked.
My next step was to remove the .class and try the command again: it worked! It is still unexplained why git bash added everything when it found two matches... since the dry run behaves differently from the actual run I think there must be a bug, but I think that discussion is to be held elsewhere (unless somebody thinks it isn't a bug).
You could try with git add ./**/*.java
Note: I tested with zsh, it should also work for bash as well.

emacs drill down shortcut

I am new to emacs. In Netbeans, you can right click on any object and it will send you directly to the header or implementation file. Is there a shortcut key to do this in emacs?
You have to create a TAGS file first.
If you're on linux:
$ ctags -e -R *.h *.cpp
// this will create tags for all .h and .cpp files,
// starting from the current directory, and recursing into subdirectories.
// -e : emacs tags (as oposed to vi tags, the default)
// -R : recursive
You can also add to an existing tags file by using the --append flag. For example:
$ ctags --append -e -R *.h *.cpp /home/user/jdoe/thirdparty
// This will add to the TAGS file in the current directory
When you want to jump to a symbol definition, in emacs use M-x find-tag, or M-.. It'll ask you where the TAGS file is, and you're set. To pop out, use M-x pop-tag-mark, by default mapped to M-*.
Note: ctags is alright, but since it's not a compiler, sometimes it'll take you to the wrong place.
You can use etags to provide a similar functionality. Once your TAGS file is created, you can use the M-. shortcut that invokes (find-tag).
As with everything: Emacs gives you several ways to do something, in this case a bunch of them don't work out of the box. You can either use etags or if you need a really big hammer semantic, which is part of the cedet project. This will give you much more then simply jumping into a header file, but maybe that is what you need.

Vim C++ auto complete

How do I enable auto completion in Vim?
I tried to do this one, but I'm not proficient with the vimrc file, etc., so it didn't work out. Can you give me step by step instructions on how to do this?
Edit
I tried installing OmniCppComplete. Followed the instructions, but when I try to use it I get the following error:
Error detected while processing function omni#cpp#complete#Main..24_InitComplete:
line 24:
E10: \ should be followed by /, ? or &
Vim by default will do completion based on words in the file using Ctrl-N or Ctrl-P, which is handy for recently referenced local variables etc, and works for code in any language or even ordinary text (handy for completing difficult to spell names). However it doesn't do this semantically or with reference to what actual types you're allowed in the particular context you're writing. For this you will need to install ctags, and then in /usr/include type:
ctags -f ~/.vim/stdtags -R --c++-kinds=+p --fields=+iaS --extra=+q .
And then add this to your .vimrc:
set nocp
filetype plugin on
map <C-L> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR><CR>
set tags=~/.vim/stdtags,tags,.tags,../tags
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
That will also make Ctrl-L reload tags, and thus pick up new autocomplete tags, from the current directory.
Detailed instructions Auto complete (archive.org) Type in first few characters and press Ctrl->P(for backward search) or Ctrl->N(for forward search), list down all options available or completes it.
I use vim7.2 (auto complete was introduced in vim7) and these controls work just fine.
My favorite is clang_complete here. It's very easy to install and the default configuration in the ReadMe document works good. You don't need to generate the tags,
It automatically show the complete options when available. It also can highlight the
syntax errors.