1 /*
2  * TextEditingTargetPrefsHelper.java
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 package org.rstudio.studio.client.workbench.views.source.editors.text;
16 
17 import java.util.ArrayList;
18 
19 import org.rstudio.core.client.files.FileSystemItem;
20 import org.rstudio.studio.client.workbench.prefs.model.UserPrefs;
21 import org.rstudio.studio.client.workbench.views.source.model.ProjectConfig;
22 import org.rstudio.studio.client.workbench.views.source.model.SourceDocument;
23 
24 import com.google.gwt.event.shared.HandlerRegistration;
25 
26 public class TextEditingTargetPrefsHelper
27 {
28    public enum PrefsSet
29    {
30       Embedded,  // The prefs to be used for embedded targets
31       Full       // The prefs to be used for full targets
32    }
33 
34    public static interface PrefsContext
35    {
getActiveFile()36       FileSystemItem getActiveFile();
37    }
38 
registerPrefs( ArrayList<HandlerRegistration> releaseOnDismiss, UserPrefs prefs, ProjectConfig projectConfig, DocDisplay docDisplay, final SourceDocument sourceDoc)39    public static void registerPrefs(
40                      ArrayList<HandlerRegistration> releaseOnDismiss,
41                      UserPrefs prefs,
42                      ProjectConfig projectConfig,
43                      DocDisplay docDisplay,
44                      final SourceDocument sourceDoc)
45    {
46       registerPrefs(releaseOnDismiss,
47                     prefs,
48                     projectConfig,
49                     docDisplay,
50                     () -> {
51                         String path = sourceDoc.getPath();
52                         if (path != null)
53                            return FileSystemItem.createFile(path);
54                         else
55                            return null;
56                      },
57                     PrefsSet.Full);
58    }
59 
registerPrefs( ArrayList<HandlerRegistration> releaseOnDismiss, UserPrefs prefs, final ProjectConfig projectConfig, final DocDisplay docDisplay, final PrefsContext context, PrefsSet prefsSet)60    public static void registerPrefs(
61                      ArrayList<HandlerRegistration> releaseOnDismiss,
62                      UserPrefs prefs,
63                      final ProjectConfig projectConfig,
64                      final DocDisplay docDisplay,
65                      final PrefsContext context,
66                      PrefsSet prefsSet)
67    {
68       releaseOnDismiss.add(prefs.highlightSelectedWord().bind(
69             (arg) ->
70             {
71                docDisplay.setHighlightSelectedWord(arg);
72             }));
73       releaseOnDismiss.add(prefs.useSpacesForTab().bind(
74             (arg) ->
75             {
76                if (TextEditingTarget.shouldEnforceHardTabs(context.getActiveFile()))
77                {
78                   docDisplay.setUseSoftTabs(false);
79                }
80                else
81                {
82                   if (projectConfig == null)
83                      docDisplay.setUseSoftTabs(arg);
84                }
85              }));
86       releaseOnDismiss.add(prefs.numSpacesForTab().bind(
87             (arg) ->
88             {
89                if (projectConfig == null)
90                  docDisplay.setTabSize(arg);
91             }));
92       releaseOnDismiss.add(prefs.autoDetectIndentation().bind(
93             (arg) ->
94             {
95                if (projectConfig == null)
96                  docDisplay.autoDetectIndentation(arg);
97             }));
98       releaseOnDismiss.add(prefs.blinkingCursor().bind(
99             (arg) ->
100             {
101                docDisplay.setBlinkingCursor(arg);
102             }));
103       releaseOnDismiss.add(prefs.marginColumn().bind(
104             (arg) ->
105             {
106                docDisplay.setPrintMarginColumn(arg);
107             }));
108       releaseOnDismiss.add(prefs.showInvisibles().bind(
109             (arg) ->
110             {
111                docDisplay.setShowInvisibles(arg);
112             }));
113       releaseOnDismiss.add(prefs.showIndentGuides().bind(
114             (arg) ->
115             {
116                docDisplay.setShowIndentGuides(arg);
117             }));
118       releaseOnDismiss.add(prefs.scrollPastEndOfDocument().bind(
119             (arg) ->
120             {
121                docDisplay.setScrollPastEndOfDocument(arg);
122             }));
123       releaseOnDismiss.add(prefs.highlightRFunctionCalls().bind(
124             (arg) ->
125             {
126                docDisplay.setHighlightRFunctionCalls(arg);
127             }));
128       releaseOnDismiss.add(prefs.rainbowParentheses().bind(
129             (arg) ->
130             {
131                docDisplay.setRainbowParentheses(arg);
132             }));
133       releaseOnDismiss.add(prefs.codeCompletionOther().bind(
134             (arg) ->
135             {
136                docDisplay.syncCompletionPrefs();
137             }));
138       releaseOnDismiss.add(prefs.codeCompletionCharacters().bind(
139             (arg) ->
140             {
141                docDisplay.syncCompletionPrefs();
142             }));
143       releaseOnDismiss.add(prefs.codeCompletionDelay().bind(
144             (arg) ->
145             {
146                docDisplay.syncCompletionPrefs();
147             }));
148       releaseOnDismiss.add(prefs.enableSnippets().bind(
149             (arg) ->
150             {
151                docDisplay.syncCompletionPrefs();
152             }));
153       releaseOnDismiss.add(prefs.showDiagnosticsOther().bind(
154             (arg) ->
155             {
156                docDisplay.syncDiagnosticsPrefs();
157             }));
158       releaseOnDismiss.add(prefs.diagnosticsOnSave().bind(
159             (arg) ->
160             {
161               docDisplay.syncDiagnosticsPrefs();
162             }));
163       releaseOnDismiss.add(prefs.backgroundDiagnosticsDelayMs().bind(
164             (arg) ->
165             {
166                docDisplay.syncDiagnosticsPrefs();
167             }));
168       releaseOnDismiss.add(prefs.showInlineToolbarForRCodeChunks().bind(
169             (arg) ->
170             {
171                docDisplay.forceImmediateRender();
172             }));
173       releaseOnDismiss.add(prefs.surroundSelection().bind(
174             (arg) ->
175             {
176                docDisplay.setSurroundSelectionPref(arg);
177             }));
178       releaseOnDismiss.add(prefs.enableTextDrag().bind(
179             (arg) ->
180             {
181                docDisplay.setDragEnabled(arg);
182             }));
183 
184       // Full editors get additional prefs (we don't use these in embedded editors)
185       if (prefsSet == PrefsSet.Full)
186       {
187          releaseOnDismiss.add(prefs.showMargin().bind(
188                (arg) ->
189                {
190                   docDisplay.setShowPrintMargin(arg);
191                }));
192          releaseOnDismiss.add(prefs.showLineNumbers().bind(
193                (arg) ->
194                {
195                   docDisplay.setShowLineNumbers(arg);
196                }));
197          releaseOnDismiss.add(prefs.highlightSelectedLine().bind(
198                (arg) ->
199                {
200                   docDisplay.setHighlightSelectedLine(arg);
201                }));
202          releaseOnDismiss.add(prefs.editorKeybindings().bind(
203                (arg) ->
204                {
205                   docDisplay.setUseVimMode(arg == UserPrefs.EDITOR_KEYBINDINGS_VIM);
206                }));
207          releaseOnDismiss.add(prefs.editorKeybindings().bind(
208                (arg) ->
209                {
210                   docDisplay.setUseEmacsKeybindings(arg == UserPrefs.EDITOR_KEYBINDINGS_EMACS);
211                }));
212          releaseOnDismiss.add(prefs.foldStyle().bind(
213                (arg) ->
214                {
215                   docDisplay.setFoldStyle(FoldStyle.fromPref(arg));
216                }));
217       }
218 
219       // Embedded mode specific prefs
220       if (prefsSet == PrefsSet.Embedded)
221       {
222          releaseOnDismiss.add(prefs.visualMarkdownEditingShowMargin().bind(
223                (arg) ->
224                {
225                   docDisplay.setShowPrintMargin(arg);
226                }));
227       }
228    }
229 }
230