Skip to content

Commit ad02cbc

Browse files
committedDec 15, 2024
Ninth commit
1 parent a34b181 commit ad02cbc

22 files changed

+547
-222
lines changed
 

‎.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ scriptor.log
99
whatsnew.txt
1010
scriptor.xml
1111
scriptor.zip
12-
archives
12+
archives
13+
ignore

‎pom.xml

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616
<dependencies>
1717
<dependency>
18-
<groupId>org.commonmark</groupId>
19-
<artifactId>commonmark-ext-gfm-tables</artifactId>
20-
<version>0.24.0</version>
18+
<groupId>org.xerial</groupId>
19+
<artifactId>sqlite-jdbc</artifactId>
20+
<version>3.47.1.0</version>
2121
</dependency>
2222
<dependency>
2323
<groupId>org.commonmark</groupId>

‎resources/process_run_previous.gif

590 Bytes
Loading

‎resources/process_stop_all.gif

364 Bytes
Loading

‎resources/sqlite_viewer.png

514 Bytes
Loading

‎src/main/java/com/scriptor/AutocompleteExample.java

-92
This file was deleted.

‎src/main/java/com/scriptor/Scriptor.java

+13-4
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ public class Scriptor extends JFrame implements ActionListener {
5151
public Scriptor() {
5252
logger.clearAll();
5353

54+
logger.insert("Loading plugins...");
5455
pluginsHandler.loadPlugins();
56+
logger.insert("Loaded " + pluginsHandler.getPlugins().size() + " plugins.");
5557

58+
logger.insert("Loading frame...");
5659
setTitle("Scriptor");
5760
setSize(1400, 800);
5861
setDefaultCloseOperation(EXIT_ON_CLOSE);
@@ -184,13 +187,19 @@ public void windowClosing(WindowEvent e) {
184187
});
185188

186189
// Others
187-
textAreaTabManager.openPreviousTabs();
190+
if (config.getOpenPreviousFilesOnStartup()) {
191+
textAreaTabManager.openPreviousTabs();
192+
} else {
193+
textAreaTabManager.newFile();
194+
}
188195

189196
new ScriptorKeybinds(this, textAreaTabPane);
190197

191198
updateStatusBar();
192199

193200
newWelcomeNotification();
201+
202+
logger.insert("Loaded frame, Scriptor is now ready to use.");
194203
}
195204

196205
public static void main(String[] args) {
@@ -205,20 +214,20 @@ public static void main(String[] args) {
205214
}
206215

207216
public static String getVersion() {
208-
return "2024.12.09-1";
217+
return "1.0.0-prerelease-1";
209218
}
210219

211220
public void setSystemLookAndFeel() {
212221
try {
213222
try {
214223
UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
215224
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
216-
e.printStackTrace();
225+
logger.insert(e.toString());
217226
}
218227

219228
SwingUtilities.updateComponentTreeUI(this);
220229
} catch (UnsupportedLookAndFeelException e) {
221-
e.printStackTrace();
230+
logger.insert(e.toString());
222231
}
223232
}
224233

‎src/main/java/com/scriptor/core/config/ScriptorConfig.java

+34
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ public boolean getSyntaxHighlightingEnabled() {
9595
return structure.getSyntaxHighlighting();
9696
}
9797

98+
public boolean getBookmarkingEnabled() {
99+
return structure.getBookmarking();
100+
}
101+
102+
public boolean getMarkOccurrencesEnabled() {
103+
return structure.getMarkOccurrences();
104+
}
105+
98106
public int getLanguage() {
99107
return structure.getLanguage();
100108
}
@@ -233,6 +241,26 @@ public void setAutoIndent(boolean value) {
233241
}
234242
}
235243

