Change indentation with Emacs minor mode - c++

I have a CS class that requires (or at least strongly suggests) 8 spaces for C++ indentation. I normally use 2, so this is quite different for me.
I have until recently been just toggling the indent code in my .emacs and running eval-buffer, but that seems like a poor solution with a programmable editor.
So I am wondering: how might I go about creating a minor Mode (or is there a better function for this?)? I'd like to be able to enable it with M-x comp-mode or something similar.
I have seen minor modes, but they seem to instead focus on key mappings. Perhaps I am looking at the wrong Emacs feature.
Perhaps I can extend the C++ mode to create a comp-mode with different indentation settings?

You could probably do this with a minor mode, but an easier solution is to use directory variables. Create a file called .dir-locals.el in the directory containing your coursework and put something like this in it:
((c++-mode . ((indent-tabs-mode . nil)
(c-basic-offset . 8))))

Related

Enforcing coding styles in Visual Studio and VIM

I work with a medium sized team of developers, with half being Linux developers using VIM on Ubuntu and MacVIM on OSX, and the other half being Windows developers using Visual Studio 2010 or later.
A fair bit of time has been wasted in the past when handling things like SVN operations failing due to mixed line endings, or changes to code reviews due to a mix of hard-tabs versus spaces-as-tabs (and sometimes of varying lengths, ie: 4 spaces vs 2 spaces vs 8 spaces, etc), and I would like to put an end to it.
The plan is to adapt a common coding style we've designed, which is almost identical to the Linux Kernel coding style. For all developers, we could require them to run their code through the checkpatch.pl script used by Linux kernel devs, but our code includes C, C++, and C#, so we would need to generalize the rule checker script beyond just ANSI C.
Is there a generic way to implement a rule set for VIM, and another for Visual studio? We'd like to generate a script that checks entire files, which could be hooked into our version control system so that it's run on code before commits complete, and perhaps as a run-time script to enforce the style as coders type?
Thank you.
EditorConfig seems to do exactly what you want in Vim, Visual Studio, and a lot of other editors and IDEs.
The run-time "script" is the best first-line of defense. In this case, it will be various Vim and Visual Studio settings to help enforce your code style. That alone will catch quite a few problems. Keep in mind, this won't catch everything, but will encourage the coding style you want.
I've worked across Linux & Visual Studio in a team before (and sometimes by myself). The whole Tabs/Spaces issue drove me nuts as there would be wholesale groups of lines that were either shifted WAY over or not enough. To solve this, I ended up using these three settings in Vim (also set similar values in Visual Studio), thus catching one class of issues at the root.
Vim
set expandtab
set shiftwidth=4 " Mainly for if/for/while/general {} block indentation. 4 spaces.
set softtabstop=-1 " Allows us to use the Tab key and have it act like shiftwidth.
Visual Studio
Insert spaces when Tab key is pressed.
Shift 4 spaces on indent inside code block
They key is getting rid of the Tab characters, or at least having both systems use the SAME SETTINGS (i.e. both using Tab with the same values or SPACEs substituting as Tabs)
Something to watch out for:
Someone copying a file from one Operating System to a different one and then checking the file into SVN on that machine. SVN will blindly commit, say, a DOS line-ending file from a UNIX system. You want to checkout/commit files on the same system only. Otherwise, checking out/editing/committing files all on the same OS should present no issues, as SVN can convert the line endings upon checkout. You can "fix" this by loading a file into Vim and then converting the line-endings to the particular OS you want by typing ":set fileformat=dos" (if you want to change to Windows-style), ":set fileformat=unix" (for unix style), or finally ":set fileformat=mac" for Mac.
As far as the code style goes, as you probably already know, both Vim and Visual Studio offer lots of flexibility there. While I cannot give you the specific settings for Vim, the options to look at are
autoindent
cindent
cinoptions (implied from cindent)
cinkeys (implied from cindent)
comments (default is probably fine, but here for thoroughness)
So, you will want
set autoindent
and cindent should be automatically set when editing a C or C++ file. The defaults for cinoptions and cinkeys are ok for me, but I have tweaked them in the past when working with a different group.
Don't forget about using the '=' command over a selected range of lines to reformat the code! This can be very handy!
I shy away from the completely automatic SVN backend method because it may take longer than you expect to get it right, and when it screws up, it will probably take more time out of your day than you expect as well. After all, you really just want to be productive, right?.
Discipline up front is key!

