Skip to content

Commit

Permalink
Merge 0c27400 into a7a304d
Browse files Browse the repository at this point in the history
  • Loading branch information
SeeSharpSoft committed Feb 6, 2020
2 parents a7a304d + 0c27400 commit c5a6fb5
Show file tree
Hide file tree
Showing 52 changed files with 353 additions and 358 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Expand Up @@ -3,5 +3,5 @@
# https://www.jetbrains.com/intellij-repository/snapshots

name='CSV Plugin'
javaVersion=1.8
javaTargetVersion=1.8
javaVersion=8
javaTargetVersion=8
@@ -0,0 +1,30 @@
package net.seesharpsoft.intellij.plugins.csv;

import java.util.regex.Pattern;

public enum CsvEscapeCharacter {
QUOTE("\"", "Double Quote (\")"),
BACKSLASH("\\", "Backslash (\\)");

private final String myCharacter;
private final String myDisplay;
private final Pattern myPattern;

CsvEscapeCharacter(String character, String display) {
myCharacter = character;
myDisplay = display;
myPattern = Pattern.compile(Pattern.quote(myCharacter + "\""));
}

public String getCharacter() {
return myCharacter;
}

public String getDisplay() {
return myDisplay;
}

public boolean isEscapedQuote(String text) {
return myPattern.matcher(text).matches();
}
}
29 changes: 20 additions & 9 deletions src/main/java/net/seesharpsoft/intellij/plugins/csv/CsvHelper.java
Expand Up @@ -18,7 +18,6 @@
import com.intellij.psi.util.PsiTreeUtil;
import net.seesharpsoft.intellij.lang.FileParserDefinition;
import net.seesharpsoft.intellij.plugins.csv.components.CsvFileAttributes;
import net.seesharpsoft.intellij.plugins.csv.editor.CsvEditorSettings;
import net.seesharpsoft.intellij.plugins.csv.psi.CsvField;
import net.seesharpsoft.intellij.plugins.csv.psi.CsvFile;
import net.seesharpsoft.intellij.plugins.csv.psi.CsvRecord;
Expand Down Expand Up @@ -152,16 +151,24 @@ public static int getFieldEndOffset(PsiElement field) {
return separator == null ? field.getContainingFile().getTextLength() : separator.getTextOffset();
}

