Wrong indentation of comments in Emacs - emacs

In many languages, the line comment starts with a single symbol, for example # in Python and R.
I find that in Emacs, when writing such line comments, I have to repeat the comment symbol twice to make the correct indentation.
See the following example:
(setq x-select-enable-clipboard t)
;using a single comment symbol indents wrongly
;; repeating the comment symbol indents fine
(setq-default c-basic-offset 4)
With a single ; at the beginning of the line cannot get the correct indentation. How to get the correct setting? Thanks!
EDIT:
I found the solution myself. In ESS's document:
Comments are also handled specially by ESS, using an idea borrowed
from the Emacs-Lisp indentation style. By default, comments beginning
with ‘###’ are aligned to the beginning of the line. Comments
beginning with ‘##’ are aligned to the current level of indentation
for the block containing the comment. Finally, comments beginning with
‘#’ are aligned to a column on the right (the 40th column by default,
but this value is controlled by the variable comment-column,) or just
after the expression on the line containing the comment if it extends
beyond the indentation column. You turn off the default behavior by
adding the line (setq ess-fancy-comments nil) to your .emacs file.
So I put this in my .emacs:
(setq ess-fancy-comments nil) ; this is for ESS
I think for Python mode, it has a similar variable.

Your example use Emacs Lisp, in this language the standard convention is that a single ; is indented to the right, whereas two ;; is indented like code would be indented at that point. I strongly recommend that you stick to this convention, otherwise your code would stand out as being different. And three ;;; is indented to the left. Four ;;;; is left indented, and used for major sections. (See https://www.gnu.org/software/emacs/manual/html_node/elisp/Comment-Tips.html)
For Ruby, comments always indent as code, as far as I know.

The major mode should take care of this properly. If not, consider filing an enhancement request or bug report to the maintainers. Of course, "properly" might be in the eye of the beholder. You can try to make your preferences known, however. And check whether the major-mode code might already have user options for this.
Beyond that, the function that is the value of variable comment-indent-function governs this. Normally, this is set by the major mode. You can set it to any function you want (e.g. on the mode hook, so that your definition overrides the one provided by the major-mode code).
It accepts no arguments, and it returns the column you want the comment to be indented to.
Here is code that indents a comment to column 0, for example:
(defun foo () (setq comment-indent-function (lambda () 0)))
(add-hook 'SOME-MODE-HOOK 'foo 'APPEND)
For Emacs-Lisp mode, for example, you would use (add-hook 'emacs-lisp-mode-hook 'foo 'APPEND).

Related

Variable definition for Invisible Text

I'm reading about Invisible Text in the Elisp manual. It defines the variable my-symbol to add or not add ... in place of the hidden text.
;; If you want to display an ellipsis:
(add-to-invisibility-spec '(my-symbol . t))
;; If you don't want ellipsis:
(add-to-invisibility-spec 'my-symbol)
However, I don't get it. How is it that you don't use (setq my-symbol "..."). What is the difference in syntax between (setq my-symbol "...") and '(my-symbol . t).
This might be a silly question but I'm not an expert or anything in Lisp and I'm playing around with Emacs configurations.
If you were to do (setq my-symbol "...") that would just set the value of variable my-symbol to that string.
What the Elisp manual is describing is the form of a specification, that is, a Lisp data structure (in this case a list) that causes certain parts of the buffer text to be invisible. It causes that behavior because such a spec is handled by Emacs automatically.
As #jenesaisquoi said in a comment, it is the C code of Emacs that does that automatic handling of the buffer invisibility spec. To use the spec, refer to the Elisp manual, node Invisible Text.

Paragraph filling for org-mode inside latex environment

I started using org-mode to write mathematical papers so I make a heavy use of latex environments such as proof, theorem, lemma, etc. For example I often write
\begin{proof}
a very long proof follows
\end{proof}
The problem is that in org-mode the fill-paragraph (or M-q) doesn't work inside latex environments. This complicates my life because some proofs can be very long, reaching several pages when compiled to pdf, and I am unable to efficiently format them in org-mode. I couldn't find any information in the manual on options controlling paragraph filling. Is it possible to enable fill-paragraph in this case?
The problem disappears if you use an org block instead of a latex environment:
#+BEGIN_proof
...
#+END_proof
This gets exported as \begin{proof}...\end{proof}. It also lets you use org syntax inside the block, and fill paragraph works.
if you don't want to do that, maybe try visual-line-mode as a workaround.
Edit: change fill-paragraph behaviour
If you want fill paragraph to work in latex environments, you have to dig a little deeper. Filling is done by org-fill-paragraph in org.el and this function ignores latex environments by default. To change this, go to the end of the function and replace
;; Ignore every other element.
(otherwise t)
with
(latex-environment nil) ;; use default fill-paragraph
;; Ignore every other element.
(otherwise t)
If you'd rather not change the org sources, you could use advice instead, e.g.
(defun org-fill-paragraph--latex-environment (&rest args)
"Use default fill-paragraph in latex environments."
(not (eql (org-element-type (org-element-context)) 'latex-environment)))
(advice-add 'org-fill-paragraph :before-while #'org-fill-paragraph--latex-environment)
I have a command that you could bind to M-q in Org:
(defun leuven-good-old-fill-paragraph ()
(interactive)
(let ((fill-paragraph-function nil)
(adaptive-fill-function nil))
(fill-paragraph)))
Though, I don't understand either why it's not enabled by default. Maybe a question for the Org ML?

How to make flyspell bypass some words by context?

I use Emacs for writing most of my writings. I write using reStructuredText, and then transform them to LaTeX after some preprocessing since I write my citations á-la LaTeX. This is an excerpt of one of my texts (in Spanish):
En \cite[pp.~XXVIII--XXIX]{Crnkovic2002} se brindan algunos riesgos
que se pueden asumir con el desarrollo basado en componentes, los
This text is processed by some custom scripts that deals with the \cite part so rst2latex can do its job.
When I activate flyspell-mode it signals most of the citation keys as spelling errors.
How can I tell flyspell not to spellcheck things within \cite commands.
Furthermore, how can I combine rst-mode and flyspell, so that rst-mode would keep flyspell from spellchecking the following?
reST comments
reST code literal
reST directive parameters and arguments
reST raw directive contents
Any ideas?
You can set the variable ispell-parser to the value 'tex so that flyspell will ignore (la)tex sequences. To do so, you can either set it manually in each buffer like so:
M-: (setq 'ispell-parser 'tex)
or you write a little function that will do that for you. Put the following in your .emacs file:
(defun flyspell-ignore-tex ()
(interactive)
(set (make-variable-buffer-local 'ispell-parser) 'tex))
Then you can still invoke it manually, using
M-x flyspell-ignore-tex
or you could add a hook that calls that function automatically whenever you edit a file of a certain type. You would do the latter by adding the newly defined function to your auto-mode-alist. Say your filenames typically end with ".rst", then add this line to your .emacs file:
(add-to-list 'auto-mode-alist '("\\.rst$" . flyspell-ignore-tex))
As for the second part of your question: making flyspell-mode ignore larger regions, such as, e.g., reST comments, is not easily achievable. It becomes clear when you think about the way flyspell works: it checks text on a word-by-word basis. For that, flyspell-word only looks at one word at a time which it sends to an ispell process running in the background. The ispell process does the dictionary lookup and returns whether or not the current word is correct. If flyspell-word had to check every single time whether or not the current word is part of a comment or other region that should not be checked, it would be rather slow, because that would include quite a bit of searching through the buffer.
Now of course, one could approach this a little bit smarter and first find the non-comment regions etc. and then do the word-by-word checking only in those parts that are outside of those regions - but unfortunately, that's not the way flyspell is implemented.
If you can do without the "fly" part, however, ispell-mode has a mechanism to customize which regions of a buffer can be skipped. This is done via the variable ispell-skip-region-alist. But although flyspell-mode works off ispell-mode, for the reasons outlined above that variable is not used by flyspell-mode.
You can also use flyspell-generic-check-word-predicate as I explained in this question at Super User.
(aspell's tex filter may do exactly what you want - but if you want a more general solution)
Although I am using the code below to persuade flyspell to not flag certain words with numbers in them,
you can use this sort of hook to match certain context.
looking-at starts at the position you want - so you may want to search backwards for start/end of whatever context you care about.
(when "another attempt to accept certain words flyspell/ispell/aspell flags as incorrect"
(defun flyspell-ignore-WordNumber99-stuff/ag (beg end info)
(save-excursion
(goto-char beg)
(cond
((or
(looking-at "\\bWord1\\b")
(looking-at "\\bWord99Foo\\b")
)
t)
(t nil)
)
)
)
)
(add-hook 'flyspell-incorrect-hook 'flyspell-ignore-WordNumber99-stuff/ag)

How to make emacs behave closer to the regular editors?

I'm using Emacs 23.1.1 on Ubuntu with Emacs starter kit. I primarily work in the lua-mode.
Is there a way to stop Emacs being so smart about indentation? I'm used to the dumb editors, and press all the required keys manually.
I want to use two spaces per indent, tabs-to-spaces.
When I press RETURN, the new line indentation must match the previous line.
When I press TAB on the leading whitespace, the line contents must be indented by one indentation unit.
When I press TAB on the beginning of empty line, the cursor must move one indentation unit to the right.
Oh, and I'd like to get soft word wrap on 80th column and trim-trailing-spaces on save as well.
Update:
(Would put this in a comment, but it needs formatting)
If I use Thomas's solution, auto-indent on RETURN is "fixed", but TAB still indents weirdly:
local run = function(...)
x
"x" marks the spot where cursor appears after I type the first line and hit RETURN, TAB.
Emacs has a concept of modes, which means that depending on what type of file you're editing it provides special functionality that is useful for that file. Every buffer has one major mode associated and optionally a number of minor modes.
Indentation is one of the things that is typically mode-dependent. That is, you may have to configure indentation separately for every major-mode, because otherwise when you load a new file, its associated major mode may override your indentation settings. It's possible though to write a function that configures indentation and set up Emacs in a way that the function is invoked whenever a new major-mode is started.
In order to realize the settings you want, you'll need to run a few lines of elisp code. (Unfortunately your description of what should happen when you hit TAB leaves out some details, I've implemented the simplest version I could think of below -- if it's not what you want, that can be changed, of course.)
Put the following code in the file named .emacs in your home directory (~):
(setq-default indent-tabs-mode nil) ; use spaces for indentation
(defvar my-indentation-width 2
"The number of spaces I prefer for line indentation.")
(defun my-enter ()
"Inserts a newline character then indents the new line just
like the previous line"
(interactive)
(newline)
(indent-relative-maybe))
(defun my-indent ()
"When point is on leading white-space of a non-empty line, the
line is indented `my-indentation-width' spaces. If point is at
the beginning of an empty line, inserts `my-indentation-width'
spaces."
(interactive)
(insert (make-string my-indentation-width ? )))
(defun my-indentation-setup ()
"Binds RETURN to the function `my-enter' and TAB to call
`my-indent'"
(local-set-key "\r" 'my-enter)
(setq indent-line-function 'my-indent))
(defun delete-trailing-whitespace-and-blank-lines ()
"Deletes all whitespace at the end of a buffer (or, rather, a
buffer's accessible portion, see `Narrowing'), including blank
lines."
(interactive)
(let ((point (point)))
(delete-trailing-whitespace)
(goto-char (point-max))
(delete-blank-lines)
(goto-char (min point (point-max)))))
;; make sure trailing whitespace is removed every time a buffer is saved.
(add-hook 'before-save-hook 'delete-trailing-whitespace-and-blank-lines)
;; globally install my indentation setup
(global-set-key "\r" 'my-enter)
(setq indent-line-function 'my-indent)
;; also override key setting of major-modes, if any
(add-hook 'after-change-major-mode-hook 'my-indentation-setup)
This works for me in Emacs 23, although I may have missed some edge cases. However, these changes are so fundamental that I predict you will run into incompatibilities sooner or later with some major-modes that expect indentation to work they set it up. If you really want to get into Emacs it's worthwhile adapting the habits you inherited from other editors to the way Emacs does things.
For soft word-wrap there is a minor-mode called "longlines" which you can download from here: http://www.emacswiki.org/cgi-bin/emacs/download/longlines.el I haven't used it so I can't tell you how well it works.
Fixing TAB and RETURN:
(global-set-key "\t" 'self-insert-command)
(global-set-key "\r" 'newline-and-indent)
Fill column (haven't tried): say ESC x customize-var, enter fill-column, set to 80.

Emacs C-mode indent problem with Doxygen style comment

I am having a problem with doxygen style multi-line comments with emacs indent feature in c-mode. According to doxygen manual (http://www.doxygen.nl/manual/docblocks.html) the form below is accepted.
/********************************************//**
* ... text
***********************************************/
I am trying to use this format in emacs but when I tab in on the line '* ... text' the * ends up below the /** at the end of the first line like so:
/********************************************//**
* ... text
***********************************************/
Any suggestions on how to fix this? Still learning all the in-and-outs of emacs.
The reason it is indenting as such is that (by default) multi-line comments are lined up with the start of the comment on the previous line. In this case, the start of the containing comment is in column 47.
Now, how to fix it. Here's how I figured out how to fix it, the solution is at the end.
First, there's the cc-mode manual, specifically the section on customizing indentation. A useful key is C-c C-s which tells you which syntax is being used for indentation. In this case it is ((c 61)) - the c is the important part for now.
To customize it interactively, you can type C-c C-o (when the point is on the line whose indentation you want to fix). You'll be prompted for which syntax entry you want to customize (defaults to c in this case b/c that's the current syntax), then you'll be prompted for what you want to change the syntax entry to (default is c-lineup-C-comments).
Now we can look at that function to see how we might customize it to meet your needs. M-x find-function c-lineup-C-comments.
That's where it gets more difficult. You can customize the way cc-mode handles comment indentation, but what it looks like you want it to do (in this case) is to recognize that the c-comment you're in is immediately preceded by another c-comment, and that comment is the one you want to align indentation to.
How do you do that? The easiest way I can think of is to advise 'c-lineup-C-comments to recognize this special case and change the value of its first argument to be what you want. My limited testing shows this works for your example:
(defadvice c-lineup-C-comments (before c-lineup-C-comments-handle-doxygen activate)
(let ((langelm (ad-get-arg 0)))
(save-excursion
(save-match-data
(goto-char (1+ (c-langelem-pos langelem)))
(if (progn
(beginning-of-line)
;; only when the langelm is of form (c . something)
;; and we're at a doxygen comment line
(and (eq 'c (car langelm))
(looking-at "^\\(\\s-*\\)/\\*+//\\*\\*$")))
;; set the goal position to what we want
(ad-set-arg 0 (cons 'c (match-end 1))))))))
The end result of this advice should be that the argument passed into c-lineup-C-comments should be transformed from (c . 61) to (c . 17) (or something like that), essentially fooling the routine into lining up with the comment at the beginning of the line, and not the comment which you're currently modifying.
Which version of emacs are you using? My emacs 22 has this problem, but on another machine with emacs 23 does not. This is probalby due to some "electric" indentation. Try M-x describe-key RET RET and also M-x describe-mode to get a nice place to start searching for clues. There is also http://doxymacs.sourceforge.net/ but I have not tesed it personally.