I'm a C++ programmer using a setup consisting of cc-mode and CEDET and of course our beloved emacs (v24.2).
A feature I'm missing is a function that moves point fast through a list of arguments. Consider this example:
void takesManyArgs( int a1, int a2, int a3, std::pair<int,int> a4, int a5 ){
// does something nifty!
}
// [...]
takesManyArgs( b1, b2, b3, make_pair( b4, b5 ), b6 );
Where point is just before the first int. Now I'd like to an easy way to quickly move through the list of arguments, i.e. a forward-argument (and backward-argument aswell) function that moves right before the first non-whitespace character past the comma (the argument separator).
I have written a small function that does it but it's not quite the way I'd like it work:
(defun arg-forward ()
"Move point forward in the file until we hit an argument separator, i.e. comma, colon or semicolon."
(interactive)
(progn
(re-search-forward "[,]")))
In principle this function just jumps to the next comma. That's not the behaviour I want.
I'd like a function that:
,| int it will look like , |int where | marks point) |int b3 to |make_pair( int b4, int b5 ) to |int a6 where | marks point Any help from you elisp "hackers" is appreciated!
Edit: Added some clarification.
Edit2: Fixed that example "Code"
This function seems to do what you requested:
(defun arg-forward ()
"Move point forward until we hit an argument separator, the comma, colon, semicolon"
(interactive)
(condition-case nil
(let ((separator-regexp "[,:;]"))
(forward-sexp)
(while (not (or (looking-at (format "[ \t]*%s" separator-regexp))
(save-excursion (forward-char -1)
(looking-at (format "[]\"')}]*[ \t]*%s " separator-regexp)))))
(forward-sexp))
(if (looking-at separator-regexp)
(forward-char 1))
;; going forward one sexp and back puts point at front of sexp
;; essentially skipping the whitespace, but also ensuring we don't
;; jump out of a larger closing set of parentheses
(forward-sexp)
(forward-sexp -1))
(error
(beep)
(message "At end of argument list"))))
You could write a function that uses forward-sexp and checks to see if you're at one of "argument separator" or "end of argument list".
I don't seem to have an emacs handy right now, so I can't trivially check an example implementation, but with those at hand, you should be well on your way.
Untested code below:
(defun forward-argument ()
(interactive)
(let ((argument-terminator "[),]")) ;; Arguments stop at commas or close
(while (not (looking-at argument-terminator)) ;; until we're at end-of-argument...
(forward-sexp 1)))) ;; move forward
This could probably benefit from pulling the argument-terminator out into a defvar, so it's easy to make it mode-specific. It could probably benefit from having a count prefix (wrap it in a (while (> count 0) ... (setq count (1- count)) and default count to 1 if no prefix is given) and a few other things., Not to mention actually checking the code against a live emacs instead of trying to remember what arguments functions take and what they're called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With