setting inline-open in modeline in emacs - emacs

I have this in my .emacs:
(c-set-offset 'inline-open 0)
Is there a way to "unset" inline-open in a modeline so that for some files inline-open does cause an indentation?
Thanks.

You can accomplish this with file variables like you suspect. Either at the top, or at the bottom.
To do this at the top, add:
// -*- eval: (setq c-offsets-alist (assq-delete-all 'inline-open c-offsets-alist)) -*-
at the top of your file.
Alternatively, you can add it at the end of your file in a slightly different format.
// Local Variables:
// eval: (setq c-offsets-alist (assq-delete-all 'inline-open c-offsets-alist))
// End:
Note: Emacs will ask you the first time you open a file with this kind of trickery, and if you answer !, Emacs will automatically add this code to the list of things that are considered "safe" in file local variables. It will set safe-local-variable-values in your .emacs.customization.el file.
Note 2: The snippets of code are using C++ style comments, adjust appropriately if you need C comments, or some other comment scheme.

Related

How to use the same file extension with different modes?

I have files with a .new extension that contain LaTeX code (they are the output of a program that does things on the original .tex source).
In order to check them I need that they have the LaTeX syntax highlighted and that they can be opened in read-only mode to avoid introducing errors. So I put these lines in my .emacs:
(setq auto-mode-alist
(append '(("\\.new\\'" . read-only-mode)
("\\.new\\'" . latex-mode))
auto-mode-alist))
But it does not work as expected because only the first mode is applied. How can I force emacs to apply both read-only-mode and latex-mode to the same file extension?
An easy solution is to associate your file extension with a custom derived major mode:
(define-derived-mode read-only-latex-mode latex-mode "LaTeX"
"Major mode for viewing files of input for LaTeX."
(read-only-mode 1))
(add-to-list 'auto-mode-alist '("\\.new\\'" . read-only-latex-mode))
The new read-only-latex-mode does everything that latex-mode does (including running latex-mode-hook if you're already using that), but it additionally enables read-only-mode after all of the parent mode's actions have taken place.
Any other code which cares about the major mode being latex-mode should already be testing that using the standard approach of (derived-mode-p 'latex-mode) which is still true for this new mode; so in principle this approach should Just Work.
Not sure I can really provide an answer, but here's some things to consider:
read-only-mode is a minor mode, while
auto-mode-alist is meant to turn on major modes. For major modes, it makes sense that you can have only one.
You can put something like -*- buffer-read-only: t; -*- on your first line in the file (possibly behind some comments or shebangs, depending on the file type) which would turn on read-only-mode. Maybe automate this using auto-insert-alist and match the .new filename pattern.
There's some good suggestions over at https://www.reddit.com/r/emacs/comments/jqxgiz/how_can_i_make_some_files_automatically_readonly/ , namely try file local variables and use find-file-hook
Hope some of that helps.

Change emacs comment markers from ;; to //

When I am using Emacs to edit a ".s" file, I want to change the comment from ";;" to "//". I can't seem to find out how to change the comment identifiers?
For example, when I comment-region.
More information:
I appear to be in ASM-MODE which is the default mode for editing assembler files. I made sure that I was in asm-mode by
(setq auto-mode-alist
(append '(("\\.s$" . asm-mode)auto-mode-alist))
Because assembly programs typically use ; as the comment indicator, asm-mode uses this. However, for some reason I cannot figure the GNU assembler (GNU Binutils for Raspbian) 2.35.2 uses // or # or # for comments NOT a ;
Therefore, I would like to change the behaviour such that when I select a region and M-X comment-region it uses either // or # for comments. I cannot use the default comment character, I need to change it to either double-slashes // or an at symbol #
The question is really how do I go about changing the default comment character for in a mode?
Assuming that the major mode of the .s file is asm-mode, you can use the mode hook to tweak the comment start string:
(defun my/asm-comment-tweak ()
(setq-local comment-start "// "))
(eval-after-load "asm"
(add-hook 'asm-mode-hook #'my/asm-comment-tweak))
Adding the above to your init file should let you open a .s file, which will be in asm-mode. The last thing that is done by asm-mode is to run the mode hook which will call the function my/asm-comment-tweak: the function will set the buffer-local variable comment-start to the string you specified.
This pattern is very common: many problems in customizing emacs are solved in exactly the same way. You define a function that tweaks a variable and you arrange for the function to be called by the appropriate mode hook.

Collapse/expand parts of .emacs file with org-mode

I recently learned the basics of emacs' org-mode and couldn't help but imagine applying the collapse/expand concept to parts of a source file. I would like to be able to divide my .emacs file in subparts and only display headers on load, somewhat like the following:
; ERC config...
; DIRED config...
; MISC config...
Each of these would of course be headers to many lines of codes once expanded, like this:
; ERC config
(defun start-irc ()
(interactive)
(erc-tls :server "irc.freenode.net" :port 6697 :nick "foo"))
; DIRED config...
; MISC config...
So is this possible? How could I accomplish something like this with emacs 24.2?
Thanks!
As nice as org-mode is, it does require some structure, which I don't believe can be maintained the way you want in your .emacs file.
What does work well is folding-mode. Check out the information for it on the wiki page, but basically what you do is set up comments around the chunks of code you want to put in a fold, like so:
;;{{{ some folder of some kind
(a few lines)
(of lisp)
(this "code" is just filler)
;;}}}
;;{{{ a different folder
(some more elisp code)
;;}}}
And when it is folded, it will look like:
;;{{{ some folder of some kind...
;;{{{ a different folder...
Babel enables you to achieve exactly this (i.e. managing your init file in org-mode). Specifically, see: http://orgmode.org/worg/org-contrib/babel/intro.html#emacs-initialization
Myself, I make use of outline-minor-mode in my init file for vaguely similar purposes. Various things are treated as outline headings, but you can set outline-regexp as a file local variable to restrict that behaviour, and then you toggle things open and closed with outline-toggle-children (which you would bind to some convenient key). The toggle command works from anywhere in the section, not just on the heading.
I start the headings I want to be collapsed by default with ;;;; * and end my init file with:
;;; Local Variables:
;;; outline-regexp: ";;;; "
;;; eval:(progn (outline-minor-mode 1) (while (re-search-forward "^;;;; \\* " nil t) (outline-toggle-children)))
;;; End:
In your instance you could use:
;;; Local Variables:
;;; outline-regexp: "; "
;;; eval:(progn (outline-minor-mode 1) (hide-body))
;;; End:
Pretty similar in effect to Trey's suggestion, although I expect with folding you can trivially nest sections which I'm not accounting for (having no need to do so). I feel the outline approach leaves the file looking slightly cleaner, if that matters to you.
You can also take a look at the new Outshine package which works together with outline-minor-mode to make it feel more like org-mode. In (e)lisp files outshine interprets sequences of semicolons as headers so all existing code which follows standard conventions for comments becomes foldable without any changes. Many org-mode-like key bindings (like TAB to fold/unfold heading, etc) work too.

Emacs modeline at the end of file in one line

I am working on a project where some people use vi, some use emacs and some others (including gedit). The most simple yet global way (although not perfect) to enforce (at least visual) style was to add the following lines to the end of each file:
...
return 0;
}
// Editor modelines - generated by http://www.wireshark.org/tools/modelines.html
// Local variables:
// c-basic-offset: 4
// tab-width: 4
// indent-tabs-mode: t
// truncate-lines: 1
// End:
// vim:set ft=cpp ts=4 sw=4 sts=4 nowrap: cindent:
the question is: how can I convert the emacs portion in a "one-line" code (as vim can)? and yet keep it at the end of the source file (not at the top).
(Probably this can be recasted as Lisp question but I am not familiar with it)
Directory Local Variables are probably a better approach.
http://www.emacswiki.org/emacs/DirectoryVariables
http://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html
The single .dir-locals.el file will be processed by everyone, and no need for file local variables at all.
vim may well have a similar mechanism?
You can use the eval: declaration, but Emacs will ask you to confirm that it is safe to evaluate. If you tell Emacs to accept it permanently, it won't ask about that expression again (it stores it in safe-local-variable-values in the custom-set-variables section of your init file).
;;; Local Variables:
;;; eval:(setq c-basic-offset 4 tab-width 4 indent-tabs-mode t truncate-lines 1)
;;; End:
You can wrap multiple expressions in progn:
;;; Local Variables:
;;; eval:(progn (setq c-basic-offset 4) (message "hello"))
;;; End:
Or use any other constructs (I don't think there are any restrictions).
You would need to use the // Local Variables: and // End:. The rest can be made into one line as in // eval: (setq c-basic-offset 4 tab-width 4 indent-tabs-mode t truncate-lines 1).
Looks like you might be SOL:
Specifying File Variables: http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html
Variables in Emacs:
http://www.gnu.org/software/emacs/manual/html_node/emacs/Variables.html#Variables
Unless you use Phils's eval style.
(setq c-basic-offset 4 tab-width 4 indent-tabs-mode t truncate-lines 1) add this to your .emacs. If you wish to do this for specific file types you can always use the add-hook call, such as (add-hook 'c-mode-common-hook 'your-func-here) where your-func-here could be a function that simply sets those variables.
Refer to phils method of using Local Variables and eval to accomplish this with the first line of code given above. Sorry I didn't quite understand that this was only for a single file or very few files.
I'm going to turn the question around? Do you really need any file-local variables? If you use the same style throughout all source files, it might be better to define a C indentation setup and distribute this among all developers.
(defconst my-c-style
'((c-basic-offset . 2)
(c-offsets-alist
. ((substatement-open . 0)
(statement-case-open . +)
(inline-open . 0)
(arglist-cont-nonempty . (c-indent-operator-lineup-arglist-operators
c-lineup-arglist)))))
"My indentation style")
(defun my-c-mode-common-hook ()
(interactive)
(c-add-style "my" my-c-style t))
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

How to tell emacs to open .h file in C++ mode?

What lines should I add to my _emacs (on Windows) file to have it open .h files in C++ mode? The default is C mode.
Try this:
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
Whenever you open .h files, C++-mode will be used.
Another approach for using both c-mode and c++-mode as appropriate, is to use directory local variables to set the mode.
Directory variables are evaluated after the mode has been set1, so you can actually write a .dir-locals.el file for your C++ project containing this:
((c-mode . ((mode . c++))))
And Emacs will change the mode to c++-mode whenever it had initially set it to c-mode.
If you work with a mix of C and C++ projects, this makes for a pretty trivial solution on a per-project basis.
Of course, if the majority of your projects are C++, you might set c++-mode as the default2, and you could then use this approach in reverse to switch to c-mode where appropriate.
1 normal-mode calls (set-auto-mode) and (hack-local-variables) in that order. See also: How can I access directory-local variables in my major mode hooks?
2 To do so, add
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
to your .emacs file which open .h files in C++ mode by default.
If you don't want this to apply to every .h file, you can add the following to the bottom of your C++ header files.
// Local Variables:
// mode: c++
// End:
This will work for any Emacs variables that you want to set on a per file basis. Emacs ignores the leading characters, so use whatever comment characters are appropriate for the file type.
Apparently you can also put this at the top of the file:
// -*-c++-*-
to tell Emacs it's a C++ file.
I use this since I quite frequently end up on a vanilla Emacs and it works without configuring Emacs in any way.
Since I use both C and C++ regularly, I wrote this function to try and "guess" whether a .h file is meant to be C or C++
;; function decides whether .h file is C or C++ header, sets C++ by
;; default because there's more chance of there being a .h without a
;; .cc than a .h without a .c (ie. for C++ template files)
(defun c-c++-header ()
"sets either c-mode or c++-mode, whichever is appropriate for
header"
(interactive)
(let ((c-file (concat (substring (buffer-file-name) 0 -1) "c")))
(if (file-exists-p c-file)
(c-mode)
(c++-mode))))
(add-to-list 'auto-mode-alist '("\\.h\\'" . c-c++-header))
And if that doesn't work I set a key to toggle between C and C++ modes
;; and if that doesn't work, a function to toggle between c-mode and
;; c++-mode
(defun c-c++-toggle ()
"toggles between c-mode and c++-mode"
(interactive)
(cond ((string= major-mode "c-mode")
(c++-mode))
((string= major-mode "c++-mode")
(c-mode))))
It's not perfect, there might be a better heuristic for deciding whether a header is C or C++ but it works for me.
I could swear I saw this question answered appropriately already? Weird.
You want this:
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))