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

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.

Related

Function Browsing In Spacemacs And CIDER

In Spacemacs, with an active CIDER REPL, is there a way to browse and jump to the functions in the current clojure-mode buffer?
I have tried cider-browse-ns. However, that appears to just display the functions and variables in the current namespace, along with their docstrings. The list cannot be used to jump directly to the function/var in the source code. I am also aware that g d will jump directly to the definition of the function under point. So the pieces of what I am looking for seem to all be available, I just cannot find how to wire them together.
An analogy to what I am looking for is IntelliJ's Structure sidebar.
It would be awesome if IntelliJ's Navigate -> Symbol functionality was possible as well. Searching for the function name, using /, comes pretty close (albeit without the handy fuzzy matching).
would SPC s j (help-jump-in-buffer) be what you search ?
Pressing backslash then S \s will help you jump to the definition.
Here is the list of the available commands in browse-ns. But since Spacemacs puts you in evil-mode by default, you should precede each command by a \ which temporarily disables it.

Can you save your Clojure REPL's state (or, effectivelly, can you program complex programs using REPL?)

After defining variables, functions, etc., can you save what you have done on the REPL too an text .clj file?
most people work with the repl through an editor such ad Eclipse/Emacs/vim and that editor has the ability to save the repl, though without some diligence on the developers part this will likely be an incomplete record of what happened. Some of the state of the repl may have come from loading files etc which will be in a different state.
So the short answer is typically not.
In Linux (mine = Ubuntu 16.04.2 LTS) if you are using lein then check for .lein (hidden directory) and look for repl-history. You should find the commands that you have typed or pasted into the REPL. This can be a source for later edit - I use geany...
I am answering the parenthetical part of your question. For me, the Clojure REPL is very useful for testing functions and proving out concepts that take no more than a few lines. I will often put hooks in a module that is not the main, just so I can load a file and run it through a couple of functions. I can also do this from main using the same mindset; that is write a debug function.
I found the Eclipse plugin to be quite useful, but I do not use it much these days, mostly Vim and running the module with one or more special functions and running the main. I don't know of any way to save REPL state.

Howto organize Vim buffers, windows and tabs when working with many files

I used VIM whole my life but recently I am a bit tired of it because I am lost in buffers, windows, and tabs when working simultaneously with 20 files or so in a big project (with 500k LOC, and hundreds files).
Whenever i do :make, :grep, etc, new buffers are jumping out in the current window.
The same happens for the tags. At some point this starts to be very confusing because I really have to focus where things are in a VIM.
What are a proven and easy ways to control this behavior?
Use :hide to get rid of all windows unless you really need them open.
I'm not sure why tags are creating a new window for you, CTRL+] should re-use the current window.
nnoremap + 4<C-W>+ and nnoremap - 4<C-W>- make it much easier to resize windows, along with the standard <C-W>_ and <C-W>|.
Get a 22" monitor (minimum) and use :vsplit to show files side by side. I find this is even more important than having two smaller monitors.
Use <C-W>L, <C-W>H etc to move windows around. Don't forget :tab sp to open the current file (or a new one) in a new tab.
:map <LEFT> <C-W>h and :map <RIGHT> <C-W>l, etc make it much easier to move between windows. :map <C-LEFT> :tabprev<CR> and :map <C-RIGHT> :tabnext<CR> make it much easier to move between tabs.
And finally, if you need to have 20 files open regularly, this could be a sign that your code is poorly organized. If possible, features should be contained within a single file, then you just need to focus work on one feature at a time.
I tested out Eclim http://eclim.org/ a while ago for a friend. Basically, it lets you run Eclipse in a headless mode while using vim for editing and so on. With the extension, it allows Vim to draw on all the strengths of both worlds, adding for instance Eclipse's project tree to your favourite editor!
Installation was a bit daunting back then, but once I had it up and running, it was really smooth and quite a brilliant solution. Try it out, I'm pretty sure you won't be disappointed. And the installation is probably easier now. :)
Oh, I should also mention that there are several Eclim-setups. You can have headless Eclipse with vim as your primary interface (as I first mentioned), you can have a headed Eclipse and Vim, so that you can easily switch back and forth (in the same project no less), or you can have Vim integrated into Eclipse itself.
Run multiple vims. I use "konsole" on my Linux machine. It allows me to open many tabbed linux terminal sessions in one window. I can double click the tabs to name them, e.g. "models", "views", "controllers", etc. In each of these tabbed linux terminals, I'll have a vim process running that has usually 2 or 3 files open at a time.
Another option is to find and IDE that has Vim mode, so you can still use most of your key commands.
As a longtime vim user, it pains me to say it, but--it might be time for you to graduate to a full-fledged IDE. You can still use vim as your editor in most cases, but the IDE will handle file management and navigation for you, and probably will simplify your make and grep workflows (e.g., structural search beats the pants off of grep). What language are you working on?
Vim-CtrlSpace lets you organize Tabs, Buffers, Sessions (workspaces) + fuzzy search.
It is quite suitable to work on large projects. That's how I actually come up with it.
Before, I used 'jlanzarotta/bufexplorer.git' and 'xolox/vim-session'
You can check the demo on YouTube.