Vim Folding with RainbowParentheses

So, I've looked everywhere for a good rainbow parentheses plugin that will give different level parentheses different colors. I really like the couple that I've found, because they both do a good job of customizability while highlighting the right thing. It supports more than parentheses; chevrons, braces and brackets all get highlighted, which I really like.
It seems like there are quite a few plugins for this!; I'm currently using oblitum's because his is optimized for dark backgrounds (I often work straight from the shell).
So, following the tip at the github for that plugin, I have the "always on" snippet in my .vimrc. But when the always on block is above "syntax enable" it doesn't show {} as being highlighted for cpp files. When the always on block is below syntax enable, folding doesn't work. I think its the nature of the plugin that makes it do this; it goes though the file and adds coloration information. I notice that if I use the command :syntax enable after I've loaded the file when its not recognizing folds, then it does recognize the folds. But at this point, it removes the coloration that rainbow parentheses put on it.
In my .vimrc, I have the follow pertinent lines:
syntax enable
set foldmethod=syntax
set foldenable
set foldlevel=100
let g:rainbow_operators=2
au FileType c,cpp,objc,objcpp call rainbow#activate()
I think that, from looking at syntax files that come with vim, such as c.vim, you can see that certain blocks are annotated as folding. I bet that if you could just write a regex based upon it, you could identify characters as syntactic groups. Then you could just define a colorscheme for it. In fact, the rainbow plugin is actually calling "syn region" commands, so I think that this route is very doable, I'm just not that knowledgable with vim scripting.
Can anybody help me modify possibly the plugin or come up with a script or something that achieves both?
Sorry the lateness, I've tried to solve it at Fix disabled folding (issue #2)
I dimly remember having had the same or a similar problem.
Also XML code highlighting was broken IIRC.
I put 'always on' off, and activated the colored parentheses only when I needed it.
So my working solution was just a shortcut to toggle the plugin on and off.

C++ Keywords not Colored in Emacs

