Enabling Mode-Specific Paren Indentation in Emacs Prelude

712 views Asked by At

So I've switched to Emacs Prelude, and like it; it comes with 95% of the stuff I want baked-in, and that's lovely. Only one thing I want to change: mode-specific indent between parens, a la autopair.el. For instance, if I'm writing Scala and type:

Object foo {

  bar() {}

}

... and enter a newline between the curly braces of bar, I should get:

Object foo {

  bar() {
    // And point should be here, a Scala-standard two-space indent in from bar.
  }

}

But, if I were writing more or less the same thing in PHP, I should get a tab character instead of a two-space tab.

So: is there a "right" way to tweak this through custom.el? Prelude uses smartparens instead of autopair.el, configured in prelude-editor.el -- but I'd rather get this configured without having to hack "core" Prelude so that I can merge in updates easily.

Thoughts? Anybody else figured out how to do this with smartparens at all, or Prelude in particular?

2

There are 2 answers

2
Bozhidar Batsov On BEST ANSWER

You're already on the right track. I'll just add a bit to your self-posted answer.

The general idea with smartparens is to develop specialized configs for different major modes, so you can have the best experience for each of them. History has taught us that generic solutions generally are suboptimal.

smartparens users are encouraged to submit upstream config for various major modes - there are already configs for Ruby, Latex, Lisp and Lua. You might do well to submit upstream configs for Scala and PHP for the benefit of all smartparens users. Prelude will enable those out of the box when present.

The ability to fine tune just about everything made me pick smartparens for Prelude. I think that smartparens will become more important for Emacs users in the future (it's already managed to displace behemoths like paredit for Lisp programming).

0
Gastove On

Per SO usual, as soon as I posted this I came up with... most of an answer. It's good because it works, and works via custom.el; it's crappy because it involves a lot of repetition I can't figure out how to DRY up.

(sp-local-pair 'major-mode "{" nil :post-handlers '((my-create-newline-and-enter-sexp "RET")))                                                                                                                 
(sp-local-pair 'major-mode "(" nil :post-handlers '((my-create-newline-and-enter-sexp "RET")))                                                                                                                 
(sp-local-pair 'major-mode "[" nil :post-handlers '((my-create-newline-and-enter-sexp "RET")))                                                                                                                 
(sp-local-pair 'major-mode "<" nil :post-handlers '((my-create-newline-and-enter-sexp "RET")))                                                                                                                 

(defun my-create-newline-and-enter-sexp (&rest _ignored)                                                                                                                                                       
  "Open a new brace or bracket expression, with relevant newlines and indent. "                                                                                                                                
  (newline)                                                                                                                                                                                                    
  (indent-according-to-mode)                                                                                                                                                                                   
  (forward-line -1) 

So this... is OK. Not great, but OK. There's a variable called sp-pair-list that I'd much rather be able to access, but I can't figure out how to use it well. Anybody have better ideas? I'd love to just declare something like this and be done with it:

(loop for c in 'sp-pair-list                                                                                                                                                                                 
  do (                                                                                                                                                                                                       
    sp-local-pair 'major-mode c nil :post-handlers '((my-create-newline-and-enter-sexp "RET"))))