244+
public void setBookmarkingEnabled(boolean value) {
245+
structure.setBookmarking(value);
246+
247+
try {
248+
save();
249+
} catch (IOException e) {
250+
e.printStackTrace();
251+
}
252+
}
253+
254+
public void setMarkOccurrencesEnabled(boolean value) {
255+
structure.setMarkOccurrences(value);
256+
257+
try {
258+
save();
259+
} catch (IOException e) {
260+
e.printStackTrace();
261+
}
262+
}
263+
236264
public void setBracketMatching(boolean value) {
237265
structure.setBracketMatching(value);
238266

@@ -309,6 +337,12 @@ public void setDefault() throws IOException {
309337
structure.setPaths(new ArrayList<String>());
310338
structure.setExtended(false);
311339
structure.setZoom(12);
340+
structure.setOpenPreviousFilesOnStartup(true);
341+
structure.setAutoSaveFileEdits(false);
342+
structure.setBracketMatching(true);
343+
structure.setSyntaxHighlighting(true);
344+
structure.setAutoIndent(true);
345+
structure.setBookmarking(true);
312346
structure.setIndentTabSize(4);
313347
structure.setExpandedFolders(new ArrayList<String>());
314348
structure.setWindowPosition(new ArrayList<Double>());

‎src/main/java/com/scriptor/core/config/ScriptorConfigStructure.java

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public class ScriptorConfigStructure {
99
private boolean openPreviousFilesOnStartup;
1010
private boolean autoSaveFileEdits;
1111
private boolean autoIndent;
12+
private boolean bookMarking;
13+
private boolean markOccurrences;
1214
private int indentTabSize;
1315
private boolean bracketMatching;
1416
private boolean syntaxHighlighting;
@@ -50,6 +52,12 @@ public class ScriptorConfigStructure {
5052
public boolean getSyntaxHighlighting() { return syntaxHighlighting; }
5153
public void setSyntaxHighlighting(boolean value) { this.syntaxHighlighting = value; }
5254

55+
public boolean getBookmarking() { return bookMarking; }
56+
public void setBookmarking(boolean value) { this.bookMarking = value; }
57+
58+
public boolean getMarkOccurrences() { return markOccurrences; }
59+
public void setMarkOccurrences(boolean value) { this.markOccurrences = value; }
60+
5361
public int getLanguage() { return language; }
5462
public void setLanguage(int languageId) { this.language = languageId; }
5563

‎src/main/java/com/scriptor/core/gui/frames/ScriptorInformation.java

+50-2
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,18 @@ public ScriptorInformation(Scriptor scriptor) {
4343
tab2.setUI(new VerticalLabelUI(false));
4444
tabbedPane.setTabComponentAt(1, tab2);
4545

46-
tabbedPane.addTab("License", createLicenseInfoPanel());
47-
JLabel tab3 = new JLabel(" License ");
46+
tabbedPane.addTab("Dependencies", createDependenciesInfoPanel());
47+
JLabel tab3 = new JLabel(" Dependencies ");
4848
tab3.setFont(new Font(tab3.getFont().getName(), Font.BOLD, 12));
4949
tab3.setUI(new VerticalLabelUI(false));
5050
tabbedPane.setTabComponentAt(2, tab3);
5151

52+
tabbedPane.addTab("License", createLicenseInfoPanel());
53+
JLabel tab4 = new JLabel(" License ");
54+
tab4.setFont(new Font(tab4.getFont().getName(), Font.BOLD, 12));
55+
tab4.setUI(new VerticalLabelUI(false));
56+
tabbedPane.setTabComponentAt(3, tab4);
57+
5258
splitPane.setLeftComponent(tabbedPane);
5359

5460
add(tabbedPane);
@@ -68,6 +74,7 @@ private JPanel createGeneralInfoPanel() {
6874

6975
data.add("Version: " + Scriptor.getVersion());
7076
data.add("Written in: Java (100%)");
77+
data.add("Build tool: Maven");
7178
data.add("License: The MIT License");
7279

7380
String dataString = "";
@@ -126,6 +133,47 @@ private JPanel createContributorsInfoPanel() {
126133
return panel;
127134
}
128135

136+
private JPanel createDependenciesInfoPanel() {
137+
JPanel panel = new JPanel();
138+
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
139+
140+
JTextArea textArea = new JTextArea();
141+
textArea.setBorder(new EmptyBorder(0, 5, 0, 0));
142+
textArea.setLineWrap(true);
143+
144+
List<String> dependencies = new ArrayList<String>();
145+
146+
dependencies.add("com.fasterxml.jackson.core: jackson-databind");
147+
dependencies.add("com.fifesoft: rsyntaxtextarea");
148+
dependencies.add("com.fifesoft: autocomplete");
149+
dependencies.add("commons-io: commons-io");
150+
dependencies.add("org.apache.xmlgraphics: batik-codec");
151+
dependencies.add("org.commonmark: commonmark");
152+
dependencies.add("org.json: json");
153+
dependencies.add("org.xerial: sqlite-jdbc");
154+
155+
String dependenciesListString = "";
156+
157+
for (String dependency : dependencies) {
158+
dependenciesListString += "• " + dependency + "\n";
159+
}
160+
161+
textArea.setText("The list of dependencies used to make Scriptor:\r\n" + dependenciesListString);
162+
163+
JScrollPane sp = new JScrollPane(textArea);
164+
165+
SwingUtilities.invokeLater(() -> {
166+
JScrollBar verticalScrollBar = sp.getVerticalScrollBar();
167+
verticalScrollBar.setValue(verticalScrollBar.getMinimum());
168+
});
169+
170+
textArea.setEditable(false);
171+
172+
panel.add(sp);
173+
174+
return panel;
175+
}
176+
129177
private JPanel createLicenseInfoPanel() {
130178
JPanel panel = new JPanel();
131179
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

‎src/main/java/com/scriptor/core/gui/frames/ScriptorMarkdownViewer.java

+16-17
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import java.awt.*;
1212
import java.io.*;
13+
import java.nio.charset.StandardCharsets;
1314
import java.nio.file.Files;
1415
import java.nio.file.Paths;
1516

@@ -20,7 +21,7 @@ public ScriptorMarkdownViewer(Scriptor scriptor, String path) {
2021
this.scriptor = scriptor;
2122

2223
setTitle("Markdown Viewer - " + path);
23-
setSize(800, 600);
24+
setSize(1000, 800);
2425
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
2526
setLocationRelativeTo(null);
2627

@@ -33,27 +34,25 @@ public ScriptorMarkdownViewer(Scriptor scriptor, String path) {
3334
JScrollPane scrollPane = new JScrollPane(editorPane);
3435
add(scrollPane, BorderLayout.CENTER);
3536

36-
System.out.println(path);
37+
try {
38+
BufferedReader reader = new BufferedReader(
39+
new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8));
40+
StringBuilder sb = new StringBuilder();
41+
String line = reader.readLine();
3742

38-
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
39-
try {
40-
StringBuilder sb = new StringBuilder();
41-
String line = br.readLine();
43+
while (line != null) {
44+
sb.append(line);
45+
sb.append(System.lineSeparator());
46+
line = reader.readLine();
47+
}
4248

43-
while (line != null) {
44-
sb.append(line);
45-
sb.append(System.lineSeparator());
46-
line = br.readLine();
47-
}
49+
String markdownText = sb.toString();
4850

49-
String markdownText = sb.toString();
51+
editorPane.setText(convertToMarkdown(markdownText, readFile("./resources/github.css")));
5052

51-
editorPane.setText(convertToMarkdown(markdownText, readFile("./resources/github.css")));
52-
} finally {
53-
br.close();
54-
}
53+
reader.close();
5554
} catch (IOException e) {
56-
e.printStackTrace();
55+
scriptor.logger.insert(e.toString());
5756
}
5857

5958
setVisible(true);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package com.scriptor.core.gui.frames;
2+
3+
import javax.swing.*;
4+
import javax.swing.filechooser.FileFilter;
5+
import javax.swing.table.DefaultTableModel;
6+
7+
import com.scriptor.Scriptor;
8+
9+
import java.awt.*;
10+
import java.awt.event.ActionEvent;
11+
import java.awt.event.ActionListener;
12+
import java.io.File;
13+
import java.sql.*;
14+
import java.util.Vector;
15+
16+
public class ScriptorSQLiteViewer extends JFrame {
17+
private Scriptor scriptor;
18+
private Connection connection;
19+
private JComboBox<String> tablesComboBox;
20+
private JTable dataTable;
21+
private DefaultTableModel tableModel;
22+
23+
public ScriptorSQLiteViewer(Scriptor scriptor, String path) {
24+
this.scriptor = scriptor;
25+
26+
setTitle("SQLite Viewer - " + (path == null ? "Null" : path));
27+
setSize(1000, 800);
28+
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
29+
setLocationRelativeTo(null);
30+
31+
setIconImage(this.scriptor.getIcon("scriptor_icon.png").getImage());
32+
33+
// Layout setup
34+
setLayout(new BorderLayout());
35+
36+
// Top Panel
37+
JPanel topPanel = new JPanel(new BorderLayout());
38+
JButton openFileButton = new JButton("Open File");
39+
openFileButton.setFocusable(false);
40+
41+
tablesComboBox = new JComboBox<>();
42+
tablesComboBox.setEnabled(false);
43+
tablesComboBox.setFocusable(false);
44+
topPanel.add(openFileButton, BorderLayout.WEST);
45+
topPanel.add(tablesComboBox, BorderLayout.EAST);
46+
47+
// Data Table
48+
tableModel = new DefaultTableModel();
49+
dataTable = new JTable(tableModel);
50+
dataTable.setFocusable(false);
51+
dataTable.setEnabled(false);
52+
53+
JScrollPane tableScrollPane = new JScrollPane(dataTable);
54+
55+
add(topPanel, BorderLayout.NORTH);
56+
add(tableScrollPane, BorderLayout.CENTER);
57+
58+
// Button Action: Open SQLite File
59+
openFileButton.addActionListener(new ActionListener() {
60+
@Override
61+
public void actionPerformed(ActionEvent e) {
62+
openSQLiteFile();
63+
}
64+
});
65+
66+
// ComboBox Action: Select Table
67+
tablesComboBox.addActionListener(new ActionListener() {
68+
@Override
69+
public void actionPerformed(ActionEvent e) {
70+
String selectedTable = (String) tablesComboBox.getSelectedItem();
71+
if (selectedTable != null) {
72+
loadTableData(selectedTable);
73+
}
74+
}
75+
});
76+
77+
if (path != null) {
78+
connectToDatabase(path);
79+
}
80+
81+
setVisible(true);
82+
}
83+
84+
private void openSQLiteFile() {
85+
JFileChooser fileChooser = new JFileChooser();
86+
fileChooser.setDialogTitle("Select SQLite Database File");
87+
fileChooser.setCurrentDirectory(new File(scriptor.config.getDirectoryPath()));
88+
fileChooser.setFileFilter(new FileFilter() {
89+
@Override
90+
public boolean accept(File f) {
91+
if (f.isDirectory()) {
92+
return true;
93+
} else {
94+
String filename = f.getName().toLowerCase();
95+
96+
return filename.endsWith(".sql") || filename.endsWith(".sqlite") || filename.endsWith(".db");
97+
}
98+
}
99+
100+
@Override
101+
public String getDescription() {
102+
return "SQL File (*.sql, *.sqlite, *.db)";
103+
}
104+
});
105+
int result = fileChooser.showOpenDialog(this);
106+
107+
if (result == JFileChooser.APPROVE_OPTION) {
108+
File file = fileChooser.getSelectedFile();
109+
connectToDatabase(file.getAbsolutePath());
110+
}
111+
}
112+
113+
private void connectToDatabase(String dbFilePath) {
114+
try {
115+
if (connection != null) {
116+
connection.close();
117+
}
118+
119+
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
120+
121+
loadTableNames(dbFilePath);
122+
} catch (SQLException e) {
123+
JOptionPane.showMessageDialog(this, "Error connecting to database: " + e.getMessage(), "Error",
124+
JOptionPane.ERROR_MESSAGE);
125+
}
126+
}
127+
128+
private void loadTableNames(String dbFilePath) {
129+
try (Statement stmt = connection.createStatement()) {
130+
ResultSet rs = stmt
131+
.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';");
132+
133+
tablesComboBox.removeAllItems();
134+
while (rs.next()) {
135+
tablesComboBox.addItem(rs.getString("name"));
136+
}
137+
138+
tablesComboBox.setEnabled(true);
139+
140+
setTitle("SQLite Viewer - " + dbFilePath);
141+
} catch (SQLException e) {
142+
JOptionPane.showMessageDialog(this, "Error loading table names: " + e.getMessage(), "Error",
143+
JOptionPane.ERROR_MESSAGE);
144+
}
145+
}
146+
147+
private void loadTableData(String tableName) {
148+
try (Statement stmt = connection.createStatement()) {
149+
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
150+
151+
// Get column names
152+
ResultSetMetaData metaData = rs.getMetaData();
153+
int columnCount = metaData.getColumnCount();
154+
Vector<String> columnNames = new Vector<>();
155+
for (int i = 1; i <= columnCount; i++) {
156+
columnNames.add(metaData.getColumnName(i));
157+
}
158+
159+
// Get row data
160+
Vector<Vector<Object>> rowData = new Vector<>();
161+
while (rs.next()) {
162+
Vector<Object> row = new Vector<>();
163+
for (int i = 1; i <= columnCount; i++) {
164+
row.add(rs.getObject(i));
165+
}
166+
rowData.add(row);
167+
}
168+
169+
// Update table model
170+
tableModel.setDataVector(rowData, columnNames);
171+
} catch (SQLException e) {
172+
JOptionPane.showMessageDialog(this, "Error loading table data: " + e.getMessage(), "Error",
173+
JOptionPane.ERROR_MESSAGE);
174+
}
175+
}
176+
}

‎src/main/java/com/scriptor/core/gui/frames/ScriptorSettings.java

+30-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ private JPanel createGeneralSettingsPanel() {
6262
JPanel panel = new JPanel();
6363
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
6464

65+
JLabel __warning = new JLabel("Any changes will be saved automatically, but requires to restart the application to apply changes!");
66+
__warning.setBorder(new EmptyBorder(5, 10, 0, 0));
67+
panel.add(__warning);
68+
6569
String languages[] = { "English US" };
6670
JComboBox<String> languageComboBox = new JComboBox<String>(languages);
6771
languageComboBox.setSelectedIndex(0);
@@ -120,6 +124,10 @@ private JPanel createEditorSettingsPanel() {
120124
JPanel panel = new JPanel();
121125
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
122126

127+
JLabel __warning = new JLabel("Any changes will be saved automatically, but requires to restart the application to apply changes!");
128+
__warning.setBorder(new EmptyBorder(5, 10, 0, 0));
129+
panel.add(__warning);
130+
123131
JCheckBox autoIndentCheckBox = new JCheckBox();
124132
autoIndentCheckBox.setSelected(scriptor.config.getAutoIndent());
125133
autoIndentCheckBox.addActionListener(new ActionListener() {
@@ -140,7 +148,6 @@ public void actionPerformed(ActionEvent e) {
140148
scriptor.config.setIndentTabSize(tabSizeComboBox.getSelectedIndex() + 1);
141149
}
142150
});
143-
tabSizeComboBox.setSelectedIndex(3);
144151
JLabel languageLabel = new JLabel("Indent Tab size: ");
145152
languageLabel.setBorder(new EmptyBorder(0, 5, 0, 0));
146153
panel.add(newJPanelLeftLayout(languageLabel, tabSizeComboBox));
@@ -167,6 +174,28 @@ public void actionPerformed(ActionEvent e) {
167174
JLabel syntaxHighlightingEnabledLabel = new JLabel("Enable Syntax Highlighting");
168175
panel.add(newJPanelLeftLayout(syntaxHighlightingEnabledCheckBox, syntaxHighlightingEnabledLabel));
169176

177+
JCheckBox bookmarkingCheckBox = new JCheckBox();
178+
bookmarkingCheckBox.setSelected(scriptor.config.getBookmarkingEnabled());
179+
bookmarkingCheckBox.addActionListener(new ActionListener() {
180+
@Override
181+
public void actionPerformed(ActionEvent e) {
182+
scriptor.config.setBookmarkingEnabled(bookmarkingCheckBox.isSelected());
183+
}
184+
});
185+
JLabel bookmakingLabel = new JLabel("Enable Bookmarking");
186+
panel.add(newJPanelLeftLayout(bookmarkingCheckBox, bookmakingLabel));
187+
188+
JCheckBox markOccurrencesCheckBox = new JCheckBox();
189+
markOccurrencesCheckBox.setSelected(scriptor.config.getMarkOccurrencesEnabled());
190+
markOccurrencesCheckBox.addActionListener(new ActionListener() {
191+
@Override
192+
public void actionPerformed(ActionEvent e) {
193+
scriptor.config.setMarkOccurrencesEnabled(markOccurrencesCheckBox.isSelected());
194+
}
195+
});
196+
JLabel markOccurrencesLabel = new JLabel("Enable Mark Occurrences");
197+
panel.add(newJPanelLeftLayout(markOccurrencesCheckBox, markOccurrencesLabel));
198+
170199
return panel;
171200
}
172201

‎src/main/java/com/scriptor/core/gui/frames/ScriptorWhatsNew.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public ScriptorWhatsNew(Scriptor scriptor) {
4747
br.close();
4848
}
4949
} catch (IOException e) {
50-
e.printStackTrace();
50+
scriptor.logger.insert(e.toString());
5151
}
5252

5353
JCheckBox checkBox = new JCheckBox("Never show this again on startup.");

‎src/main/java/com/scriptor/core/gui/menus/ScriptorMenubar.java

+64-40
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.scriptor.Scriptor;
1313
import com.scriptor.core.gui.frames.ScriptorInformation;
1414
import com.scriptor.core.gui.frames.ScriptorMarkdownViewer;
15+
import com.scriptor.core.gui.frames.ScriptorSQLiteViewer;
1516
import com.scriptor.core.utils.JClosableComponentType;
1617

1718
public class ScriptorMenubar extends JMenuBar {
@@ -21,7 +22,7 @@ public ScriptorMenubar(Scriptor scriptor) {
2122
*/
2223
JMenu fileMenu = new JMenu("File");
2324

24-
JMenuItem menuItemNewFile = createMenuItem("New File", scriptor.getIcon("new_file.png"), TOOL_TIP_TEXT_KEY,
25+
JMenuItem menuItemNewFile = createMenuItem("New File", scriptor.getIcon("new_file.png"), null,
2526
KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK));
2627
menuItemNewFile.addActionListener(new ActionListener() {
2728
@Override
@@ -30,7 +31,7 @@ public void actionPerformed(ActionEvent e) {
3031
}
3132
});
3233

33-
JMenuItem menuItemOpenFile = createMenuItem("Open File", scriptor.getIcon("file_open.png"), TOOL_TIP_TEXT_KEY,
34+
JMenuItem menuItemOpenFile = createMenuItem("Open File", scriptor.getIcon("file_open.png"), null,
3435
KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));
3536
menuItemOpenFile.addActionListener(new ActionListener() {
3637
@Override
@@ -40,15 +41,15 @@ public void actionPerformed(ActionEvent e) {
4041
});
4142

4243
JMenuItem menuItemOpenFolder = createMenuItem("Open Folder", scriptor.getIcon("folder_open.png"),
43-
TOOL_TIP_TEXT_KEY, null);
44+
null, null);
4445
menuItemOpenFolder.addActionListener(new ActionListener() {
4546
@Override
4647
public void actionPerformed(ActionEvent e) {
4748
scriptor.textAreaTabManager.openFolder();
4849
}
4950
});
5051

51-
JMenuItem menuItemSave = createMenuItem("Save", scriptor.getIcon("save.gif"), TOOL_TIP_TEXT_KEY,
52+
JMenuItem menuItemSave = createMenuItem("Save", scriptor.getIcon("save.gif"), null,
5253
KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK));
5354
menuItemSave.addActionListener(new ActionListener() {
5455
@Override
@@ -57,7 +58,7 @@ public void actionPerformed(ActionEvent e) {
5758
}
5859
});
5960

60-
JMenuItem menuItemSaveAs = createMenuItem("Save As", scriptor.getIcon("saveas.gif"), TOOL_TIP_TEXT_KEY,
61+
JMenuItem menuItemSaveAs = createMenuItem("Save As", scriptor.getIcon("saveas.gif"), null,
6162
KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK));
6263
menuItemSaveAs.addActionListener(new ActionListener() {
6364
@Override
@@ -66,7 +67,7 @@ public void actionPerformed(ActionEvent e) {
6667
}
6768
});
6869

69-
JMenuItem menuItemSaveAll = createMenuItem("Save All", scriptor.getIcon("saveall.gif"), TOOL_TIP_TEXT_KEY,
70+
JMenuItem menuItemSaveAll = createMenuItem("Save All", scriptor.getIcon("saveall.gif"), null,
7071
null);
7172
menuItemSaveAll.addActionListener(new ActionListener() {
7273
@Override
@@ -75,28 +76,18 @@ public void actionPerformed(ActionEvent e) {
7576
}
7677
});
7778

78-
JMenuItem menuItemCloseTab = createMenuItem("Close Tab", scriptor.getIcon("close_tab.png"), TOOL_TIP_TEXT_KEY,
79+
JMenuItem menuItemCloseApp = createMenuItem("Exit", scriptor.getIcon("delete.gif"), null,
7980
null);
80-
menuItemCloseTab.addActionListener(new ActionListener() {
81+
menuItemCloseApp.addActionListener(new ActionListener() {
8182
@Override
8283
public void actionPerformed(ActionEvent e) {
83-
int index = scriptor.textAreaTabManager.getCurrentIndex();
84-
85-
if (index != 1) {
86-
scriptor.textAreaTabManager.closeTabByIndex(index);
84+
if (scriptor.isDisplayable()) {
85+
scriptor.dispose();
86+
System.exit(0);
8787
}
8888
}
8989
});
9090

91-
JMenuItem menuItemCloseAllTabs = createMenuItem("Close All Tabs", scriptor.getIcon("close_all_tabs.png"),
92-
TOOL_TIP_TEXT_KEY, null);
93-
menuItemCloseAllTabs.addActionListener(new ActionListener() {
94-
@Override
95-
public void actionPerformed(ActionEvent e) {
96-
scriptor.textAreaTabManager.closeAllTabs();
97-
}
98-
});
99-
10091
fileMenu.add(menuItemNewFile);
10192
fileMenu.addSeparator();
10293
fileMenu.add(menuItemOpenFile);
@@ -106,16 +97,15 @@ public void actionPerformed(ActionEvent e) {
10697
fileMenu.add(menuItemSaveAs);
10798
fileMenu.add(menuItemSaveAll);
10899
fileMenu.addSeparator();
109-
fileMenu.add(menuItemCloseTab);
110-
fileMenu.add(menuItemCloseAllTabs);
100+
fileMenu.add(menuItemCloseApp);
111101

112102
/*
113103
* Edit menu
114104
*/
115105

116106
JMenu editMenu = new JMenu("Edit");
117107

118-
JMenuItem menuItemUndo = createMenuItem("Undo", scriptor.getIcon("undo.gif"), TOOL_TIP_TEXT_KEY,
108+
JMenuItem menuItemUndo = createMenuItem("Undo", scriptor.getIcon("undo.gif"), null,
119109
KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_DOWN_MASK));
120110
menuItemUndo.addActionListener(new ActionListener() {
121111
@Override
@@ -128,7 +118,7 @@ public void actionPerformed(ActionEvent e) {
128118
}
129119
});
130120

131-
JMenuItem menuItemRedo = createMenuItem("Redo", scriptor.getIcon("redo.gif"), TOOL_TIP_TEXT_KEY,
121+
JMenuItem menuItemRedo = createMenuItem("Redo", scriptor.getIcon("redo.gif"), null,
132122
KeyStroke.getKeyStroke(KeyEvent.VK_Y, KeyEvent.CTRL_DOWN_MASK));
133123
menuItemRedo.addActionListener(new ActionListener() {
134124
@Override
@@ -141,7 +131,7 @@ public void actionPerformed(ActionEvent e) {
141131
}
142132
});
143133

144-
JMenuItem menuItemCut = createMenuItem("Cut", scriptor.getIcon("cut.gif"), TOOL_TIP_TEXT_KEY,
134+
JMenuItem menuItemCut = createMenuItem("Cut", scriptor.getIcon("cut.gif"), null,
145135
KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_DOWN_MASK));
146136
menuItemCut.addActionListener(new ActionListener() {
147137
@Override
@@ -152,7 +142,7 @@ public void actionPerformed(ActionEvent e) {
152142
}
153143
});
154144

155-
JMenuItem menuItemCopy = createMenuItem("Copy", scriptor.getIcon("copy.gif"), TOOL_TIP_TEXT_KEY,
145+
JMenuItem menuItemCopy = createMenuItem("Copy", scriptor.getIcon("copy.gif"), null,
156146
KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK));
157147
menuItemCopy.addActionListener(new ActionListener() {
158148
@Override
@@ -163,7 +153,7 @@ public void actionPerformed(ActionEvent e) {
163153
}
164154
});
165155

166-
JMenuItem menuItemPaste = createMenuItem("Paste", scriptor.getIcon("paste.gif"), TOOL_TIP_TEXT_KEY,
156+
JMenuItem menuItemPaste = createMenuItem("Paste", scriptor.getIcon("paste.gif"), null,
167157
KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK));
168158
menuItemPaste.addActionListener(new ActionListener() {
169159
@Override
@@ -174,7 +164,7 @@ public void actionPerformed(ActionEvent e) {
174164
}
175165
});
176166

177-
JMenuItem menuItemDelete = createMenuItem("Delete", scriptor.getIcon("trash.gif"), TOOL_TIP_TEXT_KEY,
167+
JMenuItem menuItemDelete = createMenuItem("Delete", scriptor.getIcon("trash.gif"), null,
178168
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
179169
menuItemDelete.addActionListener(new ActionListener() {
180170
@Override
@@ -185,7 +175,7 @@ public void actionPerformed(ActionEvent e) {
185175
}
186176
});
187177

188-
JMenuItem menuItemSelectAll = createMenuItem("Select All", null, TOOL_TIP_TEXT_KEY,
178+
JMenuItem menuItemSelectAll = createMenuItem("Select All", null, null,
189179
KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK));
190180
menuItemSelectAll.addActionListener(new ActionListener() {
191181
@Override
@@ -212,7 +202,7 @@ public void actionPerformed(ActionEvent e) {
212202
JMenu viewMenu = new JMenu("View");
213203

214204
JMenuItem menuItemOpenExplorer = createMenuItem("Open Explorer", scriptor.getIcon("tree_explorer.gif"),
215-
TOOL_TIP_TEXT_KEY,
205+
null,
216206
KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK));
217207
menuItemOpenExplorer.addActionListener(new ActionListener() {
218208
@Override
@@ -222,7 +212,7 @@ public void actionPerformed(ActionEvent e) {
222212
});
223213

224214
JMenuItem menuItemOpenTerminal = createMenuItem("Open Terminal", scriptor.getIcon("console.gif"),
225-
TOOL_TIP_TEXT_KEY,
215+
null,
226216
KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK));
227217
menuItemOpenTerminal.addActionListener(new ActionListener() {
228218
@Override
@@ -231,8 +221,17 @@ public void actionPerformed(ActionEvent e) {
231221
}
232222
});
233223

224+
viewMenu.add(menuItemOpenExplorer);
225+
viewMenu.add(menuItemOpenTerminal);
226+
227+
/*
228+
* Tools menu
229+
*/
230+
231+
JMenu toolsMenu = new JMenu("Tools");
232+
234233
JMenuItem menuItemMarkdownViewer = createMenuItem("Markdown Viewer", scriptor.getIcon("markdown_viewer.png"),
235-
TOOL_TIP_TEXT_KEY, null);
234+
null, null);
236235
menuItemMarkdownViewer.addActionListener(new ActionListener() {
237236
@Override
238237
public void actionPerformed(ActionEvent e) {
@@ -249,14 +248,38 @@ public void actionPerformed(ActionEvent e) {
249248
"Markdown Viewer",
250249
WARNING_MESSAGE);
251250
}
251+
} else {
252+
showMessageDialog(scriptor, "The current file is not a markdown or a plain text file.",
253+
"Markdown Viewer",
254+
WARNING_MESSAGE);
252255
}
253256
}
254257
});
255258

256-
viewMenu.add(menuItemOpenExplorer);
257-
viewMenu.add(menuItemOpenTerminal);
258-
viewMenu.addSeparator();
259-
viewMenu.add(menuItemMarkdownViewer);
259+
JMenuItem menuItemSQLiteViewer = createMenuItem("SQLite Viewer", scriptor.getIcon("sqlite_viewer.png"),
260+
null, null);
261+
menuItemSQLiteViewer.addActionListener(new ActionListener() {
262+
@Override
263+
public void actionPerformed(ActionEvent e) {
264+
String path = scriptor.textAreaTabManager.getCurrentPath();
265+
266+
if (path != null) {
267+
String extension = FilenameUtils.getExtension(path);
268+
269+
if (extension.equalsIgnoreCase("sql") || extension.equalsIgnoreCase("sqlite")
270+
|| extension.equalsIgnoreCase("db")) {
271+
new ScriptorSQLiteViewer(scriptor, path);
272+
} else {
273+
new ScriptorSQLiteViewer(scriptor, null);
274+
}
275+
} else {
276+
new ScriptorSQLiteViewer(scriptor, null);
277+
}
278+
}
279+
});
280+
281+
toolsMenu.add(menuItemMarkdownViewer);
282+
toolsMenu.add(menuItemSQLiteViewer);
260283

261284
/*
262285
* Help menu
@@ -265,17 +288,17 @@ public void actionPerformed(ActionEvent e) {
265288
JMenu helpMenu = new JMenu("Help");
266289

267290
JMenuItem menuItemHelp = createMenuItem("Help?", scriptor.getIcon("help.gif"),
268-
TOOL_TIP_TEXT_KEY,
291+
null,
269292
null);
270293
menuItemHelp.addActionListener(new ActionListener() {
271294
@Override
272295
public void actionPerformed(ActionEvent e) {
273-
296+
274297
}
275298
});
276299

277300
JMenuItem menuItemAbout = createMenuItem("About", scriptor.getIcon("information.png"),
278-
TOOL_TIP_TEXT_KEY,
301+
null,
279302
null);
280303
menuItemAbout.addActionListener(new ActionListener() {
281304
@Override
@@ -295,6 +318,7 @@ public void actionPerformed(ActionEvent e) {
295318
add(fileMenu);
296319
add(editMenu);
297320
add(viewMenu);
321+
add(toolsMenu);
298322
add(helpMenu);
299323
}
300324

‎src/main/java/com/scriptor/core/gui/panels/ScriptorFileExplorer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ private Icon resizeSVGToIcon(String svgFilePath, int width, int height) {
643643

644644
return icon;
645645
} catch (IOException | TranscoderException e) {
646-
e.printStackTrace();
646+
scriptor.logger.insert(e.toString());
647647
return null;
648648
}
649649
}

‎src/main/java/com/scriptor/core/gui/panels/ScriptorPluginsPanel.java

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ public void itemStateChanged(ItemEvent e) {
7474
secondaryPanel.setLayout(new BorderLayout());
7575

7676
JButton editButton = new JButton("Edit JSON");
77-
editButton.setEnabled(!plugin.getSystem());
7877
editButton.setFocusable(false);
7978
editButton.addActionListener(new ActionListener() {
8079
@Override

‎src/main/java/com/scriptor/core/gui/toolbar/ScriptorTerminalToolbar.java

+24-13
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,6 @@ public void actionPerformed(ActionEvent e) {
2828
}
2929
});
3030

31-
JButton buttonCloseCurrentTerminal = createButton(getIcon("close.gif"), "Close Terminal");
32-
buttonCloseCurrentTerminal.addActionListener(new ActionListener() {
33-
@Override
34-
public void actionPerformed(ActionEvent e) {
35-
int index = scriptor.terminalTabManager.getIndex();
36-
37-
scriptor.terminalTabManager.closeTabByIndex(index);
38-
}
39-
});
40-
4131
JButton buttonClearOutput = createButton(getIcon("erase.gif"), "Clear Output");
4232
buttonClearOutput.addActionListener(new ActionListener() {
4333
@Override
@@ -68,6 +58,14 @@ public void actionPerformed(ActionEvent e) {
6858
}
6959
});
7060

61+
JButton buttonProcessStopAll = createButton(getIcon("process_stop_all.gif"), "Stop All Processes");
62+
buttonProcessStopAll.addActionListener(new ActionListener() {
63+
@Override
64+
public void actionPerformed(ActionEvent e) {
65+
scriptor.terminalTabManager.stopAllProcesses();
66+
}
67+
});
68+
7169
JButton buttonCopy = createButton(getIcon("copy.gif"), "Copy Output");
7270
buttonCopy.addActionListener(new ActionListener() {
7371
@Override
@@ -80,8 +78,19 @@ public void actionPerformed(ActionEvent e) {
8078
}
8179
});
8280

81+
JButton buttonRunPreviousCommand = createButton(getIcon("process_run_previous.gif"),
82+
"Run Previous Command");
83+
buttonRunPreviousCommand.addActionListener(new ActionListener() {
84+
@Override
85+
public void actionPerformed(ActionEvent e) {
86+
ScriptorTerminal terminal = scriptor.terminalTabManager.getCurrentTerminal();
87+
88+
terminal.runPreviousCommand();
89+
}
90+
});
91+
8392
JButton buttonExecutedCommandsHistory = createButton(getIcon("executed_commands_history.gif"),
84-
"View commands history");
93+
"View Commands History");
8594
buttonExecutedCommandsHistory.addActionListener(new ActionListener() {
8695
@Override
8796
public void actionPerformed(ActionEvent e) {
@@ -102,8 +111,6 @@ public void actionPerformed(ActionEvent e) {
102111
});
103112

104113
add(buttonNewTerminal);
105-
/*add(Box.createRigidArea(new Dimension(4, 0)));
106-
add(buttonCloseCurrentTerminal);*/
107114
add(Box.createRigidArea(new Dimension(4, 0)));
108115
add(buttonClearOutput);
109116

@@ -114,6 +121,8 @@ public void actionPerformed(ActionEvent e) {
114121
add(buttonProcessRestart);
115122
add(Box.createRigidArea(new Dimension(4, 0)));
116123
add(buttonProcessStop);
124+
add(Box.createRigidArea(new Dimension(4, 0)));
125+
add(buttonProcessStopAll);
117126

118127
add(Box.createRigidArea(new Dimension(4, 0)));
119128
addSeparator(new Dimension(4, 20));
@@ -125,6 +134,8 @@ public void actionPerformed(ActionEvent e) {
125134
addSeparator(new Dimension(4, 20));
126135
add(Box.createRigidArea(new Dimension(4, 0)));
127136

137+
add(buttonRunPreviousCommand);
138+
add(Box.createRigidArea(new Dimension(4, 0)));
128139
add(buttonExecutedCommandsHistory);
129140

130141
JPanel panel = new JPanel();

‎src/main/java/com/scriptor/core/managers/ScriptorTextAreaTabManager.java

+100-39
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.fife.ui.rtextarea.*;
88

99
import com.scriptor.Scriptor;
10+
import com.scriptor.core.gui.frames.ScriptorSQLiteViewer;
1011
import com.scriptor.core.plugins.ScriptorPluginsHandler;
1112
import com.scriptor.core.utils.ScriptorProgrammingLanguagesUtils;
1213

@@ -29,6 +30,7 @@
2930
public class ScriptorTextAreaTabManager {
3031
private final Scriptor scriptor;
3132
private final JTabbedPane tabbedPane;
33+
private Timer autoSaveTimer;
3234

3335
private boolean _switchedTab = false;
3436

@@ -124,7 +126,19 @@ public void openFileFromPath(String path) {
124126

125127
String extension = FilenameUtils.getExtension(file.getPath());
126128

127-
if (!ScriptorProgrammingLanguagesUtils.getSupportedAndEditableExtensions().contains(extension)) {
129+
if (extension.equalsIgnoreCase("sql") || extension.equalsIgnoreCase("sqlite")
130+
|| extension.equalsIgnoreCase("db")) {
131+
int response = showConfirmDialog(null,
132+
"The file was detected to be a SQL file, would you like to open it in SQLite viewer?",
133+
"SQL File Detected",
134+
YES_NO_OPTION);
135+
136+
if (response == YES_OPTION) {
137+
new ScriptorSQLiteViewer(scriptor, path);
138+
139+
return;
140+
}
141+
} else if (!ScriptorProgrammingLanguagesUtils.getSupportedAndEditableExtensions().contains(extension)) {
128142
int response = showConfirmDialog(null,
129143
"The file extension \'." + extension
130144
+ "\' is not supported.\nDo you want to open the file with the default associated program?",
@@ -135,7 +149,7 @@ public void openFileFromPath(String path) {
135149
try {
136150
Desktop.getDesktop().open(file);
137151
} catch (IOException e) {
138-
e.printStackTrace();
152+
scriptor.logger.insert(e.toString());
139153
}
140154

141155
return;
@@ -176,8 +190,8 @@ public void openFileFromPath(String path) {
176190
JScrollBar verticalScrollBar = scrollPane.getVerticalScrollBar();
177191
verticalScrollBar.setValue(verticalScrollBar.getMinimum());
178192
});
179-
} catch (IOException exception) {
180-
exception.printStackTrace();
193+
} catch (IOException e) {
194+
scriptor.logger.insert(e.toString());
181195
}
182196

183197
tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
@@ -242,8 +256,8 @@ public void saveFile() {
242256
if (wasNullBefore) {
243257
scriptor.filesExplorer.refreshTree();
244258
}
245-
} catch (IOException exception) {
246-
exception.printStackTrace();
259+
} catch (IOException e) {
260+
scriptor.logger.insert(e.toString());
247261
}
248262
}
249263
}
@@ -291,8 +305,8 @@ public void saveFileByIndex(int index) {
291305

292306
scriptor.setTitle("Scriptor - " + selectedFile.getPath());
293307
updateTabTitle(index, selectedFile.getName());
294-
} catch (IOException exception) {
295-
exception.printStackTrace();
308+
} catch (IOException e) {
309+
scriptor.logger.insert(e.toString());
296310
}
297311
}
298312
}
@@ -339,13 +353,13 @@ public void saveAsFile() {
339353
}
340354

341355
reader.close();
342-
} catch (IOException exception) {
343-
exception.printStackTrace();
356+
} catch (IOException e) {
357+
scriptor.logger.insert(e.toString());
344358
}
345359

346360
scriptor.filesExplorer.refreshTree();
347-
} catch (IOException exception) {
348-
exception.printStackTrace();
361+
} catch (IOException e) {
362+
scriptor.logger.insert(e.toString());
349363
}
350364
}
351365
}
@@ -538,38 +552,61 @@ public String getCurrentPath() {
538552
private RTextScrollPane newTextArea(String filePath) {
539553
RSyntaxTextArea textArea = new RSyntaxTextArea(20, 60);
540554

541-
if (filePath != null) {
542-
String fileExtension = FilenameUtils.getExtension(filePath);
555+
if (scriptor.config.getSyntaxHighlightingEnabled()) {
556+
if (filePath != null) {
557+
String fileExtension = FilenameUtils.getExtension(filePath);
543558

544-
textArea.setSyntaxEditingStyle(ScriptorProgrammingLanguagesUtils.getSyntaxConstantByFileExtension(fileExtension));
559+
textArea.setSyntaxEditingStyle(
560+
ScriptorProgrammingLanguagesUtils.getSyntaxConstantByFileExtension(fileExtension));
561+
} else {
562+
textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
563+
}
545564
} else {
546565
textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
547566
}
548567

549-
textArea.setBracketMatchingEnabled(true);
568+
textArea.setBracketMatchingEnabled(scriptor.config.getBracketMatching());
550569
textArea.setAnimateBracketMatching(false);
551-
textArea.setAutoIndentEnabled(true);
570+
textArea.setAutoIndentEnabled(scriptor.config.getAutoIndent());
552571
textArea.setDragEnabled(true);
553-
textArea.setTabSize(4);
572+
textArea.setTabSize(scriptor.config.getIndentTabSize());
554573
textArea.setCodeFoldingEnabled(true);
555574
textArea.setHyperlinksEnabled(true);
556575
textArea.setHighlightSecondaryLanguages(false);
557576

558577
Font font = textArea.getFont();
559578
textArea.setFont(font.deriveFont((float) scriptor.config.getZoom()));
560579

561-
addSyntaxHighlighting(textArea);
580+
if (scriptor.config.getSyntaxHighlightingEnabled()) {
581+
addSyntaxHighlighting(textArea);
582+
}
583+
584+
if (scriptor.config.getMarkOccurrencesEnabled()) {
585+
textArea.setMarkOccurrences(true);
586+
textArea.setMarkOccurrencesDelay(100);
587+
}
562588

563589
RTextScrollPane scrollPane = new RTextScrollPane(textArea);
564590
scrollPane.setWheelScrollingEnabled(true);
565591

566-
Gutter gutter = scrollPane.getGutter();
592+
if (scriptor.config.getBookmarkingEnabled()) {
593+
Gutter gutter = scrollPane.getGutter();
594+
595+
Font lineNumberFont = gutter.getLineNumberFont();
596+
gutter.setLineNumberFont(lineNumberFont.deriveFont((float) scriptor.config.getZoom()));
567597

568-
Font lineNumberFont = gutter.getLineNumberFont();
569-
gutter.setLineNumberFont(lineNumberFont.deriveFont((float) scriptor.config.getZoom()));
598+
gutter.setBookmarkingEnabled(true);
599+
gutter.setBookmarkIcon(scriptor.getIcon("bookmark.gif"));
600+
}
570601

571-
gutter.setBookmarkingEnabled(true);
572-
gutter.setBookmarkIcon(scriptor.getIcon("bookmark.gif"));
602+
autoSaveTimer = new Timer(1000, new ActionListener() {
603+
@Override
604+
public void actionPerformed(ActionEvent e) {
605+
autoSaveTimer.stop();
606+
saveFile();
607+
}
608+
});
609+
autoSaveTimer.setRepeats(false);
573610

574611
textArea.getDocument().addDocumentListener(new DocumentListener() {
575612
@Override
@@ -605,8 +642,12 @@ public void changedUpdate(DocumentEvent e) {
605642
arraySavedPaths.set(selectedIndex, false);
606643

607644
if (file.exists() && file.isFile()) {
608-
scriptor.setTitle("Scriptor - " + file.getPath() + "*");
609-
updateTabTitle(selectedIndex, file.getName() + "*");
645+
if (scriptor.config.getAutoSaveFileEdits()) {
646+
resetAutoSaveTimer();
647+
} else {
648+
scriptor.setTitle("Scriptor - " + file.getPath() + "*");
649+
updateTabTitle(selectedIndex, file.getName() + "*");
650+
}
610651
} else {
611652
scriptor.setTitle("Scriptor - " + "Untitled*");
612653
updateTabTitle(selectedIndex, "Untitled*");
@@ -694,27 +735,42 @@ public void actionPerformed(ActionEvent e) {
694735
tabbedPane.setTabComponentAt(index, tabPanel);
695736
}
696737

738+
private void resetAutoSaveTimer() {
739+
if (autoSaveTimer.isRunning()) {
740+
autoSaveTimer.restart();
741+
} else {
742+
autoSaveTimer.start();
743+
}
744+
}
745+
697746
private void addSyntaxHighlighting(RSyntaxTextArea textArea) {
698747
SyntaxScheme scheme = textArea.getSyntaxScheme();
699748

700749
scheme.getStyle(Token.ANNOTATION).foreground = getConfigSyntaxHighlightingTokenColor("ANNOTATION");
701750
scheme.getStyle(Token.RESERVED_WORD).foreground = getConfigSyntaxHighlightingTokenColor("RESERVED_WORD");
702751
scheme.getStyle(Token.RESERVED_WORD_2).foreground = getConfigSyntaxHighlightingTokenColor("RESERVED_WORD");
703752

704-
scheme.getStyle(Token.LITERAL_STRING_DOUBLE_QUOTE).foreground = getConfigSyntaxHighlightingTokenColor("LITERAL_STRING_DOUBLE_QUOTE");
753+
scheme.getStyle(Token.LITERAL_STRING_DOUBLE_QUOTE).foreground = getConfigSyntaxHighlightingTokenColor(
754+
"LITERAL_STRING_DOUBLE_QUOTE");
705755
scheme.getStyle(Token.LITERAL_CHAR).foreground = getConfigSyntaxHighlightingTokenColor("LITERAL_CHAR");
706-
scheme.getStyle(Token.LITERAL_BACKQUOTE).foreground = getConfigSyntaxHighlightingTokenColor("LITERAL_BACKQUOTE");
756+
scheme.getStyle(Token.LITERAL_BACKQUOTE).foreground = getConfigSyntaxHighlightingTokenColor(
757+
"LITERAL_BACKQUOTE");
707758

708759
scheme.getStyle(Token.LITERAL_BOOLEAN).foreground = getConfigSyntaxHighlightingTokenColor("LITERAL_BOOLEAN");
709760

710-
scheme.getStyle(Token.LITERAL_NUMBER_DECIMAL_INT).foreground = getConfigSyntaxHighlightingTokenColor("LITERAL_NUMBER_DECIMAL_INT");
711-
scheme.getStyle(Token.LITERAL_NUMBER_FLOAT).foreground = getConfigSyntaxHighlightingTokenColor("LITERAL_NUMBER_FLOAT");
712-
scheme.getStyle(Token.LITERAL_NUMBER_HEXADECIMAL).foreground = getConfigSyntaxHighlightingTokenColor("LITERAL_NUMBER_HEXADECIMAL");
761+
scheme.getStyle(Token.LITERAL_NUMBER_DECIMAL_INT).foreground = getConfigSyntaxHighlightingTokenColor(
762+
"LITERAL_NUMBER_DECIMAL_INT");
763+
scheme.getStyle(Token.LITERAL_NUMBER_FLOAT).foreground = getConfigSyntaxHighlightingTokenColor(
764+
"LITERAL_NUMBER_FLOAT");
765+
scheme.getStyle(Token.LITERAL_NUMBER_HEXADECIMAL).foreground = getConfigSyntaxHighlightingTokenColor(
766+
"LITERAL_NUMBER_HEXADECIMAL");
713767

714768
scheme.getStyle(Token.REGEX).foreground = getConfigSyntaxHighlightingTokenColor("REGEX");
715769

716-
scheme.getStyle(Token.COMMENT_MULTILINE).foreground = getConfigSyntaxHighlightingTokenColor("COMMENT_MULTILINE");
717-
scheme.getStyle(Token.COMMENT_DOCUMENTATION).foreground = getConfigSyntaxHighlightingTokenColor("COMMENT_DOCUMENTATION");
770+
scheme.getStyle(Token.COMMENT_MULTILINE).foreground = getConfigSyntaxHighlightingTokenColor(
771+
"COMMENT_MULTILINE");
772+
scheme.getStyle(Token.COMMENT_DOCUMENTATION).foreground = getConfigSyntaxHighlightingTokenColor(
773+
"COMMENT_DOCUMENTATION");
718774
scheme.getStyle(Token.COMMENT_EOL).foreground = getConfigSyntaxHighlightingTokenColor("COMMENT_EOL");
719775

720776
scheme.getStyle(Token.SEPARATOR).foreground = getConfigSyntaxHighlightingTokenColor("SEPARATOR");
@@ -730,20 +786,25 @@ private void addSyntaxHighlighting(RSyntaxTextArea textArea) {
730786
scheme.getStyle(Token.MARKUP_DTD).foreground = getConfigSyntaxHighlightingTokenColor("MARKUP_DTD");
731787
// scheme.getStyle(Token.MARKUP_ENTITY_REFERENCE).foreground = Color.BLUE;
732788
// scheme.getStyle(Token.MARKUP_PROCESSING_INSTRUCTION).foreground = Color.BLUE;
733-
scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE).foreground = getConfigSyntaxHighlightingTokenColor("MARKUP_TAG_ATTRIBUTE");
734-
scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE_VALUE).foreground = getConfigSyntaxHighlightingTokenColor("MARKUP_TAG_ATTRIBUTE_VALUE");
735-
scheme.getStyle(Token.MARKUP_TAG_DELIMITER).foreground = getConfigSyntaxHighlightingTokenColor("MARKUP_TAG_DELIMITER");
789+
scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE).foreground = getConfigSyntaxHighlightingTokenColor(
790+
"MARKUP_TAG_ATTRIBUTE");
791+
scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE_VALUE).foreground = getConfigSyntaxHighlightingTokenColor(
792+
"MARKUP_TAG_ATTRIBUTE_VALUE");
793+
scheme.getStyle(Token.MARKUP_TAG_DELIMITER).foreground = getConfigSyntaxHighlightingTokenColor(
794+
"MARKUP_TAG_DELIMITER");
736795
scheme.getStyle(Token.MARKUP_TAG_NAME).foreground = getConfigSyntaxHighlightingTokenColor("MARKUP_TAG_NAME");
737796

738797
textArea.setSyntaxScheme(scheme);
739798
}
740799

741800
private Color getConfigSyntaxHighlightingTokenColor(String token) {
742-
return Color.decode((String) scriptor.pluginsHandler.getMergedConfig().get("syntax.highlight.tokens." + token + ".color"));
801+
return Color.decode(
802+
(String) scriptor.pluginsHandler.getMergedConfig().get("syntax.highlight.tokens." + token + ".color"));
743803
}
744804

745805
private Icon getFileIcon(File file) {
746-
File fileIcon = new File("resources/icons/" + ScriptorProgrammingLanguagesUtils.getLanguageIconNameByFile(file));
806+
File fileIcon = new File(
807+
"resources/icons/" + ScriptorProgrammingLanguagesUtils.getLanguageIconNameByFile(file));
747808

748809
return fileIcon == null ? null : resizeSVGToIcon(fileIcon.getPath(), 14, 14);
749810
}
@@ -769,7 +830,7 @@ private Icon resizeSVGToIcon(String svgFilePath, int width, int height) {
769830

770831
return icon;
771832
} catch (IOException | TranscoderException e) {
772-
e.printStackTrace();
833+
scriptor.logger.insert(e.toString());
773834
return null;
774835
}
775836
}

‎src/main/java/com/scriptor/core/plugins/ScriptorPluginsHandler.java

-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ public void loadPlugins() {
3838

3939
plugins.add(plugin);
4040
} catch (IOException e) {
41-
System.err.println("Error reading file: " + file.getName());
4241
e.printStackTrace();
4342
} catch (Exception e) {
44-
System.err.println("Error parsing JSON in file: " + file.getName());
4543
e.printStackTrace();
4644
}
4745
}

‎src/main/java/com/scriptor/core/terminal/ScriptorTerminal.java

+19-4
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void keyTyped(KeyEvent event) {
7979
processWriter.write(command + "\n");
8080
processWriter.flush();
8181
} catch (IOException ex) {
82-
ex.printStackTrace();
82+
scriptor.logger.insert(ex.toString());
8383
}
8484
} else if (!awaitingInput && !isAlive()) {
8585
commandTextField.setText("");
@@ -223,7 +223,7 @@ public void executeCommand(String command) {
223223
}
224224
}
225225
} catch (IOException ex) {
226-
ex.printStackTrace();
226+
scriptor.logger.insert(ex.toString());
227227
}
228228
});
229229

@@ -243,7 +243,7 @@ public void executeCommand(String command) {
243243

244244
} catch (IOException ex) {
245245
appendToTerminal("Error: Unable to execute command\n", Color.RED, true);
246-
ex.printStackTrace();
246+
scriptor.logger.insert(ex.toString());
247247
}
248248
}
249249
}
@@ -301,7 +301,7 @@ private void appendToTerminal(String text, Color color, boolean... details) {
301301
try {
302302
doc.insertString(doc.getLength(), text, style);
303303
} catch (BadLocationException e) {
304-
e.printStackTrace();
304+
scriptor.logger.insert(e.toString());
305305
}
306306
}
307307

@@ -332,6 +332,21 @@ public void restartProcess() {
332332
executeCommand(commands.get(commands.size() - 1));
333333
}
334334

335+
public void runPreviousCommand() {
336+
if (commands.size() == 0) {
337+
showMessageDialog(scriptor, "The commands history for this terminal is empty.", "Terminal Commands History",
338+
WARNING_MESSAGE);
339+
340+
return;
341+
}
342+
343+
closeProcess();
344+
345+
appendToTerminal(commands.get(commands.size() - 1) + "\n", Color.decode("#000000"));
346+
347+
executeCommand(commands.get(commands.size() - 1));
348+
}
349+
335350
public void setAwaitingInput(boolean awaiting) {
336351
this.awaitingInput = awaiting;
337352
}

‎src/main/java/com/scriptor/core/utils/ScriptorLogger.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.scriptor.core.utils;
22

33
import java.io.*;
4+
import java.time.LocalDateTime;
5+
import java.time.format.DateTimeFormatter;
46
import java.util.Scanner;
57

68
public class ScriptorLogger {
@@ -24,9 +26,12 @@ public ScriptorLogger() {
2426
}
2527

2628
public void insert(String text) {
29+
LocalDateTime dateNow = LocalDateTime.now();
2730
String data = read();
2831

29-
data += text.endsWith("\n") ? text : (text + "\n");
32+
DateTimeFormatter formatted = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
33+
34+
data += "[" + formatted.format(dateNow) + "] " + (text.endsWith("\n") ? text : (text + "\n"));
3035

3136
write(data);
3237
}

0 commit comments

Comments
 (0)
Please sign in to comment.