[intellij sh] IDEA-221381 Make Unix line separator by default for shell files and add it to code style settings

GitOrigin-RevId: 9c8ef51ba590f91ed0a8b44ea41749ddf71f5cb1
This commit is contained in:
Mikhail Mazurkevich
2020-10-20 18:48:59 +00:00
committed by intellij-monorepo-bot
parent 245594bfc1
commit b5637db965
6 changed files with 91 additions and 3 deletions
+1
View File
@@ -69,6 +69,7 @@ Adds support for working with shell script files
<lineIndentProvider implementation="com.intellij.sh.formatter.ShLineIndentProvider"/>
<langCodeStyleSettingsProvider implementation="com.intellij.sh.codeStyle.ShLanguageCodeStyleSettingsProvider"/>
<fileDocumentManagerListener implementation="com.intellij.sh.formatter.ShLineEndingsAdapter"/>
<externalFormatProcessor implementation="com.intellij.sh.formatter.ShExternalFormatter"/>
<lang.formatter language="Shell Script" implementationClass="com.intellij.sh.formatter.ShFormatterModelBuilder"/>
<postFormatProcessor implementation="com.intellij.sh.formatter.ShPostFormatProcessor"/>
@@ -3,6 +3,7 @@ sh.code.style.choose.path=Choose Path to the Shfmt Formatter:
sh.code.style.download.link=Download shfmt formatter
sh.code.style.keep.column.alignment.padding=Keep column alignment padding
sh.code.style.minify.program.to.reduce.its.size=Minify program to reduce its size
sh.code.style.unix.line.separator=Use Unix line separator (\\n)
sh.code.style.redirect.operators.will.be.followed.by.a.space=Redirect operators will be followed by a space
sh.code.style.switch.cases.will.be.indented=Switch cases will be indented
@@ -46,7 +46,7 @@
<properties/>
<border type="empty"/>
<children>
<grid id="153e3" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="153e3" layout-manager="GridLayoutManager" row-count="8" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints/>
<properties/>
@@ -84,7 +84,7 @@
</component>
<vspacer id="15d8d">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false">
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false">
<preferred-size width="-1" height="100"/>
</grid>
</constraints>
@@ -92,7 +92,7 @@
<grid id="2466a" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="30" vgap="-1">
<margin top="10" left="0" bottom="0" right="0"/>
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -143,6 +143,12 @@
</component>
</children>
</grid>
<component id="4abe1" class="com.intellij.ui.components.JBCheckBox" binding="myUnixLineSeparator">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
</children>
@@ -50,6 +50,7 @@ public class ShCodeStylePanel extends CodeStyleAbstractPanel {
private JCheckBox myRedirectFollowedBySpace;
private JCheckBox myKeepColumnAlignmentPadding;
private JCheckBox myMinifyProgram;
private JCheckBox myUnixLineSeparator;
@SuppressWarnings("unused")
private ActionLink myShfmtDownloadLink;
@@ -76,6 +77,7 @@ public class ShCodeStylePanel extends CodeStyleAbstractPanel {
myRedirectFollowedBySpace.setText(ShBundle.message("sh.code.style.redirect.operators.will.be.followed.by.a.space"));
myKeepColumnAlignmentPadding.setText(ShBundle.message("sh.code.style.keep.column.alignment.padding"));
myMinifyProgram.setText(ShBundle.message("sh.code.style.minify.program.to.reduce.its.size"));
myUnixLineSeparator.setText(ShBundle.message("sh.code.style.unix.line.separator"));
addPanelToWatch(myPanel);
}
@@ -130,6 +132,7 @@ public class ShCodeStylePanel extends CodeStyleAbstractPanel {
shSettings.REDIRECT_FOLLOWED_BY_SPACE = myRedirectFollowedBySpace.isSelected();
shSettings.KEEP_COLUMN_ALIGNMENT_PADDING = myKeepColumnAlignmentPadding.isSelected();
shSettings.MINIFY_PROGRAM = myMinifyProgram.isSelected();
shSettings.USE_UNIX_LINE_SEPARATOR = myUnixLineSeparator.isSelected();
ShSettings.setShfmtPath(myShfmtPathSelector.getText());
myWarningPanel.setVisible(!ShShfmtFormatterUtil.isValidPath(myShfmtPathSelector.getText()));
myErrorLabel.setVisible(false);
@@ -145,6 +148,7 @@ public class ShCodeStylePanel extends CodeStyleAbstractPanel {
|| isFieldModified(myRedirectFollowedBySpace, shSettings.REDIRECT_FOLLOWED_BY_SPACE)
|| isFieldModified(myKeepColumnAlignmentPadding, shSettings.KEEP_COLUMN_ALIGNMENT_PADDING)
|| isFieldModified(myMinifyProgram, shSettings.MINIFY_PROGRAM)
|| isFieldModified(myUnixLineSeparator, shSettings.USE_UNIX_LINE_SEPARATOR)
|| isFieldModified(myTabCharacter, indentOptions.USE_TAB_CHARACTER)
|| isFieldModified(myIndentField, indentOptions.INDENT_SIZE)
|| isFieldModified(myTabField, indentOptions.TAB_SIZE)
@@ -170,6 +174,7 @@ public class ShCodeStylePanel extends CodeStyleAbstractPanel {
myRedirectFollowedBySpace.setSelected(shSettings.REDIRECT_FOLLOWED_BY_SPACE);
myKeepColumnAlignmentPadding.setSelected(shSettings.KEEP_COLUMN_ALIGNMENT_PADDING);
myMinifyProgram.setSelected(shSettings.MINIFY_PROGRAM);
myUnixLineSeparator.setSelected(shSettings.USE_UNIX_LINE_SEPARATOR);
myShfmtPathSelector.setText(ShSettings.getShfmtPath());
myWarningPanel.setVisible(!ShShfmtFormatterUtil.isValidPath(ShSettings.getShfmtPath()));
myErrorLabel.setVisible(false);
@@ -10,6 +10,7 @@ public class ShCodeStyleSettings extends CustomCodeStyleSettings {
public boolean REDIRECT_FOLLOWED_BY_SPACE = false;
public boolean KEEP_COLUMN_ALIGNMENT_PADDING = false;
public boolean MINIFY_PROGRAM = false;
public boolean USE_UNIX_LINE_SEPARATOR = true;
public ShCodeStyleSettings(CodeStyleSettings container) {
super("Shell_Script", container);
@@ -0,0 +1,74 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sh.formatter;
import com.intellij.application.options.CodeStyle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentManagerListener;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.StatusBarWidget;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.impl.status.LineSeparatorPanel;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.sh.codeStyle.ShCodeStyleSettings;
import com.intellij.sh.psi.ShFile;
import com.intellij.util.LineSeparator;
import org.jetbrains.annotations.NotNull;
import static com.intellij.openapi.wm.StatusBar.StandardWidgets.LINE_SEPARATOR_PANEL;
public class ShLineEndingsAdapter implements FileDocumentManagerListener {
private boolean statusBarUpdated;
@Override
public void beforeAllDocumentsSaving() {
statusBarUpdated = false;
}
@Override
public void beforeDocumentSaving(@NotNull Document document) {
VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
if (virtualFile == null) return;
Project project = ProjectUtil.guessProjectForFile(virtualFile);
if (project == null) return;
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
if (!(psiFile instanceof ShFile)) return;
CodeStyleSettings settings = CodeStyle.getSettings(psiFile);
ShCodeStyleSettings shSettings = settings.getCustomSettings(ShCodeStyleSettings.class);
String expectedLineSeparator = shSettings.USE_UNIX_LINE_SEPARATOR ? LineSeparator.LF.getSeparatorString() :
LineSeparator.getSystemLineSeparator().getSeparatorString();
String fileDetectedLineSeparator = virtualFile.getDetectedLineSeparator();
if (fileDetectedLineSeparator == null || !fileDetectedLineSeparator.equals(expectedLineSeparator)) {
virtualFile.setDetectedLineSeparator(expectedLineSeparator);
if (!statusBarUpdated) {
statusBarUpdated = true;
updateStatusBar(project);
}
}
}
private static void updateStatusBar(@NotNull Project project) {
ApplicationManager.getApplication().invokeLater(() -> {
IdeFrame frame = WindowManager.getInstance().getIdeFrame(project);
StatusBar statusBar = frame != null ? frame.getStatusBar() : null;
StatusBarWidget widget = statusBar != null ? statusBar.getWidget(LINE_SEPARATOR_PANEL) : null;
if (widget instanceof LineSeparatorPanel) {
FileEditorManagerEvent event = new FileEditorManagerEvent(FileEditorManager.getInstance(project),
null, null, null, null);
((LineSeparatorPanel)widget).selectionChanged(event);
}
});
}
}