mirror of https://github.com/buggins/dlangide.git
Merge branch 'master' of https://github.com/buggins/dlangide into find
This commit is contained in:
commit
d6e39c67d0
|
|
@ -11,15 +11,18 @@ Currently supported features:
|
||||||
* Build and run project with DUB
|
* Build and run project with DUB
|
||||||
* Build log highlight and navigation to place of error or warning by clicking on log line
|
* Build log highlight and navigation to place of error or warning by clicking on log line
|
||||||
* DUB dependencies update
|
* DUB dependencies update
|
||||||
|
* DUB package configuration selection (implemented by NCrashed)
|
||||||
|
* Dependency projects are shown in workspace tree
|
||||||
|
|
||||||
Source editor features:
|
Source editor features:
|
||||||
|
|
||||||
* D language source code syntax highlight (basic)
|
* D language source code syntax highlight (basic)
|
||||||
* Indent / unindent text with Tab and Shift+Tab or Ctrl+\[ and Ctrl+\]
|
* Indent / unindent text with Tab and Shift+Tab or Ctrl+\[ and Ctrl+\]
|
||||||
* Toggle line or block comments by Ctrl+/ and Ctrl+Shift+/
|
* Toggle line or block comments by Ctrl+/ and Ctrl+Shift+/
|
||||||
* Select word by mouse double click
|
|
||||||
* D source code autocompletion by Ctrl+Space or Ctrl+Shift+G (using DCD)
|
* D source code autocompletion by Ctrl+Space or Ctrl+Shift+G (using DCD)
|
||||||
* D source code Go To Definition by Ctrl+G or F12 (using DCD)
|
* D source code Go To Definition by Ctrl+G or F12 (using DCD)
|
||||||
|
* D source code Smart Indents
|
||||||
|
* Select word by mouse double click
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
@ -28,6 +31,8 @@ GitHub page: [https://github.com/buggins/dlangide](https://github.com/buggins/dl
|
||||||
|
|
||||||
DlangUI project GitHub page: [https://github.com/buggins/dlangui](https://github.com/buggins/dlangui)
|
DlangUI project GitHub page: [https://github.com/buggins/dlangui](https://github.com/buggins/dlangui)
|
||||||
|
|
||||||
|
[](https://gitter.im/buggins/dlangide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://travis-ci.org/buggins/dlangide) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=H2ADZV8S6TDHQ "Donate once-off to this project using Paypal")
|
||||||
|
|
||||||
|
|
||||||
DCD integration
|
DCD integration
|
||||||
===============
|
===============
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids>DebugInfo DCD</debugids>
|
<debugids>DebugInfo DCD</debugids>
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>Unicode USE_FREETYPE USE_LIBDPARSE USE_MAGO</versionids>
|
<versionids>Unicode USE_FREETYPE</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>3</mapverbosity>
|
<mapverbosity>3</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,9 @@ void testMago() {
|
||||||
Log.e("OLE 2 failed to initialize");
|
Log.e("OLE 2 failed to initialize");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDebugCoreServer2 coreServer = null;
|
||||||
|
|
||||||
//hr = CoCreateInstance(&CLSID_MAGO, null, CLSCTX_ALL, &IID_IDebugEngine2, cast(void**)&piUnknown);
|
//hr = CoCreateInstance(&CLSID_MAGO, null, CLSCTX_ALL, &IID_IDebugEngine2, cast(void**)&piUnknown);
|
||||||
hr = CoCreateInstance(&IID_MAGO_NATIVE_ENGINE, //CLSID_MAGO,
|
hr = CoCreateInstance(&IID_MAGO_NATIVE_ENGINE, //CLSID_MAGO,
|
||||||
null,
|
null,
|
||||||
|
|
@ -118,10 +121,10 @@ void testMago() {
|
||||||
envblock ~= 0;
|
envblock ~= 0;
|
||||||
opts ~= 0;
|
opts ~= 0;
|
||||||
|
|
||||||
|
IDebugPort2 port;
|
||||||
hr = debugEngineLaunch.LaunchSuspended (
|
hr = debugEngineLaunch.LaunchSuspended (
|
||||||
null,
|
null,
|
||||||
null,
|
port,
|
||||||
exe.ptr,//LPCOLESTR
|
exe.ptr,//LPCOLESTR
|
||||||
args.ptr,
|
args.ptr,
|
||||||
dir.ptr,
|
dir.ptr,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class Builder : BackgroundOperationWatcher {
|
||||||
protected ExternalProcess _extprocess;
|
protected ExternalProcess _extprocess;
|
||||||
protected OutputPanel _log;
|
protected OutputPanel _log;
|
||||||
protected ProtectedTextStorage _box;
|
protected ProtectedTextStorage _box;
|
||||||
|
protected ProjectConfiguration _projectConfig;
|
||||||
protected BuildConfiguration _buildConfig;
|
protected BuildConfiguration _buildConfig;
|
||||||
protected BuildOperation _buildOp;
|
protected BuildOperation _buildOp;
|
||||||
protected bool _verbose;
|
protected bool _verbose;
|
||||||
|
|
@ -23,8 +24,9 @@ class Builder : BackgroundOperationWatcher {
|
||||||
@property Project project() { return _project; }
|
@property Project project() { return _project; }
|
||||||
@property void project(Project p) { _project = p; }
|
@property void project(Project p) { _project = p; }
|
||||||
|
|
||||||
this(AppFrame frame, Project project, OutputPanel log, BuildConfiguration buildConfig, BuildOperation buildOp, bool verbose) {
|
this(AppFrame frame, Project project, OutputPanel log, ProjectConfiguration projectConfig, BuildConfiguration buildConfig, BuildOperation buildOp, bool verbose) {
|
||||||
super(frame);
|
super(frame);
|
||||||
|
_projectConfig = projectConfig;
|
||||||
_buildConfig = buildConfig;
|
_buildConfig = buildConfig;
|
||||||
_buildOp = buildOp;
|
_buildOp = buildOp;
|
||||||
_verbose = verbose;
|
_verbose = verbose;
|
||||||
|
|
@ -62,7 +64,11 @@ class Builder : BackgroundOperationWatcher {
|
||||||
} else if (_buildOp == BuildOperation.Clean) {
|
} else if (_buildOp == BuildOperation.Clean) {
|
||||||
params ~= "clean".dup;
|
params ~= "clean".dup;
|
||||||
} else if (_buildOp == BuildOperation.Run) {
|
} else if (_buildOp == BuildOperation.Run) {
|
||||||
params ~= "run".dup;
|
if (_projectConfig.type == ProjectConfiguration.Type.Library) {
|
||||||
|
params ~= "test".dup;
|
||||||
|
} else {
|
||||||
|
params ~= "run".dup;
|
||||||
|
}
|
||||||
} else if (_buildOp == BuildOperation.Upgrade) {
|
} else if (_buildOp == BuildOperation.Upgrade) {
|
||||||
params ~= "upgrade".dup;
|
params ~= "upgrade".dup;
|
||||||
params ~= "--force-remove".dup;
|
params ~= "--force-remove".dup;
|
||||||
|
|
@ -83,6 +89,10 @@ class Builder : BackgroundOperationWatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_projectConfig.name != ProjectConfiguration.DEFAULT_NAME) {
|
||||||
|
params ~= "--config=".dup ~ _projectConfig.name;
|
||||||
|
}
|
||||||
|
|
||||||
if (_verbose)
|
if (_verbose)
|
||||||
params ~= "-v".dup;
|
params ~= "-v".dup;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ enum IDEActions : int {
|
||||||
FileClose,
|
FileClose,
|
||||||
FileExit,
|
FileExit,
|
||||||
EditPreferences,
|
EditPreferences,
|
||||||
|
ProjectConfigurations,
|
||||||
BuildConfigurations,
|
BuildConfigurations,
|
||||||
BuildWorkspace,
|
BuildWorkspace,
|
||||||
RebuildWorkspace,
|
RebuildWorkspace,
|
||||||
|
|
@ -68,6 +69,7 @@ const Action ACTION_FILE_EXIT = new Action(IDEActions.FileExit, "MENU_FILE_EXIT"
|
||||||
const Action ACTION_WORKSPACE_BUILD = new Action(IDEActions.BuildWorkspace, "MENU_BUILD_WORKSPACE_BUILD"c);
|
const Action ACTION_WORKSPACE_BUILD = new Action(IDEActions.BuildWorkspace, "MENU_BUILD_WORKSPACE_BUILD"c);
|
||||||
const Action ACTION_WORKSPACE_REBUILD = new Action(IDEActions.RebuildWorkspace, "MENU_BUILD_WORKSPACE_REBUILD"c);
|
const Action ACTION_WORKSPACE_REBUILD = new Action(IDEActions.RebuildWorkspace, "MENU_BUILD_WORKSPACE_REBUILD"c);
|
||||||
const Action ACTION_WORKSPACE_CLEAN = new Action(IDEActions.CleanWorkspace, "MENU_BUILD_WORKSPACE_CLEAN"c);
|
const Action ACTION_WORKSPACE_CLEAN = new Action(IDEActions.CleanWorkspace, "MENU_BUILD_WORKSPACE_CLEAN"c);
|
||||||
|
const Action ACTION_PROJECT_CONFIGURATIONS = new Action(IDEActions.ProjectConfigurations, "MENU_PROJECT_CONFIGURATIONS"c);
|
||||||
const Action ACTION_BUILD_CONFIGURATIONS = new Action(IDEActions.BuildConfigurations, "MENU_BUILD_CONFIGURATIONS"c);
|
const Action ACTION_BUILD_CONFIGURATIONS = new Action(IDEActions.BuildConfigurations, "MENU_BUILD_CONFIGURATIONS"c);
|
||||||
const Action ACTION_PROJECT_BUILD = new Action(IDEActions.BuildProject, "MENU_BUILD_PROJECT_BUILD"c, "run-build", KeyCode.F7, 0);
|
const Action ACTION_PROJECT_BUILD = new Action(IDEActions.BuildProject, "MENU_BUILD_PROJECT_BUILD"c, "run-build", KeyCode.F7, 0);
|
||||||
const Action ACTION_PROJECT_REBUILD = new Action(IDEActions.RebuildProject, "MENU_BUILD_PROJECT_REBUILD"c, "run-build-clean", KeyCode.F7, KeyFlag.Control);
|
const Action ACTION_PROJECT_REBUILD = new Action(IDEActions.RebuildProject, "MENU_BUILD_PROJECT_REBUILD"c, "run-build-clean", KeyCode.F7, KeyFlag.Control);
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class DSourceEdit : SourceEdit {
|
||||||
/// returns project import paths - if file from project is opened in current editor
|
/// returns project import paths - if file from project is opened in current editor
|
||||||
string[] importPaths() {
|
string[] importPaths() {
|
||||||
if (_projectSourceFile)
|
if (_projectSourceFile)
|
||||||
return _projectSourceFile.project.sourcePaths ~ _projectSourceFile.project.builderSourcePaths;
|
return _projectSourceFile.project.importPaths;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,33 @@ class BackgroundOperationWatcherTest : BackgroundOperationWatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Subclass of toolbars that can update their items
|
||||||
|
class UpdateableToolBarComboBox : ToolBarComboBox {
|
||||||
|
this(string id, dstring[] items) {
|
||||||
|
super(id, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property items(dstring[] newItems) {
|
||||||
|
_adapter.items = newItems;
|
||||||
|
if(newItems.length > 0) {
|
||||||
|
selectedItemIndex = 0;
|
||||||
|
}
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@property dstring selectedItem() {
|
||||||
|
size_t index = _selectedItemIndex;
|
||||||
|
if(index < 0 || index >= _adapter.itemCount) return "";
|
||||||
|
|
||||||
|
return _adapter.items.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// DIDE app frame
|
/// DIDE app frame
|
||||||
class IDEFrame : AppFrame {
|
class IDEFrame : AppFrame {
|
||||||
|
|
||||||
|
private UpdateableToolBarComboBox projectConfigurationCombo;
|
||||||
|
|
||||||
MenuItem mainMenuItems;
|
MenuItem mainMenuItems;
|
||||||
WorkspacePanel _wsPanel;
|
WorkspacePanel _wsPanel;
|
||||||
OutputPanel _logPanel;
|
OutputPanel _logPanel;
|
||||||
|
|
@ -439,6 +463,17 @@ class IDEFrame : AppFrame {
|
||||||
tb.addButtons(ACTION_FILE_OPEN, ACTION_FILE_SAVE, ACTION_SEPARATOR);
|
tb.addButtons(ACTION_FILE_OPEN, ACTION_FILE_SAVE, ACTION_SEPARATOR);
|
||||||
|
|
||||||
tb.addButtons(ACTION_DEBUG_START);
|
tb.addButtons(ACTION_DEBUG_START);
|
||||||
|
|
||||||
|
projectConfigurationCombo = new UpdateableToolBarComboBox("projectConfig", [ProjectConfiguration.DEFAULT_NAME.to!dstring]);
|
||||||
|
projectConfigurationCombo.onItemClickListener = delegate(Widget source, int index) {
|
||||||
|
if (currentWorkspace) {
|
||||||
|
currentWorkspace.setStartupProjectConfiguration(projectConfigurationCombo.selectedItem.to!string);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
projectConfigurationCombo.action = ACTION_PROJECT_CONFIGURATIONS;
|
||||||
|
tb.addControl(projectConfigurationCombo);
|
||||||
|
|
||||||
ToolBarComboBox cbBuildConfiguration = new ToolBarComboBox("buildConfig", ["Debug"d, "Release"d, "Unittest"d]);
|
ToolBarComboBox cbBuildConfiguration = new ToolBarComboBox("buildConfig", ["Debug"d, "Release"d, "Unittest"d]);
|
||||||
cbBuildConfiguration.onItemClickListener = delegate(Widget source, int index) {
|
cbBuildConfiguration.onItemClickListener = delegate(Widget source, int index) {
|
||||||
if (currentWorkspace && index < 3) {
|
if (currentWorkspace && index < 3) {
|
||||||
|
|
@ -596,9 +631,19 @@ class IDEFrame : AppFrame {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool loadProject(Project project) {
|
||||||
|
if (!project.load()) {
|
||||||
|
_logPanel.logLine("Cannot read project " ~ project.filename);
|
||||||
|
window.showMessageBox(UIString("Cannot open project"d), UIString("Error occured while opening project "d ~ toUTF32(project.filename)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_logPanel.logLine(toUTF32("Project file " ~ project.filename ~ " is opened ok"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void openFileOrWorkspace(string filename) {
|
void openFileOrWorkspace(string filename) {
|
||||||
if (filename.isWorkspaceFile) {
|
if (filename.isWorkspaceFile) {
|
||||||
Workspace ws = new Workspace();
|
Workspace ws = new Workspace(this);
|
||||||
if (ws.load(filename)) {
|
if (ws.load(filename)) {
|
||||||
askForUnsavedEdits(delegate() {
|
askForUnsavedEdits(delegate() {
|
||||||
setWorkspace(ws);
|
setWorkspace(ws);
|
||||||
|
|
@ -610,13 +655,7 @@ class IDEFrame : AppFrame {
|
||||||
} else if (filename.isProjectFile) {
|
} else if (filename.isProjectFile) {
|
||||||
_logPanel.clear();
|
_logPanel.clear();
|
||||||
_logPanel.logLine("Trying to open project from " ~ filename);
|
_logPanel.logLine("Trying to open project from " ~ filename);
|
||||||
Project project = new Project();
|
Project project = new Project(currentWorkspace, filename);
|
||||||
if (!project.load(filename)) {
|
|
||||||
_logPanel.logLine("Cannot read project file " ~ filename);
|
|
||||||
window.showMessageBox(UIString("Cannot open project"d), UIString("Error occured while opening project"d));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_logPanel.logLine("Project file is opened ok");
|
|
||||||
string defWsFile = project.defWorkspaceFile;
|
string defWsFile = project.defWorkspaceFile;
|
||||||
if (currentWorkspace) {
|
if (currentWorkspace) {
|
||||||
Project existing = currentWorkspace.findProject(project.filename);
|
Project existing = currentWorkspace.findProject(project.filename);
|
||||||
|
|
@ -633,6 +672,7 @@ class IDEFrame : AppFrame {
|
||||||
} else if (result.id == IDEActions.AddToCurrentWorkspace) {
|
} else if (result.id == IDEActions.AddToCurrentWorkspace) {
|
||||||
// add to current
|
// add to current
|
||||||
currentWorkspace.addProject(project);
|
currentWorkspace.addProject(project);
|
||||||
|
loadProject(project);
|
||||||
currentWorkspace.save();
|
currentWorkspace.save();
|
||||||
refreshWorkspace();
|
refreshWorkspace();
|
||||||
}
|
}
|
||||||
|
|
@ -657,10 +697,11 @@ class IDEFrame : AppFrame {
|
||||||
string defWsFile = project.defWorkspaceFile;
|
string defWsFile = project.defWorkspaceFile;
|
||||||
_logPanel.logLine("Creating new workspace " ~ defWsFile);
|
_logPanel.logLine("Creating new workspace " ~ defWsFile);
|
||||||
// new ws
|
// new ws
|
||||||
Workspace ws = new Workspace();
|
Workspace ws = new Workspace(this);
|
||||||
ws.name = project.name;
|
ws.name = project.name;
|
||||||
ws.description = project.description;
|
ws.description = project.description;
|
||||||
ws.addProject(project);
|
ws.addProject(project);
|
||||||
|
loadProject(project);
|
||||||
ws.save(defWsFile);
|
ws.save(defWsFile);
|
||||||
setWorkspace(ws);
|
setWorkspace(ws);
|
||||||
_logPanel.logLine("Done");
|
_logPanel.logLine("Done");
|
||||||
|
|
@ -691,10 +732,15 @@ class IDEFrame : AppFrame {
|
||||||
_logPanel.logLine("No project is opened");
|
_logPanel.logLine("No project is opened");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Builder op = new Builder(this, currentWorkspace.startupProject, _logPanel, currentWorkspace.buildConfiguration, buildOp, false);
|
Builder op = new Builder(this, currentWorkspace.startupProject, _logPanel, currentWorkspace.projectConfiguration, currentWorkspace.buildConfiguration, buildOp, false);
|
||||||
setBackgroundOperation(op);
|
setBackgroundOperation(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// updates list of available configurations
|
||||||
|
void setProjectConfigurations(dstring[] items) {
|
||||||
|
projectConfigurationCombo.items = items;
|
||||||
|
}
|
||||||
|
|
||||||
/// handle files dropped to application window
|
/// handle files dropped to application window
|
||||||
void onFilesDropped(string[] filenames) {
|
void onFilesDropped(string[] filenames) {
|
||||||
//Log.d("onFilesDropped(", filenames, ")");
|
//Log.d("onFilesDropped(", filenames, ")");
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ class WorkspacePanel : DockWindow {
|
||||||
TreeItem root = _tree.items.newChild(_workspace.filename, _workspace.name, "project-development");
|
TreeItem root = _tree.items.newChild(_workspace.filename, _workspace.name, "project-development");
|
||||||
root.intParam = ProjectItemType.Workspace;
|
root.intParam = ProjectItemType.Workspace;
|
||||||
foreach(project; _workspace.projects) {
|
foreach(project; _workspace.projects) {
|
||||||
TreeItem p = root.newChild(project.filename, project.name, "project-d");
|
TreeItem p = root.newChild(project.filename, project.name, project.isDependency ? "project-d-dependency" : "project-d");
|
||||||
p.intParam = ProjectItemType.Project;
|
p.intParam = ProjectItemType.Project;
|
||||||
addProjectItems(p, project.items);
|
addProjectItems(p, project.items);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import std.file;
|
||||||
import std.json;
|
import std.json;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
|
import std.process;
|
||||||
|
|
||||||
/// return true if filename matches rules for workspace file names
|
/// return true if filename matches rules for workspace file names
|
||||||
bool isProjectFile(string filename) {
|
bool isProjectFile(string filename) {
|
||||||
|
|
@ -223,6 +224,57 @@ string[] dmdSourcePaths() {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stores info about project configuration
|
||||||
|
struct ProjectConfiguration {
|
||||||
|
/// name used to build the project
|
||||||
|
string name;
|
||||||
|
/// type, for libraries one can run tests, for apps - execute them
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
/// How to display default configuration in ui
|
||||||
|
immutable static string DEFAULT_NAME = "default";
|
||||||
|
/// Default project configuration
|
||||||
|
immutable static ProjectConfiguration DEFAULT = ProjectConfiguration(DEFAULT_NAME, Type.Default);
|
||||||
|
|
||||||
|
/// Type of configuration
|
||||||
|
enum Type {
|
||||||
|
Default,
|
||||||
|
Executable,
|
||||||
|
Library
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type parseType(string s)
|
||||||
|
{
|
||||||
|
switch(s)
|
||||||
|
{
|
||||||
|
case "executable": return Type.Executable;
|
||||||
|
case "library": return Type.Library;
|
||||||
|
case "dynamicLibrary": return Type.Library;
|
||||||
|
case "staticLibrary": return Type.Library;
|
||||||
|
default: return Type.Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// parsing from setting file
|
||||||
|
static ProjectConfiguration[string] load(Setting s)
|
||||||
|
{
|
||||||
|
ProjectConfiguration[string] res = [DEFAULT_NAME: DEFAULT];
|
||||||
|
Setting configs = s.objectByPath("configurations");
|
||||||
|
if(configs is null || configs.type != SettingType.ARRAY)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
foreach(conf; configs) {
|
||||||
|
if(!conf.isObject) continue;
|
||||||
|
Type t = Type.Default;
|
||||||
|
if(auto typeName = conf.getString("targetType"))
|
||||||
|
t = parseType(typeName);
|
||||||
|
if (string confName = conf.getString("name"))
|
||||||
|
res[confName] = ProjectConfiguration(confName, t);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// DLANGIDE D project
|
/// DLANGIDE D project
|
||||||
class Project : WorkspaceItem {
|
class Project : WorkspaceItem {
|
||||||
protected Workspace _workspace;
|
protected Workspace _workspace;
|
||||||
|
|
@ -230,16 +282,30 @@ class Project : WorkspaceItem {
|
||||||
protected ProjectFolder _items;
|
protected ProjectFolder _items;
|
||||||
protected ProjectSourceFile _mainSourceFile;
|
protected ProjectSourceFile _mainSourceFile;
|
||||||
protected SettingsFile _projectFile;
|
protected SettingsFile _projectFile;
|
||||||
|
protected bool _isDependency;
|
||||||
|
protected string _dependencyVersion;
|
||||||
|
|
||||||
protected string[] _sourcePaths;
|
protected string[] _sourcePaths;
|
||||||
protected string[] _builderSourcePaths;
|
protected string[] _builderSourcePaths;
|
||||||
|
protected ProjectConfiguration[string] _configurations;
|
||||||
|
|
||||||
|
this(Workspace ws, string fname = null, string dependencyVersion = null) {
|
||||||
this(string fname = null) {
|
|
||||||
super(fname);
|
super(fname);
|
||||||
|
_workspace = ws;
|
||||||
_items = new ProjectFolder(fname);
|
_items = new ProjectFolder(fname);
|
||||||
|
_dependencyVersion = dependencyVersion;
|
||||||
|
_isDependency = _dependencyVersion.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property bool isDependency() { return _isDependency; }
|
||||||
|
@property string dependencyVersion() { return _dependencyVersion; }
|
||||||
|
|
||||||
|
/// returns project configurations
|
||||||
|
@property const(ProjectConfiguration[string]) configurations() const
|
||||||
|
{
|
||||||
|
return _configurations;
|
||||||
|
}
|
||||||
|
|
||||||
/// returns project's own source paths
|
/// returns project's own source paths
|
||||||
@property string[] sourcePaths() { return _sourcePaths; }
|
@property string[] sourcePaths() { return _sourcePaths; }
|
||||||
/// returns project's own source paths
|
/// returns project's own source paths
|
||||||
|
|
@ -250,6 +316,29 @@ class Project : WorkspaceItem {
|
||||||
return _builderSourcePaths;
|
return _builderSourcePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void addUnique(ref string[] dst, string[] items) {
|
||||||
|
foreach(item; items) {
|
||||||
|
bool found = false;
|
||||||
|
foreach(existing; dst) {
|
||||||
|
if (item.equal(existing)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
dst ~= item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@property string[] importPaths() {
|
||||||
|
string[] res;
|
||||||
|
addUnique(res, sourcePaths);
|
||||||
|
addUnique(res, builderSourcePaths);
|
||||||
|
foreach(dep; _dependencies) {
|
||||||
|
addUnique(res, dep.sourcePaths);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
string relativeToAbsolutePath(string path) {
|
string relativeToAbsolutePath(string path) {
|
||||||
if (isAbsolute(path))
|
if (isAbsolute(path))
|
||||||
return path;
|
return path;
|
||||||
|
|
@ -346,6 +435,10 @@ class Project : WorkspaceItem {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_name = toUTF32(_projectFile.getString("name"));
|
_name = toUTF32(_projectFile.getString("name"));
|
||||||
|
if (_isDependency) {
|
||||||
|
_name ~= "-"d;
|
||||||
|
_name ~= toUTF32(_dependencyVersion.startsWith("~") ? _dependencyVersion[1..$] : _dependencyVersion);
|
||||||
|
}
|
||||||
_description = toUTF32(_projectFile.getString("description"));
|
_description = toUTF32(_projectFile.getString("description"));
|
||||||
Log.d(" project name: ", _name);
|
Log.d(" project name: ", _name);
|
||||||
Log.d(" project description: ", _description);
|
Log.d(" project description: ", _description);
|
||||||
|
|
@ -355,7 +448,12 @@ class Project : WorkspaceItem {
|
||||||
|
|
||||||
Log.i("Project source paths: ", sourcePaths);
|
Log.i("Project source paths: ", sourcePaths);
|
||||||
Log.i("Builder source paths: ", builderSourcePaths);
|
Log.i("Builder source paths: ", builderSourcePaths);
|
||||||
|
if (!_isDependency)
|
||||||
|
loadSelections();
|
||||||
|
|
||||||
|
_configurations = ProjectConfiguration.load(_projectFile);
|
||||||
|
Log.i("Project configurations: ", _configurations);
|
||||||
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e("Cannot parse json", e);
|
Log.e("Cannot parse json", e);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -365,5 +463,82 @@ class Project : WorkspaceItem {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Project[] _dependencies;
|
||||||
|
@property Project[] dependencies() { return _dependencies; }
|
||||||
|
protected bool addDependency(Project dep) {
|
||||||
|
if (_workspace)
|
||||||
|
_workspace.addDependencyProject(dep);
|
||||||
|
_dependencies ~= dep;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool loadSelections() {
|
||||||
|
_dependencies.length = 0;
|
||||||
|
DubPackageFinder finder = new DubPackageFinder();
|
||||||
|
scope(exit) destroy(finder);
|
||||||
|
SettingsFile selectionsFile = new SettingsFile(buildNormalizedPath(_dir, "dub.selections.json"));
|
||||||
|
if (!selectionsFile.load())
|
||||||
|
return false;
|
||||||
|
Setting versions = selectionsFile.objectByPath("versions");
|
||||||
|
if (!versions)
|
||||||
|
return false;
|
||||||
|
string[string] versionMap = versions.strMap;
|
||||||
|
foreach(packageName, packageVersion; versionMap) {
|
||||||
|
string fn = finder.findPackage(packageName, packageVersion);
|
||||||
|
Log.d("dependency ", packageName, " ", packageVersion, " : ", fn ? fn : "NOT FOUND");
|
||||||
|
if (fn) {
|
||||||
|
Project p = new Project(_workspace, fn, packageVersion);
|
||||||
|
if (p.load()) {
|
||||||
|
addDependency(p);
|
||||||
|
} else {
|
||||||
|
Log.e("cannot load dependency package ", packageName, " ", packageVersion, " from file ", fn);
|
||||||
|
destroy(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DubPackageFinder {
|
||||||
|
string systemDubPath;
|
||||||
|
string userDubPath;
|
||||||
|
string tempPath;
|
||||||
|
this() {
|
||||||
|
version(Windows){
|
||||||
|
systemDubPath = buildNormalizedPath(environment.get("ProgramData"), "dub", "packages");
|
||||||
|
userDubPath = buildNormalizedPath(environment.get("APPDATA"), "dub", "packages");
|
||||||
|
tempPath = buildNormalizedPath(environment.get("TEMP"), "dub", "packages");
|
||||||
|
} else version(Posix){
|
||||||
|
systemDubPath = "/var/lib/dub/packages";
|
||||||
|
userDubPath = buildNormalizedPath(environment.get("HOME"), ".dub", "packages");
|
||||||
|
if(!userDubPath.isAbsolute)
|
||||||
|
userDubPath = buildNormalizedPath(getcwd(), userDubPath);
|
||||||
|
tempPath = "/tmp/packages";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string findPackage(string packageDir, string packageName, string packageVersion) {
|
||||||
|
string fullName = packageVersion.startsWith("~") ? packageName ~ "-" ~ packageVersion[1..$] : packageName ~ "-" ~ packageVersion;
|
||||||
|
string pathName = absolutePath(buildNormalizedPath(packageDir, fullName));
|
||||||
|
if (pathName.exists && pathName.isDir) {
|
||||||
|
string fn = buildNormalizedPath(pathName, "dub.json");
|
||||||
|
if (fn.exists && fn.isFile)
|
||||||
|
return fn;
|
||||||
|
fn = buildNormalizedPath(pathName, "package.json");
|
||||||
|
if (fn.exists && fn.isFile)
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string findPackage(string packageName, string packageVersion) {
|
||||||
|
string res = null;
|
||||||
|
res = findPackage(userDubPath, packageName, packageVersion);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
res = findPackage(systemDubPath, packageName, packageVersion);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
module dlangide.workspace.workspace;
|
module dlangide.workspace.workspace;
|
||||||
|
|
||||||
import dlangide.workspace.project;
|
import dlangide.workspace.project;
|
||||||
|
import dlangide.ui.frame;
|
||||||
import dlangui.core.logger;
|
import dlangui.core.logger;
|
||||||
|
import std.conv;
|
||||||
import std.path;
|
import std.path;
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.json;
|
import std.json;
|
||||||
|
import std.range;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
|
|
||||||
|
|
@ -44,11 +47,14 @@ bool isWorkspaceFile(string filename) {
|
||||||
/// DlangIDE workspace
|
/// DlangIDE workspace
|
||||||
class Workspace : WorkspaceItem {
|
class Workspace : WorkspaceItem {
|
||||||
protected Project[] _projects;
|
protected Project[] _projects;
|
||||||
|
|
||||||
|
protected IDEFrame _frame;
|
||||||
protected BuildConfiguration _buildConfiguration;
|
protected BuildConfiguration _buildConfiguration;
|
||||||
|
protected ProjectConfiguration _projectConfiguration = ProjectConfiguration.DEFAULT;
|
||||||
this(string fname = null) {
|
|
||||||
|
this(IDEFrame frame, string fname = null) {
|
||||||
super(fname);
|
super(fname);
|
||||||
|
_frame = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property Project[] projects() {
|
@property Project[] projects() {
|
||||||
|
|
@ -58,14 +64,28 @@ class Workspace : WorkspaceItem {
|
||||||
@property BuildConfiguration buildConfiguration() { return _buildConfiguration; }
|
@property BuildConfiguration buildConfiguration() { return _buildConfiguration; }
|
||||||
@property void buildConfiguration(BuildConfiguration config) { _buildConfiguration = config; }
|
@property void buildConfiguration(BuildConfiguration config) { _buildConfiguration = config; }
|
||||||
|
|
||||||
|
@property ProjectConfiguration projectConfiguration() { return _projectConfiguration; }
|
||||||
|
@property void projectConfiguration(ProjectConfiguration config) { _projectConfiguration = config; }
|
||||||
|
|
||||||
protected Project _startupProject;
|
protected Project _startupProject;
|
||||||
|
|
||||||
@property Project startupProject() { return _startupProject; }
|
@property Project startupProject() { return _startupProject; }
|
||||||
@property void startupProject(Project project) { _startupProject = project; }
|
@property void startupProject(Project project) {
|
||||||
|
_startupProject = project;
|
||||||
|
_frame.setProjectConfigurations(project.configurations.keys.map!(k => k.to!dstring).array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// setups currrent project configuration by name
|
||||||
|
void setStartupProjectConfiguration(string conf)
|
||||||
|
{
|
||||||
|
if(_startupProject && conf in _startupProject.configurations) {
|
||||||
|
_projectConfiguration = _startupProject.configurations[conf];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void fillStartupProject() {
|
protected void fillStartupProject() {
|
||||||
if (!_startupProject && _projects.length)
|
if (!_startupProject && _projects.length)
|
||||||
_startupProject = _projects[0];
|
startupProject = _projects[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// tries to find source file in one of projects, returns found project source file item, or null if not found
|
/// tries to find source file in one of projects, returns found project source file item, or null if not found
|
||||||
|
|
@ -93,6 +113,17 @@ class Workspace : WorkspaceItem {
|
||||||
fillStartupProject();
|
fillStartupProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool addDependencyProject(Project p) {
|
||||||
|
for (int i = 0; i < _projects.length; i++) {
|
||||||
|
if (_projects[i].filename.equal(p.filename)) {
|
||||||
|
_projects[i] = p;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addProject(p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
string absoluteToRelativePath(string path) {
|
string absoluteToRelativePath(string path) {
|
||||||
return toForwardSlashSeparator(relativePath(path, _dir));
|
return toForwardSlashSeparator(relativePath(path, _dir));
|
||||||
}
|
}
|
||||||
|
|
@ -108,6 +139,8 @@ class Workspace : WorkspaceItem {
|
||||||
json["description"] = JSONValue(toUTF8(_description));
|
json["description"] = JSONValue(toUTF8(_description));
|
||||||
JSONValue[string] projects;
|
JSONValue[string] projects;
|
||||||
foreach (Project p; _projects) {
|
foreach (Project p; _projects) {
|
||||||
|
if (p.isDependency)
|
||||||
|
continue; // don't save dependency
|
||||||
string pname = toUTF8(p.name);
|
string pname = toUTF8(p.name);
|
||||||
string ppath = absoluteToRelativePath(p.filename);
|
string ppath = absoluteToRelativePath(p.filename);
|
||||||
projects[pname] = JSONValue(ppath);
|
projects[pname] = JSONValue(ppath);
|
||||||
|
|
@ -147,7 +180,7 @@ class Workspace : WorkspaceItem {
|
||||||
Log.d("project: ", key, " path:", path);
|
Log.d("project: ", key, " path:", path);
|
||||||
if (!isAbsolute(path))
|
if (!isAbsolute(path))
|
||||||
path = buildNormalizedPath(_dir, path); //, "dub.json"
|
path = buildNormalizedPath(_dir, path); //, "dub.json"
|
||||||
Project project = new Project(path);
|
Project project = new Project(this, path);
|
||||||
_projects ~= project;
|
_projects ~= project;
|
||||||
project.load();
|
project.load();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ MENU_BUILD_PROJECT_BUILD=Build Project
|
||||||
MENU_BUILD_PROJECT_REBUILD=Rebuild Project
|
MENU_BUILD_PROJECT_REBUILD=Rebuild Project
|
||||||
MENU_BUILD_PROJECT_CLEAN=Clean Project
|
MENU_BUILD_PROJECT_CLEAN=Clean Project
|
||||||
MENU_PROJECT=&PROJECT
|
MENU_PROJECT=&PROJECT
|
||||||
|
MENU_PROJECT_CONFIGURATIONS=Project configurations
|
||||||
MENU_PROJECT_SET_AS_STARTUP=Set as Startup Project
|
MENU_PROJECT_SET_AS_STARTUP=Set as Startup Project
|
||||||
MENU_PROJECT_SETTINGS=Project Settings
|
MENU_PROJECT_SETTINGS=Project Settings
|
||||||
MENU_PROJECT_REFRESH=Refresh Workspace Items
|
MENU_PROJECT_REFRESH=Refresh Workspace Items
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ MENU_EDIT_CUT=Вырезать
|
||||||
MENU_EDIT_UNDO=&Отмена
|
MENU_EDIT_UNDO=&Отмена
|
||||||
MENU_EDIT_REDO=&Повторить
|
MENU_EDIT_REDO=&Повторить
|
||||||
MENU_EDIT_PREFERENCES=&Настройки
|
MENU_EDIT_PREFERENCES=&Настройки
|
||||||
|
MENU_PROJECT_CONFIGURATIONS=Конфигурации проекта
|
||||||
MENU_VIEW=&Вид
|
MENU_VIEW=&Вид
|
||||||
MENU_VIEW_LANGUAGE=&Язык интерфейса
|
MENU_VIEW_LANGUAGE=&Язык интерфейса
|
||||||
MENU_VIEW_LANGUAGE_EN=English
|
MENU_VIEW_LANGUAGE_EN=English
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 330 B |
|
|
@ -17,6 +17,7 @@ res/mdpi/edit-redo.png
|
||||||
res/mdpi/edit-undo.png
|
res/mdpi/edit-undo.png
|
||||||
res/mdpi/edit-unindent.png
|
res/mdpi/edit-unindent.png
|
||||||
res/mdpi/project-d.png
|
res/mdpi/project-d.png
|
||||||
|
res/mdpi/project-d-dependency.png
|
||||||
res/mdpi/project-development.png
|
res/mdpi/project-development.png
|
||||||
res/mdpi/project-open.png
|
res/mdpi/project-open.png
|
||||||
res/mdpi/run-build.png
|
res/mdpi/run-build.png
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue