I've read the answers in Disable smart underscore for good ESS and ESS smart underscore does not work in emacs25 reasonably carefully and don't seem to be getting any of them to work. Maybe that's because the emacs/ESS ecosystem has changed, or maybe I'm just missing something.

Emacs version:

GNU Emacs 27.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.30, 
cairo version 1.16.0) of 2022-01-24, modified by Debian

and ESS 18.10.2.

When I open an R session and type _ I get the <- (as expected) and a message:

‘ess-smart-S-assign’ is an obsolete command (as of ESS 18.10); use ‘ess-insert-assign’ instead.

(I don't know if this is a sign that I'm doing something wrong, or just a generic startup warning message).

There are a lot of recipes out there; I've tried adding

(setq ess-insert-assign nil)

, which doesn't appear to change the behavior.

I've tried

(add-hook 'ess-mode-hook
      (define-key ess-r-mode-map "_" #'ess-insert-assign)
      (define-key inferior-ess-r-mode-map "_" #'ess-insert-assign)

which similarly doesn't seem to work.

I am admittedly cargo culting my way through this, but if anyone has suggestions for recipes and/or diagnostics ...

I have also installed polymode and poly-R (in case that matters). My entire .emacs file, other than the attempts to tame the underscore, consists of

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
   '(default-text-scale poly-R polymode tabbar session pod-mode parsebib muttrc-mode mutt-alias markdown-mode magit initsplit htmlize graphviz-dot-mode folding ess eproject diminish csv-mode company color-theme-modern cmake-mode browse-kill-ring boxquote bm bar-cursor apache-mode))
'(safe-local-variable-values '((TeX-master . t) (ess-swv-processor . knitr)))

2 Answers 2


Why don't you switch to the 19.04 version ...

ESS 19.04 19.04 (unreleased) release notes

  • Changes and New Features in 19.04 (unreleased): smart-underscore and ess-smart-S-assign-key have been removed. Users who liked the previous behavior (i.e. underscore inserting “<-”) should bind ess-insert-assign to the underscore in their Emacs initialization file. For example, (define-key ess-r-mode-map "_" #'ess-insert-assign) and (define-key inferior-ess-r-mode-map "_" #'ess-insert-assign) will activate it in all ESS R buffers

  • Changes and New Features in 18.10: ess-smart-S-assign was renamed to ess-insert-assign. It provides similar functionality but for any keybinding, not just ‘_‘. For instance if you bind it to ‘;‘, repeated invocations cycle through between assignment and inserting ‘;‘.

  • This worked for me. It is DEEPLY confusing that (AFAICT) there is no Emacs version actually labeled 19.04.
    – Ben Bolker
    Sep 22 at 14:29

smart-assign is no longer default behaviour for ESS. Unless you specifically turn it on, it shouldn't happen.

Users who want this feature are advised to add the following to their init:

(define-key ess-r-mode-map "_" #'ess-insert-assign)
(define-key inferior-ess-r-mode-map "_" #'ess-insert-assign)

From your question, it looks like you have added this code in at least your ess-mode-hook, and maybe elsewhere. If you remove these lines from your init and restart Emacs, the feature should be turned off as you want.

PS. You don't actually have to restart Emacs, you could just run the following code:

(define-key ess-r-mode-map "_" #'self-insert-command)
(define-key inferior-ess-r-mode-map "_" #'self-insert-command)

You don't need this in your init if you've removed the other code mentioned above.

  • I cannot for the life of me get this to work. I have no idea what's going on. (Thanks for trying ...)
    – Ben Bolker
    Sep 15 at 20:01
  • 1
    @BenBolker if you can post your config file somewhere I can see it, I'll take a look.
    – Tyler
    Sep 15 at 21:14
  • Do M-x debug-on-entry ess-insert-assign, and type _ and see what happens. Do a C-h k _ in the problematic buffer and see what is being reported. You want to bind "_" to self-insert-command, to get the dumb behaviour. Sep 22 at 7:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.