Easy ways to try out and test Lisp syntax?

Clojure has introduced me to the concept of Lisp syntax, and I'm interested, but it's a pain to get the Clojure repl set up and use it on different machines. What other resources are there out there for actually on-the-fly testing and playing with Lisp syntax?
I'm imagining something like a website where you can input rudimentary code, or a browser add-on, or even just a standalone application that steps you through Lisp (something that runs on Linux/Ubuntu).
Haven't been able to find anything like that to start me off in a simple/accessible way.
The SISC Online REPL is exactly what you need. It accepts Scheme syntax, which is a variant of Lisp.
For a standalone app I like PLT Scheme because it seems to work the same on every platform I've tried. I was previously using MIT Scheme on Ubuntu, but decided to switch when I bought a new machine with 64-bit Vista installed.
At the risk of losing all of my rep points, try newlisp.
I've used LispBox in the past. Easy to set up and get going, but I have to admit that Emacs is second nature to me. If you're unfamiliar with that, you may can use another editor, but getting intimate with Emacs will help you live comfortably in Lispville.
It's not hard to get to a Clojure REPL nowadays.
Go to http://build.clojure.org/ and download clojure.jar.
Install a JVM.
java -jar clojure.jar
This should work on any machine that has a JVM installed.
For more fun, install rlwrap and use rlwrap java -jar clojure.
For learning Lisp the LispWorks personal edition is fine: LispWorks downloads. There are versions for Mac OS X, Windows, Linux and FreeBSD. All have the same user interface capabilities and this includes an editor and listener - plus lots of other tools. On Linux and FreeBSD in currently (LispWorks 5) uses X11/Motif for the GUI - this will change in a future version (LispWorks 6) to GTK. So to run it now under Linux, you need to have the Motif lib installed. Other than that using it is relatively painless. There are some restrictions to it (only 5 hours runtime, then you need to save and restart, ...) and the full version is commercial. But for learning some Lisp basics, it is quite good.
Franz has an online REPL for Allegro Common Lisp.
http://www.franz.com/products/allegrocl/prompt/
codepad.org is a nice simple online way to enter and run code (in many different languages, including Scheme). I use it all the time for testing out snippets of code to use in SO answers.
I won't edit Lisp code without an editor that does what Emacs will do with the following configuration:
(define-key lisp-mode-shared-map "[" 'insert-parentheses)
(define-key lisp-mode-shared-map "]" 'move-past-close-and-reindent)
The former inserts balanced parentheses. If you give it a numeric prefix argument, it inserts that many nested pairs. By default, it inserts one. If you have a text region marked, it encloses that region in the innermost inserted pair. That means that you'll never open a parenthesis that's not closed.
The latter is harder to explain, as it's used less frequently. It's more of a navigation command than an insertion command. It confirms that you're done editing the current form and moves the cursor up, out, and past it, preparing for the next likely insertion.
With these keys bound, one no longer needs to use the Shift key to access the parentheses. Also, this leaves the parentheses keys bound as normal, for when sexp repair or a literal parenthesis character is required. I stole the bracket keys because they're used so infrequently in Emacs Lisp and Common Lisp. The bracket characters are still accessible with meta key bindings:
(defmacro make-key-inserter (def)
"Substitute for `self-insert-command'."
`(lambda (arg)
(interactive "*P")
(insert-char ,def (prefix-numeric-value arg))))
(define-key lisp-mode-shared-map "\M-[" (make-key-inserter ?\[))
(define-key lisp-mode-shared-map "\M-]" (make-key-inserter ?\]))
It's not essential to use Emacs, but don't settle for less with another editor that can't at least match this capability. There's also a whole family of commands for navigating and manipulating the sexp tree as a tree. Understanding why that's valuable will require you to fumble around for a while until you stop seeing syntax and start seeing the tree.
Since you're using Ubuntu, I'd just install some of the packages and give them a try.
Common Lisp: apt-get install clisp
Scheme: apt-get install drscheme
These aren't the only packaged implementations, but maybe the easier to get started with. You'll be able to play at a REPL and also run your own scripts through the interpreter.
BioBike provides a full Common Lisp evaluator through the web (with extras like a knowledge representation system, biocomputing, and an alternative visual langauge as well).
If you just want to play with LISP, interactively, quickly, GNU Emacs has a LISP interpreter built in, and listening in the *scratch* buffer. Type an S-expression, position immediately after it, and then hit Ctrl-J to evaluate it. Or <ESC>: will put an Eval: prompt in the minibuffer, accept an S-expression, and evaluate it.
You can define functions, using defun, and test things that way. You have access to ALL of the GNU Emacs built-in functions, and anything you have loaded. If you want to keep things around, you can put them in your .emacs file.
https://github.com/fogus/himera
was very easy for me to setup on a https://www.nitrous.io virtual box. Makes a nice web interface.
Downloading and running clojure-1.6.0.jar on my windows (XP) box was as easy as using this script to run the REPL :
java -cp clojure-1.6.0.jar clojure.main

C++ vim IDE. Things you'd need from it

I was going to create the C++ IDE Vim extendable plugin. It is not a problem to make one which will satisfy my own needs.
This plugin was going to work with workspaces, projects and its dependencies.
This is for unix like system with gcc as c++ compiler.
So my question is what is the most important things you'd need from an IDE? Please take in account that this is Vim, where almost all, almost, is possible.
Several questions:
How often do you manage different workspaces with projects inside them and their relationships between them? What is the most annoying things in this process.
Is is necessary to recreate "project" from the Makefile?
Thanks.
Reason to create this plugin:
With a bunch of plugins and self written ones we can simulate most of things. It is ok when we work on a one big "infinitive" project.
Good when we already have a makefile or jam file. Bad when we have to create our owns, mostly by copy and paste existing.
All ctags and cscope related things have to know about list of a real project files. And we create such ones. This <project#get_list_of_files()> and many similar could be a good project api function to cooperate with an existing and the future plugins.
Cooperation with an existing makefiles can help to find out the list of the real project files and the executable name.
With plugin system inside the plugin there can be different project templates.
Above are some reasons why I will start the job. I'd like to hear your one.
There are multiple problems. Most of them are already solved by independent and generic plugins.
Regarding the definition of what is a project.
Given a set of files in a same directory, each file can be the unique file of a project -- I always have a tests/ directory where I host pet projects, or where I test the behaviour of the compiler. On the opposite, the files from a set of directories can be part of a same and very big project.
In the end, what really defines a project is a (leaf) "makefile" -- And why restrict ourselves to makefiles, what about scons, autotools, ant, (b)jam, aap? And BTW, Sun-Makefiles or GNU-Makefiles ?
Moreover, I don't see any point in having vim know the exact files in the current project. And even so, the well known project.vim plugin already does the job. Personally I use a local_vimrc plugin (I'm maintaining one, and I've seen two others on SF). With this plugin, I just have to drop a _vimrc_local.vim file in a directory, and what is defined in it (:mappings, :functions, variables, :commands, :settings, ...) will apply to each file under the directory -- I work on a big project having a dozen of subcomponents, each component live in its own directory, has its own makefile (not even named Makefile, nor with a name of the directory)
Regarding C++ code understanding
Every time we want to do something complex (refactorings like rename-function, rename-variable, generate-switch-from-current-variable-which-is-an-enum, ...), we need vim to have an understanding of C++. Most of the existing plugins rely on ctags. Unfortunately, ctags comprehension of C++ is quite limited -- I have already written a few advanced things, but I'm often stopped by the poor information provided by ctags. cscope is no better. Eventually, I think we will have to integrate an advanced tool like elsa/pork/ionk/deshydrata/....
NB: That's where, now, I concentrate most of my efforts.
Regarding Doxygen
I don't known how difficult it is to jump to the doxygen definition associated to a current token. The first difficulty is to understand what the cursor is on (I guess omnicppcomplete has already done a lot of work in this direction). The second difficulty will be to understand how doxygen generate the page name for each symbol from the code.
Opening vim at the right line of code from a doxygen page should be simple with a greasemonkey plugin.
Regarding the debugger
There is the pyclewn project for those that run vim under linux, and with gdb as debugger. Unfortunately, it does not support other debuggers like dbx.
Responses to other requirements:
When I run or debug my compiled program, I'd like the option of having a dialog pop up which asks me for the command line parameters. It should remember the last 20 or so parameters I used for the project. I do not want to have to edit the project properties for this.
My BuildToolsWrapper plugin has a g:BTW_run_parameters option (easily overridden with project/local_vimrc solutions). Adding a mapping to ask the arguments to use is really simple. (see :h inputdialog())
work with source control system
There already exist several plugins addressing this issue. This has nothing to do with C++, and it must not be addressed by a C++ suite.
debugger
source code navigation tools (now I am using http://www.vim.org/scripts/script.php?script_id=1638 plugin and ctags)
compile lib/project/one source file from ide
navigation by files in project
work with source control system
easy acces to file changes history
rename file/variable/method functions
easy access to c++ help
easy change project settings (Makefiles, jam, etc)
fast autocomplette for paths/variables/methods/parameters
smart identation for new scopes (also it will be good thing if developer will have posibility to setup identation rules)
highlighting incorrect by code convenstion identation (tabs instead spaces, spaces after ";", spaces near "(" or ")", etc)
reformating selected block by convenstion
Things I'd like in an IDE that the ones I use don't provide:
When I run or debug my compiled program, I'd like the option of having a dialog pop up which asks me for the command line parameters. It should remember the last 20 or so parameters I used for the project. I do not want to have to edit the project properties for this.
A "Tools" menu that is configurable on a per-project basis
Ability to rejig the keyboard mappings for every possible command.
Ability to produce lists of project configurations in text form
Intelligent floating (not docked) windows for debugger etc. that pop up only when I need them, stay on top and then disappear when no longer needed.
Built-in code metrics analysis so I get a list of the most complex functions in the project and can click on them to jump to the code
Built-in support for Doxygen or similar so I can click in a Doxygen document and go directly to code. Sjould also reverse navigate from code to Doxygen.
No doubt someone will now say Eclipse can do this or that, but it's too slow and bloated for me.
Adding to Neil's answer:
integration with gdb as in emacs. I know of clewn, but I don't like that I have to restart vim to restart the debugger. With clewn, vim is integrated into the debugger, but not the other way around.
Not sure if you are developing on Windows, but if you are I suggest you check out Viemu. It is a pretty good VIM extension for Visual Studio. I really like Visual Studio as an IDE (although I still think VC6 is hard to beat), so a Vim extension for VS was perfect for me. Features that I would prefer worked better in a Vim IDE are:
The Macro Recording is a bit error prone, especially with indentation. I find I can easily and often record macros in Vim while I am editing code (eg. taking an enum defn from a header and cranking out a corresponding switch statement), but found that Viemu is a bit flakey in that deptartment.
The VIM code completion picks up words in the current buffer where Viemu hooks into the VS code completion stuff. This means if I have just created a method name and I want to ctrl ] to auto complete, Vim will pick it up, but Viemu won't.
For me, it's just down to the necessities
nice integration with ctags, so you can do jump to definition
intelligent completion, that also give you the function prototype
easy way to switch between code and headers
interactive debugging with breaakpoints, but maybe
maybe folding
extra bonus points for refactoring tools like rename or extract method
I'd say stay away from defining projects - just treat the entire file branch as part of the "project" and let users have a settings file to override that default
99% of the difference in speed I see between IDE and vim users is code lookup and navigation. You need to be able to grep your source tree for a phrase (or intelligently look for the right symbol using ctags), show all the hits, and switch to that file in like two or three keystrokes.
All the other crap like repository navigation or interactive debugging is nice, but there are other ways to solve those problems. I'd say drop the interactive debugging even. Just focus on what makes IDEs good editors - have a "big picture" view of your project, instead of single file.
In fact, are there any plugins for vim that already achieve this?