* auto indenting code blocks @ 2015-06-13 10:40 Sam Halliday 2015-06-13 11:25 ` Yuri Khan 0 siblings, 1 reply; 8+ messages in thread From: Sam Halliday @ 2015-06-13 10:40 UTC (permalink / raw) To: help-gnu-emacs Hi all, I find it extremely convenient when writing Scala code (and this may be relevant in all c-mode derivations) to be able to have my code blocks automatically expanded. I have smart-parens installed, so when I type `{' the closing brace is placed after point. But often I intend to write a multi-line block of code (this may well be the norm in C and C++) and when I type newline I expect the second brace to be moved down a line, indented, and the point placed, indented, in the middle. For example, let's say we start with this (point denoted by pipe) blah | Type `{' and smart-parens will insert the closing brace blah {|} I'd actually prefer it to be, so if anybody knows how to do that I'd be greatly appreciative of their advice. blah { | } Then I hit newline and this happens blah { |} But I *actually* want blah { | } I have cooked up a little post-self-insert-hook (see bottom of mail) but it feels like I'm inventing some form of wheel. 1. is there an existing preferred way to do what my scala-block-indent is trying to do? 2. is there an easier way (perhaps via smart-parens) to achieve what my scala-block-pad is doing, but at the point when the closing brace is inserted? (defun scala-block-indent () "It is convenient for newlines that follow a curly bracket to be indented." (when (and (eq major-mode 'scala-mode) ;; ordered for performance (looking-at "}") (looking-back "{[[:space:]]*\n")) (indent-according-to-mode) (forward-line -1) (move-end-of-line nil) (newline-and-indent))) (add-hook 'post-self-insert-hook 'scala-block-indent) (defun scala-block-pad () "It is convenient for spaces following a brace to be space padded." (when (and (eq major-mode 'scala-mode) ;; ordered for performance (looking-at "}") (looking-back "{[[:space:]]")) (insert-char ?\s) (backward-char))) (add-hook 'post-self-insert-hook 'scala-block-pad) Best regards, Sam ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: auto indenting code blocks 2015-06-13 10:40 auto indenting code blocks Sam Halliday @ 2015-06-13 11:25 ` Yuri Khan 2015-06-13 11:55 ` Michael Heerdegen 0 siblings, 1 reply; 8+ messages in thread From: Yuri Khan @ 2015-06-13 11:25 UTC (permalink / raw) To: Sam Halliday; +Cc: help-gnu-emacs@gnu.org On Sat, Jun 13, 2015 at 4:40 PM, Sam Halliday <sam.halliday@gmail.com> wrote: > I find it extremely convenient when writing Scala code (and this may be relevant in all c-mode derivations) to be able to have my code blocks automatically expanded. > > I have smart-parens installed, so when I type `{' the closing brace is placed after point. > > But often I intend to write a multi-line block of code (this may well be the norm in C and C++) and when I type newline I expect the second brace to be moved down a line, indented, and the point placed, indented, in the middle. I am solving this for C++ with the following ugly hack (BTW thanks for pointing out “looking-back”): === (defun yk-electric-ret () (interactive) (if (and (looking-at "\}") (looking-back "\{"))) (progn (newline-and-indent) (save-excursion (newline-and-indent)) (indent-according-to-mode)) (newline-and-indent))) (defun yk-braces-keys () (local-set-key (kbd "RET") 'yk-electric-ret)) (add-hook 'c-mode-common-hook 'yk-braces-keys) === It is essentially equivalent to yours except that I prefer rebinding a single key to watching for all buffer changes. > I have cooked up a little post-self-insert-hook (see bottom of mail) but it feels like I'm inventing some form of wheel. > > 1. is there an existing preferred way to do what my scala-block-indent is trying to do? > 2. is there an easier way (perhaps via smart-parens) to achieve what my scala-block-pad is doing, but at the point when the closing brace is inserted? I am also interested in answers to the above. Additionally, it would be nice to be able to select a multi-line region (def: a region that contains at least one line break), press “{” and have it automatically enclose the region in a pair of braces, add a line break immediately after the opening brace and another one before the closing brace, and re-indent all affected lines according to mode and style. (I could probably compose a function to that effect and bind it to “{” instead of c-electric-brace or self-insert-command, but that looks boring :]) ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: auto indenting code blocks 2015-06-13 11:25 ` Yuri Khan @ 2015-06-13 11:55 ` Michael Heerdegen 2015-06-13 13:14 ` Yuri Khan 0 siblings, 1 reply; 8+ messages in thread From: Michael Heerdegen @ 2015-06-13 11:55 UTC (permalink / raw) To: help-gnu-emacs Yuri Khan <yuri.v.khan@gmail.com> writes: > (defun yk-electric-ret () > (interactive) > (if (and (looking-at "\}") (looking-back "\{"))) > (progn > (newline-and-indent) > (save-excursion > (newline-and-indent)) > (indent-according-to-mode)) > (newline-and-indent))) > > (defun yk-braces-keys () > (local-set-key (kbd "RET") 'yk-electric-ret)) > (add-hook 'c-mode-common-hook 'yk-braces-keys) Shouldn't `electric-indent-mode' be able to do this? Michael. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: auto indenting code blocks 2015-06-13 11:55 ` Michael Heerdegen @ 2015-06-13 13:14 ` Yuri Khan 2015-06-13 23:30 ` Michael Heerdegen 0 siblings, 1 reply; 8+ messages in thread From: Yuri Khan @ 2015-06-13 13:14 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs@gnu.org On Sat, Jun 13, 2015 at 5:55 PM, Michael Heerdegen <michael_heerdegen@web.de> wrote: > Shouldn't `electric-indent-mode' be able to do this? Maybe it should, but it does not for me. $ emacs --version GNU Emacs 24.4.1 […] $ emacs -Q M-: (add-to-list 'load-path "~/.emacs.d/dash.el") ;; as of github:magnars/dash.el tag 2.10.0 M-: (add-to-list 'load-path "~/.emacs.d/smartparens") ;; as of github:Fuco1/smartparens.git commit 8d22a6b M-x load-library smartparens-config M-x smartparens-global-mode M-x load-library cc-mode M-: (setq c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "stroustrup"))) C-x C-f ~/test.cpp ;; where the file does not exist Now I start typing: === int main(| === As soon as I type the opening parenthesis, smartparens adds a matching closing parenthesis after the point: === int main(|) === I press End to get out of parentheses and then press Enter to start a new line: === int main() | === I press “{”. smartparens adds a matching closing brace. electric-indent-mode unindents the newly inserted pair of braces to the level of “int”: === int main() {|} === (1) I press Enter. Nothing special happens: === int main() { |} === (2) I press Enter again. Nothing special happens again: === int main() { |} === The behavior does not change if I use Ctrl+J instead of Enter. If at point (2) I go to the end of the line with the opening brace and press Enter, or if at point (1) I press Ctrl+O and then Enter, then I get the desired function skeleton: === int main() { | } === But those are not key sequences I’d like to repeat every time. If I forgo smartparens, then electric-indent-mode does indeed yield the desired sequence: === int main()| === Enter === int main() | === Opening brace === int main() {| === Enter === int main() { | === Some text === int main() { std::cout << "Hello World\n";| === Enter === int main() { std::cout << "Hello World\n"; | === Closing brace === int main() { std::cout << "Hello World\n"; }| === However, smartparens is too convenient to give up. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: auto indenting code blocks 2015-06-13 13:14 ` Yuri Khan @ 2015-06-13 23:30 ` Michael Heerdegen 2015-06-14 5:24 ` Yuri Khan [not found] ` <mailman.4973.1434259496.904.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 8+ messages in thread From: Michael Heerdegen @ 2015-06-13 23:30 UTC (permalink / raw) To: help-gnu-emacs Yuri Khan <yuri.v.khan@gmail.com> writes: > > Shouldn't `electric-indent-mode' be able to do this? > Maybe it should, but it does not for me. > If I forgo smartparens, then electric-indent-mode does indeed yield > the desired sequence: Then I think someone should make a bug report at the smartparens site please: https://github.com/Fuco1/smartparens A related report doesn't seem to exist yet. Contacting the author by email is surely ok if you don't have a github account. Regards, Michael. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: auto indenting code blocks 2015-06-13 23:30 ` Michael Heerdegen @ 2015-06-14 5:24 ` Yuri Khan [not found] ` <mailman.4973.1434259496.904.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 8+ messages in thread From: Yuri Khan @ 2015-06-14 5:24 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs@gnu.org On Sun, Jun 14, 2015 at 5:30 AM, Michael Heerdegen <michael_heerdegen@web.de> wrote: > Yuri Khan <yuri.v.khan@gmail.com> writes: > >> > Shouldn't `electric-indent-mode' be able to do this? >> Maybe it should, but it does not for me. > >> If I forgo smartparens, then electric-indent-mode does indeed yield >> the desired sequence: > > Then I think someone should make a bug report at the smartparens site > please: > > https://github.com/Fuco1/smartparens I do not believe it’s a smartparens bug. Its job in this context is to add a matching closing brace as soon as an opening brace is inserted. It’s not an electric-indent-mode bug, either. When a line break is inserted immediately before a closing brace, it reindents the closing brace according to the mode and style. What Sam and I want, however, is, with a single Enter keypress, to insert *two* line breaks, position the point between them, and indent everything nicely. This is just a piece of unimplemented functionality, and we implement it in slightly different but similar ways. It’s possible we are overlooking some part of smartparens’ functionality, hence this thread. Actually, the smartparens documentation mentions a facility for adding hooks on pair insertion: https://github.com/Fuco1/smartparens/wiki/Permissions#pre-and-post-action-hooks One of its examples specifically adds two line breaks, positions point in between, and reindents, but this happens immediately after inserting a brace, making it inconvenient to insert one-liners. The final example in the same section adds a hook that runs after a pair of braces is inserted *and* RET is pressed as the immediate next action. Which is pretty close to what I want but I think I prefer that it happen every time I press Enter while in an empty pair of braces, not only when said pair is newly inserted. The next section describes a more concise syntax for such insertions: https://github.com/Fuco1/smartparens/wiki/Permissions#pre-and-post-action-hooks === (sp-local-pair 'c++-mode "{" nil :post-handlers '(("||\n[i]" "RET"))) === Sam, you might also like this: === (sp-local-pair 'c++-mode "{" nil :post-handlers '(("||\n[i]" "RET") ("| " "SPC"))) === (substitute your major mode). I think I’ll take it for a drive. Michael, thank you for encouraging me to figure this out. ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <mailman.4973.1434259496.904.help-gnu-emacs@gnu.org>]
* Re: auto indenting code blocks [not found] ` <mailman.4973.1434259496.904.help-gnu-emacs@gnu.org> @ 2015-06-14 19:54 ` Sam Halliday 2015-06-14 19:59 ` Stefan Monnier 1 sibling, 0 replies; 8+ messages in thread From: Sam Halliday @ 2015-06-14 19:54 UTC (permalink / raw) To: help-gnu-emacs Yuri, this is *exactly* what I wanted... thank you so much for figuring it out :-D On Sunday, 14 June 2015 06:24:58 UTC+1, Yuri Khan wrote: > On Sun, Jun 14, 2015 at 5:30 AM, Michael Heerdegen > <michael_heerdegen@web.de> wrote: > > Yuri Khan <yuri.v.khan@gmail.com> writes: > > > >> > Shouldn't `electric-indent-mode' be able to do this? > >> Maybe it should, but it does not for me. > > > >> If I forgo smartparens, then electric-indent-mode does indeed yield > >> the desired sequence: > > > > Then I think someone should make a bug report at the smartparens site > > please: > > > > https://github.com/Fuco1/smartparens > > I do not believe it's a smartparens bug. Its job in this context is to > add a matching closing brace as soon as an opening brace is inserted. > > It's not an electric-indent-mode bug, either. When a line break is > inserted immediately before a closing brace, it reindents the closing > brace according to the mode and style. > > What Sam and I want, however, is, with a single Enter keypress, to > insert *two* line breaks, position the point between them, and indent > everything nicely. This is just a piece of unimplemented > functionality, and we implement it in slightly different but similar > ways. It's possible we are overlooking some part of smartparens' > functionality, hence this thread. > > Actually, the smartparens documentation mentions a facility for adding > hooks on pair insertion: > > https://github.com/Fuco1/smartparens/wiki/Permissions#pre-and-post-action-hooks > > One of its examples specifically adds two line breaks, positions point > in between, and reindents, but this happens immediately after > inserting a brace, making it inconvenient to insert one-liners. > > The final example in the same section adds a hook that runs after a > pair of braces is inserted *and* RET is pressed as the immediate next > action. Which is pretty close to what I want but I think I prefer that > it happen every time I press Enter while in an empty pair of braces, > not only when said pair is newly inserted. > > The next section describes a more concise syntax for such insertions: > > https://github.com/Fuco1/smartparens/wiki/Permissions#pre-and-post-action-hooks > > === > (sp-local-pair 'c++-mode "{" nil :post-handlers '(("||\n[i]" "RET"))) > === > > Sam, you might also like this: > > === > (sp-local-pair 'c++-mode "{" nil :post-handlers '(("||\n[i]" "RET") > ("| " "SPC"))) > === > > (substitute your major mode). > > > I think I'll take it for a drive. Michael, thank you for encouraging > me to figure this out. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: auto indenting code blocks [not found] ` <mailman.4973.1434259496.904.help-gnu-emacs@gnu.org> 2015-06-14 19:54 ` Sam Halliday @ 2015-06-14 19:59 ` Stefan Monnier 1 sibling, 0 replies; 8+ messages in thread From: Stefan Monnier @ 2015-06-14 19:59 UTC (permalink / raw) To: help-gnu-emacs > I do not believe it’s a smartparens bug. Its job in this context is to > add a matching closing brace as soon as an opening brace is inserted. > It’s not an electric-indent-mode bug, either. When a line break is > inserted immediately before a closing brace, it reindents the closing > brace according to the mode and style. > What Sam and I want, however, is, with a single Enter keypress, to > insert *two* line breaks, position the point between them, and indent > everything nicely. Indeed. IIRC electric-pair-mode offers such a feature, and during its implementation we considered other alternatives, including adding it via electric-layout-mode which is arguably conceptually closer. Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-06-14 19:59 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-06-13 10:40 auto indenting code blocks Sam Halliday 2015-06-13 11:25 ` Yuri Khan 2015-06-13 11:55 ` Michael Heerdegen 2015-06-13 13:14 ` Yuri Khan 2015-06-13 23:30 ` Michael Heerdegen 2015-06-14 5:24 ` Yuri Khan [not found] ` <mailman.4973.1434259496.904.help-gnu-emacs@gnu.org> 2015-06-14 19:54 ` Sam Halliday 2015-06-14 19:59 ` Stefan Monnier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).