There are a number of useful variables to control TAB key indentation and completion in Emacs (R) code chunks, when using ESS mode.
ess-tab-complete-in-script first indents lines and, if there is nothing to indent, autocompletes the word.
"With great power, comes great responsibility", so, when fast indenting your code, you might end up completing code without noticing with catastrophic results. Therefore you can refine things with the variable
ess-first-tab-never-complete. For example: if 'unless-eol, TAB completes only when cursor is at the end of the line; if 'symbol, it completes also in the middle of a line, but not if you are in the middle of a word; etc (read doc for more
with F1vess-first-tab-never-complete).
The problem is that, at least for me, TAB is bound to ess-noweb-indent-line, but the command governing indent-or-complete behaviour is: ess-indent-or-complete. So I use to fix the tab binding with:
(add-hook 'ess-mode-hook
'(lambda()
(local-set-key (kbd "<tab>") 'ess-indent-or-complete)
))
This works, but I wonder if this is the proper way. In the manual I don't see any prompt to hook to ESS mode and reset tab binding.
Do you know which is the canonical way to perform this?
There are a couple of reasonable ways to set the tab key (or any key, for that matter) for a specific mode. The first you alluded to in your answer, by setting the key locally via a mode hook. Note, though, that it's generally preferable to use a named function rather than a lambda so that you can remove the hook later if you want to do so:
(defun ess-keys-hook ()
"Put a bunch of keybindings in here."
(local-set-key [tab] 'ess-indent-or-complete))
(add-hook 'ess-mode-hook 'ess-keys-hook)
The other option is to define the key in the relevant mode map, which you can do like so:
(define-key ess-mode-map [tab] 'ess-indent-or-complete)
Both ways are pretty commonly used, although my own preference is for the latter, as it strikes me as cleaner and more efficient.
Related
By accident, I recently came across a latent coding error in one of my functions, dealing with a when statement. A reduced paraphrase might look like:
(defparameter a 0)
(when (or (= a 0)
(= a 1)
(* a a)))
The problem is a misplaced parenthesis, so it actually is
(when (or (= a 0)
(= a 1)
(* a a)))
In a situation like this, wouldn't it be useful for the compiler to generate either a style warning or note? It seems to me that the meaning of a when statement normally implies a condition and a body, even though the body is strictly optional. Of course, a print pretty would have caught this in the editor, but I had copied it from elsewhere. Is there a reason that SBCL does not check for these kinds of mistakes?
a print pretty would have caught this in the editor
To discuss the options, I know about:
trivial-formatter will format the source code.
(trivial-formatter:fmt :your-system :supersede)
cl-indentify indents the source code. Has a command line utility. I tried it once and it was not bad, but different than Emacs' indentation, thus annoying for me.
$ cl-indentify bar.lisp
It links to lispindent but I was less happy with its result.
However, the best would be to not only format the code and re-read it ourselves, but to
run checks against a set of rules to warn against code smells
This is what proposes the lisp-critic. It can critique a function or a file. However:
(edit) it doesn't really have a Slime integration, we have to either critique a function or a whole file.
if you feel adventurous, see an utility of mine here. It could be an easier way to test snippets that you enter at the REPL.
it hasn't the rule about when without a body (we can easily add it)
And it would be best that the run failed with an error status code if it found a code smell. Again, a little project of mine in beta tries to do that, see here. It doesn't have much rules now, but I just pushed a check for this. You can call the script:
$colisper.sh tests/playground.lisp
it shows an error (but doesn't write it in-place by default):
|;; when with no body
|(when (or (= a 0)
| (= a 1)
!| (* a a))
!| (error "colisper found a 'when' with a missing body. (we should error the script without this rewrite!)"))
and returns with an exit code, so we can use it has a git hook or on a CI pipeline.
The problem is that if a human writes (when x) (or whatever that expands into, perhaps (if x (progn) nil)) this is probably a mistake, but when a program writes it it may well not be: it may be just some edge case that the program hasn't been smart enough to optimize completely away. And a huge amount of code that the compiler processes is written by programs, not humans.
I am using Emacs with SLIME for my development environment. When I type (write-to and then C-M-i I get the following autocompletions:
Click on a completion to select it.
In this buffer, type RET to select the completion near point.
Possible completions are:
write-to-sting
write-to-string
I know Common Lisp is powerful, but I guess write-to-sting is not in the ANSI standard. Google didn't offer a single hit for this function. Then I tried to find it in the SBCL code, but alas
(documentation 'write-to-sting 'function) returns nil so it doesn't have a documentation string.
When I try to execute the function (write-to-sting) I get The function COMMON-LISP-USER::WRITE-TO-STING is undefined.
Apropos also finds an unbound function:
(apropos 'write-to)
WRITE-TO
WRITE-TO-STING
WRITE-TO-STRING (fbound)
My question is: What is going on? Does anyone knows the story behind this function?
At some point during your interaction with the Lisp environment, you wrote write-to-sting and it was read by the Lisp reader. The symbol was interned in the COMMON-LISP-USER package. After all, maybe you intended to implement a function that sends an email to Sting, who knows?
Auto-completion works by filtering the currently known symbols in the environment.
You can safely (unintern 'write-to-sting) (or implement it).
I am trying to optimize my ESS - R environment. So far I make use of the r-autoyas, I set intendation and stuff following style guides, in the mini-buffer there are eldoc hints for function arguments, and I have the option to press a key in order to find information about variable at point (more here).
Are there any other things you use in order to have a nice R environment? Maybe non-ESS people have some nice things to add (I got that info of variable at point from looking at an Eclipser). One example could be an easy way to insert "just-before-defined" variables without typing the variable name (should be something for that?).
(Please help me to change the question instead of "closing" the thread if it is not well formulated)
I am not using autoyas as I find auto-complete integration a better approach.
Insertion of previously defined symbols is a general emacs functionality called 'dabbrev-expand' and is bound to M-/. I have this in my .emacs to make it complete on full symbols:
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_\\|s.")
(setq dabbrev-case-fold-search t)
Another thing which I use extensively is imenu-based-jump-to-symbol-definition. It offers similar functionality to emacs tags, but just for open buffers in the same mode as the current buffer. It also uses IDO for queries:
Put imenu-anywhere.el into your emacs load path and add this:
(require 'imenu-anywhere)
(global-set-key [?\M-o] 'imenu-anywhere)
Now, if I do M-o foo RET emacs jumps to the function/class/method/generic definition of 'foo' as long as 'foo' is defined in one of the open buffers. This of course works whenever a mode defines imenu-tags. ESS defines those, so you should not need to add more.
There is also somewhere a collection of R-yas templates. I didn't get around to starting using them but my guess is that it's a pretty efficient template insertion mechanism.
[edit] Activate tracebug:
(setq ess-use-tracebug t)
I'm looking for a way to mimic Textmate's CSS editing behavior in Emacs.
In Textmate, when adding a CSS property:
#element {} <-- Braces auto close.
#element {background: ;} <-- after typing the colon, the semi-colon is automatically inserted and the cursor is placed between them.
I have taken a look at several css-modes (and textmate.el) but cannot see that anyone has implemented this.
I have absolutely zero knowledge of emacs-lisp would be be willing to give it a shot and write something myself, but does anyone know if this has been done already?
You want to look at some examples of electric functions (the naming convention used when additional input or formatting is performed when particular visible characters are typed).
There's nothing special about the implementation. The key in question is bound within the mode's keymap to a function which does the work. Aside from the fact that you must handle the insertion of the character typed, it's just like any other keybinding.
cc-mode has several examples. The basic approach looks like this:
(define-key c-mode-base-map "{" 'c-electric-brace)
(defun c-electric-brace (arg)
(interactive "*P")
;; [...]
(self-insert-command (prefix-numeric-value arg))
;; [...]
)
Admittedly c-electric-brace is a far more complicated function than you might be expecting, but it would be trivial to have a function which simply inserted the same number of }s after inserting the {s.
(defun my-electric-brace (arg)
"Automatically add a closing '}' for every '{' inserted."
(interactive "*P")
(let ((count (prefix-numeric-value arg)))
(self-insert-command count)
(save-excursion
(insert-char ?} count))))
(defun my-css-mode-hook ()
(local-set-key (kbd "{") 'my-electric-brace))
(add-hook 'css-mode-hook 'my-css-mode-hook)
You might find that is a little simplistic, and there are circumstances in which you don't want the matching brace to be inserted, however. You would probably also want to deal with automatically removing matching braces when you delete one of them, by defining electric delete functions.
Your electric colon requirement is also less trivial than the brace, as it should only occur in the right context (although in practice you might get away with a naive implementation, as I don't think you would be typing colons in a CSS file that were not in the correct context.)
Hopefully this points you in the right direction, if you decide to write your own solutions.
Obviously you would want to read some tutorials on elisp, but for understanding the code above, just note that you can use C-h f (describe-function) to read the documentation for any elisp function (or M-x find-function to view the code).
For general purpose autopairing of all sorts of braces, etc you might want to take a look at autopair-mode.
My Taglist in a C code:
macro
|| MIN_LEN
|| MAX_ITERATIONS
||- typedef
|| cell
|| source_cell
||- variable
|| len_given
Taglist elements (domain):
A = {MIN_LEN, MAX_ITERATIONS, cell, source_cell, len_given}
Code snippets (codomain):
B = {"code_MIN_LEN", "code_MAX_ITERATIONS", ..., "code_len_given"}
Goal: to have bijection between the sets A and B.
Example: I want to remove any element in A, such as the MIN_LEN, from A and B by removing either its element in A or B.
Question: Is there a way to quarantee a bijection between A and B so that a change either in A or in B results in a change in the other set?
I strongly doubt you can do that. The taglist plugin uses ctags to collect the symbols in your code and display them in a lateral split. The lateral split contains readonly information (if you try to work on that window, vim tells you that modifiable is off for that buffer).
What you want to achieve would imply quite complex parsing of the source code you are modifying. Even a simple task like automatic renaming (assuming you modify a function name entry in the taglist buffer and all the instances in your source are updated) requires pretty complex parsing, which is beyond the ctags features or taglist itself. Deleting and keeping everything in sync with a bijective relationship is even more complex. Suppose you have a printf line where you use a macro you want to remove. What should happen to that line? should the whole line disappear, or just the macro (in that case, the line will probably be syntactically incorrect.
taglist is a nice plugin for browsing your code, but it's unsuited for automatic refactoring (which is what you want to achieve).
Edit: as for the computational complexity, well, the worst case scenario is that you have to scout the whole document at every keystroke, looking for new occurrence of labels that could be integrated, so in this sense you could say it's O(n) at each keystroke. This is of course overkill and the worst method to implement it. I am not aware of the computational complexity of the syntax highlight in vim, (which would be useful to extract tags as well, via proper tokenization), but I would estimate it very low, and very limited in the amount of parsed data (you are unlikely to have large constructs to parse to extract the token and understand its context). In any case, this is not how taglist works. Taglist runs ctags at every vim invocation, it does not parse the document live while you type. This is however done by Eclipse, XCode and KDevelop for example, which also provide tools for automatic or semiautomatic refactoring, and can eventually integrate vim as an editor. If you need these features, you are definitely using the wrong tool.