I have been using emacs for a while for mainly python programming, and have started C++ coding with it. When I open a c++ file, it opens without problems with c++-mode. The background and foreground colors are normal for the theme I have with color-theme, but keywords and strings are not colored differently. Below is the code in my .emacs to initialize color-theme.
(add-to-list 'load-path "D:\\emacs\\color-theme-6.6.0")
(require 'color-theme)
(color-theme-initialize)
(setq color-theme-is-global t)
(color-theme-hober)
I have not put in any code for c++. Any ideas?
Edit: I tried turning off color-theme to see if at least then there would be some coloring, and there was not, even after ensuring font-lock-mode was on. Also, this is GNU Emacs 23.1.1
Place the cursor over a keyword and do M-x describe-face. The face should be identified as font-lock-keyword-face and the description of the face given. At that point it should be easier to determine whether the keyword has the wrong face, or the face just has a default appearance. You could also double-check that font-lock-mode is on with describe-mode.
I finally got syntax highlighting by removing a folder called site-lisp from the folder d:/emacs. My Emacs installation is in d:/emacs/emacs-23.1, and somehow it was reading from these files. So, removing this folder forced Emacs to use the correct ones, I think.
(font-lock-mode) should help (with non negative argument to make sure it's turned on)
Generally this should work straight out of the box on a standard install - to verify start emacs with the "-q" option to avoid loading stuff from your init file. I have verified this with a quick install (on XP Pro) of the official 23.2 binaries. Here's the output: (apparently can't post images due to low reputation - the link is img444.imageshack.us/img444/2680/46117077.png).
If this displays code as you expect, then there's an issue with your init file - I suggest using the standard approach of commenting everything out and selectively adding things back in, until you come across the offending line(s).

How can I refactor C++ source code using emacs?

I'm interested mostly in C++ and method/class name/signature automatic changes.
In recent Emacs versions (24), Semantic is able to this.
Possibly activate semantic mode M-x semantic-mode RET.
Bring up the Symref buffer with C-c , g.
Press C-c C-e to open all references.
Rename with R.
If you can program in elisp, you can look to combination of cedet + srecode from CEDET libraries - it provide all instruments for this task - find callers of functions, get signature, etc. But you need to create refactory tool yourself, using these instruments
I do this a lot, so I'm axiously awaiting other replies too.
The only tricks I know are really basic. Here are my best friends in Emacs when refactoring code:
M-x query-replace
This allows you to do a global search and replace. You'll be doing this a ton when you move methods and commonly-accessed data to other classes or namespaces.
C-x 3
This gives you a display with two buffers side-by side. You can then proceed to load different files in them, and move your cursor from one to the other with C-x o. This is pretty basic stuff, but I mention it because of how powerful it makes the next one...
C-x (
(type any amount of stuff and/or emacs commands here)
C-x )
This is how you define a macro in emacs. Any time you find yourself needing to do the same thing over and over to a bunch of code (and it is too complex for query-replace), this is a lifesaver. If you mess up, you can hit C-g to stop the macro definition, and then undo (C-_) until you are back to where you started. The keys to invoke the macro are C-x e. If you want to do it a bunch of times, you can hit Esc and type in a number first. Eg: Esc 100 C-x e will try to invoke your macro 100 times.
(Note: On Windows you can get "Meta" by hitting the Esc key, or holding down Alt).
The current (2022) state of the art is, I would say, using emacs lsp-mode with a suitable language server.
With the clangd or ccls, which provide the "language server protocol" (lsp) and connect to lsp-mode, you can refactor names with:
M-x lsp-rename
To simplify this setup, I'd recommend using Spacemacs with c-c++ and lsp layers (and using clangd).
For somewhere in between refactoring tools and simple regex, since Emacs 22 you can embed arbitrary elisp expressions in your replacement text, which allows you to do incredibly powerful text manipulation. Steve Yegge wrote a good article on this a while ago.
A friend of mine was playing with xrefactory and said it worked pretty well. It isn't cheap though.
Build cscope symbols.
lookup the symbol you want to refactor.
get into the cscope window, and start a macro after placing cursor on first occurence
ret
c-f your symbol start
navigate to start of your symbol
modify the word
c-x o (back to cscope)
n (for next cscope symbol)
you have to just c-x c-e now
I totally agree that find-and-replace work fine. However , a really nice feature of cedet is 'semantic-symref-list'.
With the cursor on a method, run this command, and you will be presented with a buffer that lists all of the places in your code that reference this tag.
You can still use find-and-replace tricks, and this will confirm that you have changed all the references.
I've been using cquery for my C++ completion which uses Microsoft LSP for IDE <-> Tool communication. cquery server satisfies the requests of the LSP protocol using a clang backend.
lsp-emacs is the package that sits between emacs and the cquery backend (cquery-emacs) which exposes an lsp-rename function. As a completion system, cquery has been very reliable and fast by the way, highly recommended.
Give it a try, follow the getting-started guide on the cquery github:
https://github.com/cquery-project/cquery/wiki/Emacs
Once you've got cquery setup:
Hover your cursor over an identifier (class, var, whatever) you'd like to rename.
M-x lsp-rename
Enter the new name for the identifier.
Do C-x s (save some buffers), which will prompt you to save
all the buffers that were touched by the refactor.
You should probably go through all modified buffers and check what was done after refactoring with any tool/language.

Hide Comments in Code in Unix Environment

I work in a Unix environment with the typical Unix tools (emacs, vim, gvim, sunstudio, etc)
My project has huge gross boilerplate comments on every method. It makes the files thousands of lines long, with a couple hundred lines of actual code. I may be exagerrating a bit but you get the idea. I am looking for a way when viewing these files to hide (not remove) all comments so I can quickly go through the code. C++ comments '//' only.
It all depends on which editor you use. In vim, you can enable folding with :
set foldenable
Then, you'll be able to use different of folding methods, for mainstream languages, you can set :
set foldmethod=syntax
which will enable syntax folding.
There are half a dozen folding methods, I think the best would be to read
help folding
which should answer everything.