public static CsvEditorSettings.EscapeCharacter getCurrentEscapeCharacter(CsvFile csvFile) {
public static CsvValueSeparator getCurrentValueSeparator(CsvFile csvFile) {
return getCurrentValueSeparator(csvFile.getContainingFile());
}

public static CsvValueSeparator getCurrentValueSeparator(PsiFile psiFile) {
return CsvFileAttributes.getInstance(psiFile.getProject()).getFileSeparator(psiFile);
}

public static CsvEscapeCharacter getCurrentEscapeCharacter(CsvFile csvFile) {
return getCurrentEscapeCharacter(csvFile.getContainingFile());
}

public static CsvEditorSettings.EscapeCharacter getCurrentEscapeCharacter(PsiFile psiFile) {
public static CsvEscapeCharacter getCurrentEscapeCharacter(PsiFile psiFile) {
return CsvFileAttributes.getInstance(psiFile.getProject()).getEscapeCharacter(psiFile);
}

public static CsvColumnInfoMap<PsiElement> createColumnInfoMap(CsvFile csvFile) {
CsvEditorSettings.EscapeCharacter escapeCharacter = getCurrentEscapeCharacter(csvFile);
CsvEscapeCharacter escapeCharacter = getCurrentEscapeCharacter(csvFile);
Map<Integer, CsvColumnInfo<PsiElement>> columnInfoMap = new HashMap<>();
CsvRecord[] records = PsiTreeUtil.getChildrenOfType(csvFile, CsvRecord.class);
int row = 0;
Expand All @@ -182,7 +189,7 @@ public static CsvColumnInfoMap<PsiElement> createColumnInfoMap(CsvFile csvFile)
return new CsvColumnInfoMap(columnInfoMap, PsiTreeUtil.hasErrorElements(csvFile));
}

public static String unquoteCsvValue(String content, CsvEditorSettings.EscapeCharacter escapeCharacter) {
public static String unquoteCsvValue(String content, CsvEscapeCharacter escapeCharacter) {
if (content == null) {
return "";
}
Expand All @@ -194,15 +201,19 @@ public static String unquoteCsvValue(String content, CsvEditorSettings.EscapeCha
return result;
}

private static boolean isQuotingRequired(String content, String separator) {
return content != null && (content.contains(separator) || content.contains("\"") || content.contains("\n") || content.startsWith(" ") || content.endsWith(" "));
private static boolean isQuotingRequired(String content, CsvValueSeparator valueSeparator) {
return content != null &&
(content.contains(valueSeparator.getCharacter()) || content.contains("\"") || content.contains("\n") || content.startsWith(" ") || content.endsWith(" "));
}

public static String quoteCsvField(String content, CsvEditorSettings.EscapeCharacter escapeCharacter, String separator, boolean quotingEnforced) {
public static String quoteCsvField(String content,
CsvEscapeCharacter escapeCharacter,
CsvValueSeparator valueSeparator,
boolean quotingEnforced) {
if (content == null) {
return "";
}
if (quotingEnforced || isQuotingRequired(content, separator)) {
if (quotingEnforced || isQuotingRequired(content, valueSeparator)) {
String result = content.replaceAll("\"", escapeCharacter.getCharacter() + "\"");
return "\"" + result + "\"";
}
Expand Down
@@ -1,10 +1,9 @@
package net.seesharpsoft.intellij.plugins.csv;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import net.seesharpsoft.intellij.plugins.csv.editor.CsvEditorSettings;
import net.seesharpsoft.intellij.plugins.csv.psi.CsvTypes;
import com.intellij.psi.TokenType;
import com.intellij.lexer.FlexLexer;

import java.util.regex.Pattern;

Expand All @@ -16,17 +15,17 @@ import java.util.regex.Pattern;
%function advance
%type IElementType
%{
private String currentSeparator;
private CsvEditorSettings.EscapeCharacter myEscapeCharacter;
private CsvValueSeparator myValueSeparator;
private CsvEscapeCharacter myEscapeCharacter;

private static final Pattern ESCAPE_TEXT_PATTERN = Pattern.compile("[,;|\\t\\r\\n]");

/**
* Provide constructor that supports a Project as parameter.
*/
CsvLexer(java.io.Reader in, String separator, CsvEditorSettings.EscapeCharacter escapeCharacter) {
CsvLexer(java.io.Reader in, CsvValueSeparator valueSeparator, CsvEscapeCharacter escapeCharacter) {
this(in);
this.currentSeparator = separator;
myValueSeparator = valueSeparator;
myEscapeCharacter = escapeCharacter;
}
%}
Expand Down Expand Up @@ -82,7 +81,7 @@ WHITE_SPACE=[ \f]+

<YYINITIAL, AFTER_TEXT, UNESCAPED_TEXT> {COMMA}
{
if (currentSeparator.equals(yytext().toString())) {
if (myValueSeparator.isValueSeparator(yytext().toString())) {
yybegin(YYINITIAL);
return CsvTypes.COMMA;
}
Expand Down
@@ -1,10 +1,9 @@
package net.seesharpsoft.intellij.plugins.csv;

import com.intellij.lexer.FlexAdapter;
import net.seesharpsoft.intellij.plugins.csv.editor.CsvEditorSettings;

public class CsvLexerAdapter extends FlexAdapter {
public CsvLexerAdapter(String separator, CsvEditorSettings.EscapeCharacter escapeCharacter) {
public CsvLexerAdapter(CsvValueSeparator separator, CsvEscapeCharacter escapeCharacter) {
super(new CsvLexer(null, separator, escapeCharacter));
}
}
Expand Up @@ -77,7 +77,7 @@ public PsiElement createElement(ASTNode node) {

@Override
public Lexer createLexer(@NotNull PsiFile file) {
return new CsvLexerAdapter(CsvCodeStyleSettings.getCurrentSeparator(file), CsvFileAttributes.getInstance(file.getProject()).getEscapeCharacter(file));
return new CsvLexerAdapter(CsvHelper.getCurrentValueSeparator(file), CsvFileAttributes.getInstance(file.getProject()).getEscapeCharacter(file));
}

@Override
Expand Down
Expand Up @@ -3,9 +3,7 @@
import com.intellij.lang.PsiBuilder;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.resolve.FileContextUtil;
import net.seesharpsoft.intellij.plugins.csv.components.CsvFileAttributes;
import net.seesharpsoft.intellij.plugins.csv.psi.CsvTypes;
import net.seesharpsoft.intellij.plugins.csv.settings.CsvCodeStyleSettings;

import java.util.regex.Pattern;

Expand All @@ -23,9 +21,7 @@ public static boolean separator(PsiBuilder builder, int tokenType) {
if (psiFile == null) {
throw new UnsupportedOperationException("parser requires containing file");
}
return builder.getTokenText().equals(
CsvCodeStyleSettings.getCurrentSeparator(psiFile)
);
return CsvHelper.getCurrentValueSeparator(psiFile).isValueSeparator(builder.getTokenText());
}
return false;
}
Expand All @@ -37,7 +33,7 @@ public static boolean escapeCharacter(PsiBuilder builder, int tokenType) {
throw new UnsupportedOperationException("parser requires containing file");
}
String tokenText = builder.getTokenText();
return CsvFileAttributes.getInstance(psiFile.getProject()).getEscapeCharacter(psiFile).isEscapedQuote(tokenText) ||
return CsvHelper.getCurrentEscapeCharacter(psiFile).isEscapedQuote(tokenText) ||
ESCAPE_TEXT_PATTERN.matcher(tokenText).matches();
}
return false;
Expand Down
@@ -1,5 +1,5 @@
package net.seesharpsoft.intellij.plugins.csv;

public interface CsvSeparatorHolder {
String getSeparator();
CsvValueSeparator getSeparator();
}
@@ -0,0 +1,32 @@
package net.seesharpsoft.intellij.plugins.csv;

import java.util.regex.Pattern;

public enum CsvValueSeparator {
COMMA(",", "Comma (,)"),
SEMICOLON(";", "Semicolon (;)"),
PIPE("|", "Pipe (|)"),
TAB("\t", "Tab (↹)");

private final String myCharacter;
private final String myDisplay;
private final Pattern myPattern;

CsvValueSeparator(String character, String display) {
myCharacter = character;
myDisplay = display;
myPattern = Pattern.compile(Pattern.quote(myCharacter));
}

public String getCharacter() {
return myCharacter;
}

public String getDisplay() {
return myDisplay;
}

public boolean isValueSeparator(String text) {
return myPattern.matcher(text).matches();
}
}
Expand Up @@ -7,14 +7,14 @@
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.psi.PsiFile;
import com.intellij.util.FileContentUtilCore;
import net.seesharpsoft.intellij.plugins.csv.CsvEscapeCharacter;
import net.seesharpsoft.intellij.plugins.csv.components.CsvFileAttributes;
import net.seesharpsoft.intellij.plugins.csv.editor.CsvEditorSettings;
import org.jetbrains.annotations.NotNull;

public class CsvChangeEscapeCharacterAction extends ToggleAction {
private CsvEditorSettings.EscapeCharacter myEscapeCharacter;
private CsvEscapeCharacter myEscapeCharacter;

CsvChangeEscapeCharacterAction(CsvEditorSettings.EscapeCharacter escapeCharacter) {
CsvChangeEscapeCharacterAction(CsvEscapeCharacter escapeCharacter) {
super(escapeCharacter.getDisplay());
myEscapeCharacter = escapeCharacter;
}
Expand Down
Expand Up @@ -6,9 +6,9 @@
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.psi.PsiFile;
import net.seesharpsoft.intellij.plugins.csv.CsvEscapeCharacter;
import net.seesharpsoft.intellij.plugins.csv.CsvLanguage;
import net.seesharpsoft.intellij.plugins.csv.components.CsvFileAttributes;
import net.seesharpsoft.intellij.plugins.csv.editor.CsvEditorSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -17,9 +17,9 @@ public class CsvChangeEscapeCharacterActionGroup extends ActionGroup {
private static final AnAction[] CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS;

static {
CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS = new AnAction[CsvEditorSettings.EscapeCharacter.values().length + 1];
CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS = new AnAction[CsvEscapeCharacter.values().length + 1];
for (int i = 0; i < CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS.length - 1; ++i) {
CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS[i] = new CsvChangeEscapeCharacterAction(CsvEditorSettings.EscapeCharacter.values()[i]);
CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS[i] = new CsvChangeEscapeCharacterAction(CsvEscapeCharacter.values()[i]);
}
CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS[CSV_ESCAPE_CHARACTER_CHANGE_ACTIONS.length - 1] = new CsvDefaultEscapeCharacterAction();
}
Expand All @@ -31,7 +31,7 @@ public void update(AnActionEvent anActionEvent) {
anActionEvent.getPresentation().setEnabledAndVisible(psiFile != null && language != null && language.isKindOf(CsvLanguage.INSTANCE));

if (psiFile != null) {
CsvEditorSettings.EscapeCharacter escapeCharacter = CsvFileAttributes.getInstance(psiFile.getProject()).getEscapeCharacter(psiFile);
CsvEscapeCharacter escapeCharacter = CsvFileAttributes.getInstance(psiFile.getProject()).getEscapeCharacter(psiFile);
anActionEvent.getPresentation().setText(String.format("CSV Escape Character: %s", escapeCharacter.getDisplay()));
}
}
Expand Down
Expand Up @@ -11,15 +11,15 @@
import com.intellij.util.FileContentUtilCore;
import net.seesharpsoft.intellij.plugins.csv.CsvLanguage;
import net.seesharpsoft.intellij.plugins.csv.CsvSeparatorHolder;
import net.seesharpsoft.intellij.plugins.csv.CsvValueSeparator;
import net.seesharpsoft.intellij.plugins.csv.components.CsvFileAttributes;
import net.seesharpsoft.intellij.plugins.csv.settings.CsvCodeStyleSettings;
import org.jetbrains.annotations.NotNull;

public class CsvChangeSeparatorAction extends ToggleAction {
private String mySeparator;
private CsvValueSeparator mySeparator;

CsvChangeSeparatorAction(String separator, String mySeparatorTextArg) {
super(mySeparatorTextArg);
CsvChangeSeparatorAction(CsvValueSeparator separator) {
super(separator.getDisplay());
mySeparator = separator;
}

Expand All @@ -30,7 +30,7 @@ public boolean isSelected(@NotNull AnActionEvent anActionEvent) {
return false;
}
CsvFileAttributes csvFileAttributes = ServiceManager.getService(psiFile.getProject(), CsvFileAttributes.class);
return csvFileAttributes.getFileSeparator(psiFile) != null && CsvCodeStyleSettings.getCurrentSeparator(anActionEvent.getProject(), psiFile).equals(mySeparator);
return csvFileAttributes.getFileSeparator(psiFile) != null && csvFileAttributes.getFileSeparator(psiFile).equals(mySeparator);
}

@Override
Expand Down
Expand Up @@ -6,9 +6,10 @@
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.psi.PsiFile;
import net.seesharpsoft.intellij.plugins.csv.CsvHelper;
import net.seesharpsoft.intellij.plugins.csv.CsvLanguage;
import net.seesharpsoft.intellij.plugins.csv.CsvSeparatorHolder;
import net.seesharpsoft.intellij.plugins.csv.settings.CsvCodeStyleSettings;
import net.seesharpsoft.intellij.plugins.csv.CsvValueSeparator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -17,9 +18,9 @@ public class CsvChangeSeparatorActionGroup extends ActionGroup {
private static final AnAction[] CSV_SEPARATOR_CHANGE_ACTIONS;

static {
CSV_SEPARATOR_CHANGE_ACTIONS = new AnAction[CsvCodeStyleSettings.SUPPORTED_SEPARATORS.length + 1];
CSV_SEPARATOR_CHANGE_ACTIONS = new AnAction[CsvValueSeparator.values().length + 1];
for (int i = 0; i < CSV_SEPARATOR_CHANGE_ACTIONS.length - 1; ++i) {
CSV_SEPARATOR_CHANGE_ACTIONS[i] = new CsvChangeSeparatorAction(CsvCodeStyleSettings.SUPPORTED_SEPARATORS[i], CsvCodeStyleSettings.SUPPORTED_SEPARATORS_DISPLAY[i]);
CSV_SEPARATOR_CHANGE_ACTIONS[i] = new CsvChangeSeparatorAction(CsvValueSeparator.values()[i]);
}
CSV_SEPARATOR_CHANGE_ACTIONS[CSV_SEPARATOR_CHANGE_ACTIONS.length - 1] = new CsvDefaultSeparatorAction();
}
Expand All @@ -35,7 +36,7 @@ public void update(AnActionEvent anActionEvent) {
if (psiFile != null) {
anActionEvent.getPresentation()
.setText(String.format("CSV Value Separator: %s",
CsvCodeStyleSettings.getSeparatorDisplayText(CsvCodeStyleSettings.getCurrentSeparator(anActionEvent.getProject(), psiFile)))
CsvHelper.getCurrentValueSeparator(psiFile).getDisplay())
);
}
}
Expand Down
@@ -1,6 +1,5 @@
package net.seesharpsoft.intellij.plugins.csv.actions;

import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
Expand All @@ -9,8 +8,6 @@
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.psi.PsiFile;
import com.intellij.util.FileContentUtilCore;
import net.seesharpsoft.intellij.plugins.csv.CsvLanguage;
import net.seesharpsoft.intellij.plugins.csv.CsvSeparatorHolder;
import net.seesharpsoft.intellij.plugins.csv.components.CsvFileAttributes;
import org.jetbrains.annotations.NotNull;

Expand All @@ -35,12 +32,8 @@ public void setSelected(@NotNull AnActionEvent anActionEvent, boolean selected)
if (psiFile == null) {
return;
}
Language language = psiFile.getLanguage();
if (!language.isKindOf(CsvLanguage.INSTANCE) || language instanceof CsvSeparatorHolder) {
return;
}
CsvFileAttributes csvFileAttributes = ServiceManager.getService(psiFile.getProject(), CsvFileAttributes.class);
csvFileAttributes.removeFileSeparator(psiFile);

CsvFileAttributes.getInstance(psiFile.getProject()).resetValueSeparator(psiFile);
FileContentUtilCore.reparseFiles(psiFile.getVirtualFile());

FileEditor fileEditor = anActionEvent.getData(PlatformDataKeys.FILE_EDITOR);
Expand Down

0 comments on commit c5a6fb5

Please sign in to comment.