Show enclosing #ifdef blocks in Emacs - emacs

Is it possible to show current #ifdef blocks in Emacs (eg in mode-line)?
For example:
#ifdef A
... | #cursor position num. 1
#ifdef !B & C
...
#else /* !B & C */
foo(); | #cursor position num. 2
#endif /* !B & C */
#endif /* A */
It should show A in mode line, if I put cursor in position 1
and show A & !(!B & C) in position 2.
I am already using hide-if-def mode. But sometimes i need to work with all #ifdef blocks.

I've not always had success with WhichFunction, but it should work with C/C++ code nicely. This customization will add a new function to the recognition scheme which will tell you when you're inside an #ifdef block.
(require 'which-func)
(which-function-mode 1)
(defun name-of-current-conditional ()
"rather inelegant coding, but it works"
(interactive)
(let (outer)
(condition-case nil
(dotimes (myv 10)
(save-excursion
(c-up-conditional (1+ myv))
(setq outer (buffer-substring-no-properties
(line-beginning-position)
(line-end-position)))))
(error nil))
outer))
(setq which-func-functions '(name-of-current-conditional))

Related

How to use HTMLIZE in a function and change the local buffer to HTMLIZE output buffer?

I'm six years into emacs and only just getting into the details. I have a hyrda in my init for browser activity, using engine-mode, browse-url, and browse-url-of-buffer. I've written a new function 'print-to-browser' that htmlizes the buffer and opens it in the default browser.
Of course browse-url-of-buffer acts on the original buffer and not htlmizes output buffer. ADD-HOOK, which I use, has a LOCAL or GLOBAL argument that toggles browse-url-of-buffer acting on both buffers or the original buffer alone, but not the new buffer alone.
Somewhere in there htmlize creates a new buffer which is probably added to the end of the buffer-list. I want either to pass last-buffer, which calls the last buffer from the selected windows buffer-list, to browse-url-of-buffer, or pass the name of the htmlized buffer to switch-to-buffer, then call browse-url-of-buffer.
Does anyone know how to do this?
Here is print-to-browser:
(defun print-to-browser ()
"Depends Htmlize. Htmlize buffer, go there, send buffer to browser"
(interactive)
(add-hook 'htmlize-after-hook 'browse-url-of-buffer nil nil)
(htmlize-buffer)
(run-hook-with-args 'htmlize-after-hook)
) ; end print-to-browser
and here is the full code block from myinit.org:
#+BEGIN_SRC emacs-lisp
(use-package engine-mode
:after hydra
:commands hydra-search/body
:config
;(engine-mode t)
;engine mode configuration
(defengine duckduckgo
"https://duckduckgo.com/?q=%s"
;:keybinding "d"
)
(defengine github
"https://github.com/search?ref=simplesearch&q=%s"
;:keybinding "h"
)
(defengine google
"http://www.google.com/search?ie=utf-8&oe=utf-8&q=%s"
;:keybinding "g"
)
(defengine google-images
"http://www.google.com/images?hl=en&source=hp&biw=1440&bih=795&gbv=2&aq=f&aqi=&aql=&oq=&q=%s"
;:keybinding "i"
)
(defengine google-maps
"http://maps.google.com/maps?q=%s"
:docstring "Mappin' it up."
;:keybinding "m"
)
(defengine stack-overflow
"https://stackoverflow.com/search?q=%s"
;:keybinding "q"
)
(defengine wikipedia
"http://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s"
;:keybinding "w"
:docstring "Searchin' the wikis.")
(defengine youtube
"http://www.youtube.com/results?aq=f&oq=&search_query=%s"
;:keybinding "y"
)
;custom function print buffer in browser
(defun print-to-browser ()
"Depends Htmlize. Htmlize buffer, go there, send buffer to browser"
(interactive)
(add-hook 'htmlize-after-hook 'browse-url-of-buffer nil nil)
(htmlize-buffer)
(run-hook-with-args 'htmlize-after-hook)
) ; end print-to-browser
:bind
("<C-m> i" . hydra-search/body)
:hydra
(hydra-search (:color blue :hint none)
"
^Browser Search or Print^
--------------------------------------------
_d_uck _g_oogle _i_mages _w_iki
_m_aps _y_outube _s_tack _h_ub
_u_rl _p_rint _h_tml
"
("w" engine/search-wikipedia "wikipedia")
("d" engine/search-duckduckgo "duckduckgo")
("h" engine/search-github "github")
("g" engine/search-google "google")
("i" engine/search-google-images "google-images")
("m" engine/search-google-maps "google-maps")
("y" engine/search-youtube "youtube")
("s" engine/search-stack-overflow "stack-overflow")
("u" browse-url "browse-url-at-point")
("p" print-to-browser "print-to-browser")
("h" browse-url-of-buffer "buffer-to-browser")
))
#+END_SRC
Presumably there are multiple simple solutions.
htmlize-buffer returns the htmlized buffer, so you can just use that as the buffer arg to browser-url-of-buffer.
(defun print-to-browser ()
(interactive)
(browse-url-of-buffer (htmlize-buffer)))
I learned this by invoking describe-function (C-h f) on these commands.
My first solution works (so far). It was only necessary to read a primer on elisp, see here: http://ergoemacs.org/emacs/elisp_basics.html
Here is print-to-browser working:
(defun print-to-browser ()
"Depends Htmlize. Htmlize buffer, go there, send buffer to browser"
(interactive)
(add-hook 'htmlize-after-hook 'browse-url-of-buffer nil nil)
(htmlize-buffer)
(switch-to-buffer
(let ((a (buffer-name)) (b ".html"))
(concat a b)))
(run-hook-with-args 'htmlize-after-hook)
) ; end print-to-browser

How to automatically align comments in different pieces of code?

I have to do a very specific task to re-do over and over again and would like to have it put permanently in my .emacs file. But I am not versed enough in emacs-lisp to manage it:
Keystroke-1, say [F8]
remember the current cursors' column position in, say, xtab
Keystroke-2, say [F9] while cursor is in some other line:
find leftmost string // in current line, if none is there, beep and stop
insert as many spaces so the // gets to previously remembered column xtab, or do nothing if cursor is already beyond xtab
search-forward for next // and place the cursor on it
I managed to assign it to a temporary keyboard macro, but have to re-record it for every changing xtab value.
The ultimate goal is that I want to align the comments in different pieces of code easily, from
int main() { // the enty function
int x = 100; // my new variable
for(int i=1; i<2012; ++i) { // loop a lot
x -= i;
}
} // end of all things
to
int main() { // the entry function
int x = 100; // my new variable
for(int i=1; i<2012; ++i) { // loop a lot
x -= i;
}
} // end of all things
Any idea how I can automate this? What do I have to put in my .emacs-file to archive this -- or similar?
As tungd said, align-regexp is good for this sort of thing.
(defun my-align-comments (beginning end)
"Align instances of // within marked region."
(interactive "*r")
(let (indent-tabs-mode align-to-tab-stop)
(align-regexp beginning end "\\(\\s-*\\)//")))
Which is like the interactive call:
M-x align-regexp RET // RET
Or for a more language-agnostic version:
(defun my-align-comments (beginning end)
"Align comments within marked region."
(interactive "*r")
(let (indent-tabs-mode align-to-tab-stop)
(align-regexp beginning end (concat "\\(\\s-*\\)"
(regexp-quote comment-start)))))
Not exactly an answer to your question, but to achieve the desired goal you can just mark the region and use align-regexp.
Here's the code:
(defvar c-current-comment-col 30)
(defun c-set-comment-col ()
(interactive)
(setq c-current-comment-col (current-column)))
(defun c-comment-to-col ()
(interactive)
(beginning-of-line)
(when (re-search-forward "//" (line-end-position) t)
(backward-char 2)
(let ((delta (- c-current-comment-col
(current-column))))
(if (plusp delta)
(insert (make-string delta ? ))
(if (looking-back
(format "\\( \\{%d\\}\\)" (- delta)))
(delete-region
(match-beginning 1)
(match-end 1))
(message
"I'm sorry Dave, I afraid can't do that.")))))
(next-line 1))
(global-set-key [C-f6] 'c-set-comment-col)
(global-set-key [f6] 'c-comment-to-col)
I've added a next-line call to the end. Now you can do
C-f6 f3 f6 M-0 f4 to align until end of buffer.
M-x align is very powerful and will automatically handle the particular example given.
However, it will also align variable declarations, which may be more than you want. In that case, you would have to customize align-region-separate or use the align-regexp answer.

C++ style in emacs : greater-than-80 column exception to the default parentheses auto-indent behavior

I have a long function declaration in C++ that I'm writing up in emacs. The indentation behavior with parenthesis doesn't make an exception for 80 columns and looks like:
std::vector<std::vector<double> > doFooBarBlahBlah(const std::map<std::pair<unsigned, std::string>, FoobarType> fooArg1,
const std::map<std::pair<unsigned, std::string>, FoobarType> fooArg2) {
Moving the argument to the next line and auto-indenting results in:
std::vector<std::vector<double> > doFooBarBlahBlah(
const std::map<std::pair<unsigned, std::string>, FoobarType> fooArg1,
const std::map<std::pair<unsigned, std::string>, FoobarType> fooArg2) {
The google C++ style guide suggests:
std::vector<std::vector<double> > doFooBarBlahBlah(
const std::map<std::pair<unsigned, std::string>, FoobarType> fooArg1,
const std::map<std::pair<unsigned, std::string>, FoobarType> fooArg2) {
Is there an emacs extension to automate indentation in a way that respects this rule?
Edited to account for column length exception
This will do the trick for you:
(defun my-c-custom-settings ()
(c-set-offset 'arglist-intro 'my-special-indent))
(add-hook 'c-mode-common-hook 'my-c-custom-settings)
(defun my-special-indent (pair)
(let* ((symbol (car pair))
(offset (cdr pair))
(regular-column (c-lineup-arglist-intro-after-paren symbol)))
(if (> (save-excursion (+ (aref regular-column 0)
(- (progn (end-of-line) (current-column))
(progn (beginning-of-line)
(skip-chars-forward " \t")
(current-column)))))
80)
'+
regular-column)))
The way to find out what setting needs be set for indentation is to move your cursor to the point you want to indent differently and do:
M-x c-set-offset
aka C-c C-o. And in this case you want to set it to '+ indicating to indent one more level than the current level. One of the settings can be a function which returns the offset.
There's a ton of information available in the manual for cc-mode on indentation, including how to customize it (I took the easy way in the sample above). As well as the documentation for c-offsets-alist.

Folding/Identifying current `ifdef block in verilog code using emacs

My work invovles browsing through long verilog codes which incorporates `ifdef blocks. My primary editor is emacs. Following is a typical example:
module Foo(
...
...
);
// Inputs, Outputs
...
`ifdef CONDITION_1
...
...
`else // CONDITION_1
...
...
`ifdef CONDITION_2
...
...
`endif //CONDITION_2
...
...
foo <= 1'b1;
...
...
`endif // CONDITION_1
As you can see foo <= 1'b1; is in the else block of ifdef CONDITION_1 Assuming that my point is on the line foo <= 1'b1; is there any way by which I could directly move to the line ifdef CONDITION_1 or fold the code so that I can see CONDITION1? I tried using backward incremental search but in that case I end up at ifdef CONDITION_2
i tried using the hide-ifdef-mode but it identifies #ifdef instead of `ifdef. These blocks do not use parenthesis. And so using C-M-u doesn't help
This will do it, although for your example above it will stop at the
`else // CONDITION_1
statement since that is what is enclosing the foo assignment:
(defun my-verilog-up-ifdef ()
"Go up `ifdef/`ifndef/`else/`endif macros until an enclosing one is found."
(interactive)
(let ((pos (point)) (depth 0) done)
(while (and (not done)
(re-search-backward "^\\s-*`\\(ifdef\\|ifndef\\|else\\|endif\\)" nil t))
(if (looking-at "\\s-*`endif")
(setq depth (1+ depth))
(if (= depth 0)
(setq done t)
(when (looking-at "\\s-*`if")
(setq depth (1- depth))))))
(unless done
(goto-char pos)
(error "Not inside an `ifdef construct"))))
The elisp constant hif-cpp-prefix controls the basic syntax that hide-ifdef-mode use. I guess that you could define it to something like the following. (Warning, this is untested, as I don't use verilog myself.)
(setq hif-cpp-prefix "\\(^\\|\r\\)[ \t]*\\(#\\|`\\)[ \t]*")
Note that this is defined using defconst rather than defvar, so the compiled version of hide-ifdef-mode might still use the original value. Loading the uncompiled file into Emacs would probably solve this.

Emacs auto compelete paren, indent and new line - how to?

In C - I want that when I type a { and then } emacs will insert a new line between them and then set the cursor in between them. For example:
int main() {
now I type } and the following happens:
int main()
{
//cursor is here
}
Edit: forgot to mention - I want emacs to know that when defining a function that it should do what was described above but when doing a for loop, or if statement for example I want it to do the following:
if (bla bla) {
type } and... :
if (bla bla) {
//cursor here
}
If you don't mind that the behaviour will be only almost, but not exactly the way you described it, there is a built-in way to do that. It's the auto-newline feature, that can be activated with the key combination C-c C-a or this line your .emacs:
(c-toggle-auto-newline 1)
The difference is that it will do the reformatting right after entering the opening brace {. When you finally enter the closing brace, it will indent it the right way, too.
You also need to set the right CC Mode style. The style "cc-mode" seems to define things the way you described it. You can activate it with the key combination C-c . and then choosing cc-mode, or the .emacs line
(c-set-style "cc-mode")
The c-mode functions are autoloaded and will therefore usually not be available while loading the .emacs file. Therefore you should wrap them in a hook for c-mode, like this
(add-hook 'c-mode-hook
(lambda ()
(c-toggle-auto-newline 1)
(c-set-style "cc-mode")))
As for the { stuff:
(define-minor-mode c-helpers-minor-mode
"This mode contains little helpers for C developement"
nil
""
'(((kbd "{") . insert-c-block-parentheses))
)
(defun insert-c-block-parentheses ()
(interactive)
(insert "{")
(newline)
(newline)
(insert "}")
(indent-for-tab-command)
(previous-line)
(indent-for-tab-command)
)
Paste the above into your .emacs. You can activate it with c-helpers-minor-mode.
Edit: The above inserts everything by just pressing {. The script below should do it if you type {}:
(defun insert-latex-brackets (opening closing) ; prototype function for all enclosing things
(interactive)
(insert opening)
(insert " ")
(insert closing)
(backward-char (+ 1 (length closing )))
)
(defun check-char-and-insert (char opening closing)
(interactive)
(if (equal char (char-to-string (char-before (point))))
(progn (delete-backward-char 1)
(insert-latex-brackets opening closing))
(insert char)
)
)
(local-set-key (kbd "}") 'check-char-and-insert)
One last note: You could try using yasnippet, which can be a real time saver used properly.