13

Background: This is the third question in a row of questions about how to make editing packages in the front-end much more bearable (the other two are here and here). It seems that the front end is quite extensible, so I may not have to start using Workbench yet :)

When writing long blocks of code, proper indentation is invaluable. This is why most programming editors preserve the white space indentation when you enter a new line. So if you have three white spaces at the current line and press Enter to move to a new line, it will also have three white spaces.

Example image

So my question is: Is there a way to make the front-end preserve the white space indentation (when editing a package)?

Ajasja
  • 13,634
  • 2
  • 46
  • 104

1 Answers1

11

I have a palette including this button:

CreatePalette[{
  Button[
   "m-editor",
   Module[{modifyCodeStyle},(*by David Reiss*)

     modifyCodeStyle[nb_NotebookObject, Notebook] := 
      Module[{styledefs, editable}, 
       editable = Editable /. Options[nb, Editable];
       SetOptions[nb, Editable -> True];
       styledefs = StyleDefinitions /. Options[nb, StyleDefinitions];
       Switch[Head[styledefs], Notebook, 
        styledefs = 
         Notebook[{First@First[styledefs], 
           Cell[StyleData["Code"], PageWidth -> WindowWidth, 
            AutoIndent -> True, AutoSpacing -> True, 
            LineBreakWithin -> Automatic, LineIndent -> 1, 
            LinebreakAdjustments -> {0.85, 2, 10, 0, 1}], 
           Rest@First[styledefs]}, 
          Sequence @@ Rest[List @@ styledefs]], 
        String | FileName | FrontEnd`FileName, 
        styledefs = 
         Notebook[{Cell[StyleData[StyleDefinitions -> styledefs]], 
           Cell[StyleData["Code"], PageWidth -> WindowWidth, 
            AutoIndent -> True, AutoSpacing -> True, 
            LineBreakWithin -> Automatic, LineIndent -> 1, 
            LinebreakAdjustments -> {0.85, 2, 10, 0, 1}]}, 
          StyleDefinitions -> "PrivateStylesheetFormatting.nb"]];
       SetOptions[nb, StyleDefinitions -> styledefs];
       SetOptions[nb, Editable -> editable]];
     modifyCodeStyle[SelectedNotebook[], Notebook]];
   ]
  },
 WindowTitle -> "fix editor"
 ]

the code for which I lifted from a post of David Reiss on the mathgroup.

To use it: open an m-editor, then click on the button. It will do what you want from there on. However, this must be repeated if you close and re-open the editor window.

Ajasja
  • 13,634
  • 2
  • 46
  • 104
acl
  • 19,834
  • 3
  • 66
  • 91
  • +1 Is it perhaps possible to apply this automatically every time package is opened? Or to change the default style sheets for the m-editor? – Ajasja May 18 '12 at 21:14
  • I don't know how it is possible to do that. Perhaps someone else does have some ideas. For my part, this kind of annoyance led me to the workbench (which simply has a different set of annoyances!) – acl May 18 '12 at 21:48
  • I had not seen this before, and I didn't know it could be done this way. +1! – Mr.Wizard May 19 '12 at 07:34
  • One crude way of applying this fix automatically would be to pool (for example every one seconf) Notebooks[] using a ScheduledTask and apply this to any new *.m that are found. The code for would be put in an init.m somewhere. I don't know if there is a way to get notification form the front-end whenever a new file is opened. That method would be preferable to pooling... – Ajasja May 19 '12 at 20:14
  • I don't see what would get notified by the frontend if a new .m file was opened. You could try using Dynamic and having it do something whenever the list of open windows changes, but that doesn't work reliably if it's off-screen. But, perhaps there is some other way to get this to work always. although you'll quickly start getting annoyed again: construct your beautifully indented code and then attempt to wrap a Total[] (say) around it. You can't block-indent... – acl May 19 '12 at 20:39
  • Good point, but perhaps a block-indent shortcut could be written as well. One would have to replace the selection with the indented version. Of course this would only be applicable to an m-editor. – Ajasja May 21 '12 at 07:41
  • Also, I've been trying to apply this using SetOptions[$FrontEnd, ...] but it doesn't seem to work. – Ajasja May 21 '12 at 08:03