├── helpers ├── shell-snippets │ ├── git-add.sh │ ├── git-pull.sh │ ├── git-diff.sh │ ├── csharp-compile.sh │ ├── git-push.sh │ ├── git-clone.sh │ ├── git-commit.sh │ ├── git-reset.sh │ ├── git-add-commit-push.sh │ └── README.md ├── toolbars │ ├── main-toolbar │ │ ├── 05-home.hl │ │ ├── 04-close-all-editors.hl │ │ └── 03-settings.hl │ ├── file-editor │ │ └── 01-save.hl │ ├── folder-editor │ │ ├── 03-upload-file.hl │ │ ├── 02-new-folder.hl │ │ └── 01-new-file.hl │ └── secondary-toolbar │ │ ├── 04-download.hl │ │ ├── 03-bookmark.hl │ │ ├── 02-delete.hl │ │ └── 01-rename.hl ├── lambda-events │ ├── hyper-ide.active-editor.get-filepath.hl │ ├── hyper-ide.active-editor.get-id.hl │ ├── hyper-ide.active-editor.get-code.hl │ ├── hyper-ide.editors.activate-next-editor.hl │ ├── hyper-ide.editors.activate-previous-editor.hl │ ├── hyper-ide.active-editor.set-code.hl │ ├── hyper-ide.active-editor.is-clean.hl │ ├── hyper-ide.file-explorer.refresh-active-folder.hl │ ├── hyper-ide.file-explorer.refresh-folder.hl │ ├── hyper-ide.active-editor.save.hl │ ├── hyper-ide.active-editor.close.hl │ ├── hyper-ide.active-editor.set-clean.hl │ ├── hyper-ide.editors.get-open-editors.hl │ ├── hyper-ide.editors.set-active-editor.hl │ └── hyper-ide.editors.close.hl ├── splash-screen-widget.hl ├── file-explorer │ ├── select-folder.hl │ ├── select-file.hl │ ├── expand-file-explorer-path.hl │ ├── get-file-explorer-objects.hl │ └── file-explorer-widget.hl ├── upload-files.hl ├── get-plugins.hl ├── activate-editor.hl ├── app-templates │ ├── hello-world.hl │ └── angular-todo.hl ├── edit-file.hl └── create-skin.hl ├── screenshots ├── screenshot-secondary.png └── hyper-ide-micro-screenshot.png ├── startup ├── version.hl ├── desktop.help-files.03-hyper-ide.hl └── plugins │ ├── hyper-ide.plugins.htmlmixed.preview.hl │ ├── hyper-ide.plugins.hyperlambda.evaluate.hl │ ├── hyper-ide.folder-plugin.refresh.hl │ ├── hyper-ide.plugins.javascript.evaluate.hl │ ├── hyper-ide.plugins.zip.unzip.hl │ ├── hyper-ide.folder-plugin.create-skin.hl │ ├── hyper-ide.folder-plugin.download-as-zip-file.hl │ ├── hyper-ide.global-plugin.launch-hypereval.hl │ ├── hyper-ide.plugins.css.beautify.hl │ ├── hyper-ide.plugins.javascript.minify.hl │ ├── hyper-ide.plugins.css.minify.hl │ ├── hyper-ide.plugins.markdown.preview.hl │ ├── hyper-ide.plugins.shell.execute.hl │ ├── hyper-ide.folder-plugin.execute.hl │ └── hyper-ide.folder-plugins.create-module.hl ├── desktop.hl ├── uninstall.hl ├── startup.hl ├── configuration ├── README.md └── extension2cm-instance.hl ├── README.md ├── launch.hl ├── help-files └── Hyper IDE │ ├── index.hl │ ├── 04 - Skinning your system.md │ ├── 03 - Create an AngularJS and MySQL app in 1 second.md │ ├── 02 - The fastest Hello World tutorial in the world.md │ ├── 01 - Introduction.md │ └── 05 - Hyper IDE API.md └── media └── main.css /helpers/shell-snippets/git-add.sh: -------------------------------------------------------------------------------- 1 | # This will will add all changes 2 | git add -A -------------------------------------------------------------------------------- /helpers/shell-snippets/git-pull.sh: -------------------------------------------------------------------------------- 1 | # Pulls from your remote repo. 2 | git pull --commit -------------------------------------------------------------------------------- /helpers/shell-snippets/git-diff.sh: -------------------------------------------------------------------------------- 1 | # Shows GIT changes that are not committed. 2 | git diff -------------------------------------------------------------------------------- /helpers/shell-snippets/csharp-compile.sh: -------------------------------------------------------------------------------- 1 | # Compiles a simple C# app. 2 | csc /out:app.exe code.cs -------------------------------------------------------------------------------- /helpers/shell-snippets/git-push.sh: -------------------------------------------------------------------------------- 1 | # This will will push all changes to your main repo. 2 | git push --all -------------------------------------------------------------------------------- /helpers/shell-snippets/git-clone.sh: -------------------------------------------------------------------------------- 1 | # Clones a Git repo. 2 | git clone https://github.com/polterguy/hello-world -------------------------------------------------------------------------------- /helpers/shell-snippets/git-commit.sh: -------------------------------------------------------------------------------- 1 | # Commits your changes 2 | git commit -a -m "YOUR COMMIT MESSAGE GOES HERE" -------------------------------------------------------------------------------- /screenshots/screenshot-secondary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polterguy/hyper-ide/HEAD/screenshots/screenshot-secondary.png -------------------------------------------------------------------------------- /screenshots/hyper-ide-micro-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polterguy/hyper-ide/HEAD/screenshots/hyper-ide-micro-screenshot.png -------------------------------------------------------------------------------- /helpers/shell-snippets/git-reset.sh: -------------------------------------------------------------------------------- 1 | # Resets all changes, including staged and working directory changes. 2 | # BE CAREFUL SINCE YOU'LL LOOS ALL CHANGES. 3 | git reset --hard 4 | git clean -f -d -------------------------------------------------------------------------------- /startup/version.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.version]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event will return the version of Hyper IDE back to caller. 7 | */ 8 | create-event:hyper-ide.version 9 | 10 | return:decimal:8.6 11 | -------------------------------------------------------------------------------- /helpers/toolbars/main-toolbar/05-home.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Home toolbar button, launches desktop (or default app). 3 | */ 4 | a 5 | href:/ 6 | role:button 7 | class:button 8 | innerValue:@"" 9 | title:Close Hyper IDE 10 | -------------------------------------------------------------------------------- /desktop.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * The desktop widget for Hyper IDE. 3 | */ 4 | container 5 | element:a 6 | class:jumbo-button 7 | title:An integrated development environment 8 | widgets 9 | span 10 | innerValue:Hyper IDE 11 | literal 12 | element:span 13 | class:icon-rocket 14 | -------------------------------------------------------------------------------- /uninstall.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Uninstalls Hyper IDE. 3 | */ 4 | 5 | 6 | 7 | 8 | 9 | /* 10 | * Deleting all relevant Active Events, and that's it. 11 | */ 12 | delete-event:p5.io.unroll-path.@IDE 13 | vocabulary:~hyper-ide. 14 | delete-event:x:/-/*?value 15 | delete-event:desktop.help-files.hyper-ide 16 | -------------------------------------------------------------------------------- /helpers/shell-snippets/git-add-commit-push.sh: -------------------------------------------------------------------------------- 1 | # NOTICE, Please supply a friendly commit message below. 2 | 3 | # This will will add all changes 4 | git add -A . 5 | 6 | # Commits your changes 7 | git commit -a -m "YOUR COMMIT MESSAGE GOES HERE" 8 | 9 | # This will will push all changes to your main repo. 10 | git push --all 11 | 12 | -------------------------------------------------------------------------------- /helpers/toolbars/file-editor/01-save.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Save editor toolbar button. 3 | */ 4 | button 5 | innerValue:@"" 6 | title:Saves your file, keyboard shortcut Alt+S 7 | onclick 8 | 9 | /* 10 | * Invoking event responsible for saving file. 11 | */ 12 | hyper-ide.active-editor.save 13 | -------------------------------------------------------------------------------- /helpers/toolbars/folder-editor/03-upload-file.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Upload file toolbar button. 3 | */ 4 | micro.widgets.upload-button 5 | title:Upload a file 6 | multiple 7 | .onupload 8 | 9 | /* 10 | * Evaluating file responsible for handling our upload. 11 | */ 12 | add:x:/+ 13 | src:x:/../*/files 14 | micro.evaluate.file:@IDE/helpers/upload-files.hl 15 | -------------------------------------------------------------------------------- /startup/desktop.help-files.03-hyper-ide.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates the __[desktop.help-files.03-hyper-ide]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event serves as a _"sink"_ event for the help system, returning the 8 | * root folder path to all help files related to Hyper IDE. 9 | */ 10 | create-event:desktop.help-files.03-hyper-ide 11 | 12 | return:@IDE/help-files/Hyper IDE/ 13 | -------------------------------------------------------------------------------- /startup.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Startup file for Hyper IDE. 3 | * Creates _"path"_ event and evaluates all files in _"/startup/"_ folder for Hyper IDE. 4 | */ 5 | 6 | 7 | /* 8 | * This is our _"path"_ Active Event for module. 9 | */ 10 | micro.path.get-folder:x:/..?name 11 | trim-right:x:/@micro.path.get-folder?value 12 | chars:/ 13 | eval-x:x:/+/* 14 | create-event:p5.io.unroll-path.@IDE 15 | return:x:/@trim-right?value 16 | 17 | 18 | /* 19 | * Evaluating all other startup files. 20 | */ 21 | micro.evaluate.folder:@IDE/startup/ 22 | -------------------------------------------------------------------------------- /helpers/shell-snippets/README.md: -------------------------------------------------------------------------------- 1 | # Template shell snippets 2 | 3 | This folder contains _"template shell snippets"_, which you can choose from when opening up a teminal execution window. 4 | Such snippets can contain things you often tend to do on a _"folder level"_, such as GIT commands, cache cleaning, etc. 5 | 6 | When you open up a _"terminal window"_ for a folder, you can choose from all these template snippets. Feel free to create 7 | your own template snippets here. 8 | 9 | Common things you often tend to do, should probably be here, such as GIT integration, etc, which there actually exist 10 | template files for in the folder. 11 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.get-filepath.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file returns the path of the file that's edited in the current 3 | * active editor. 4 | */ 5 | 6 | /* 7 | * Finding visible editor. 8 | */ 9 | p5.web.widgets.find-first-like:hyper-ide-editor-tab-editors 10 | .editor 11 | class:visible 12 | 13 | 14 | 15 | 16 | 17 | /* 18 | * Checking that the above invocation actually returned something. 19 | */ 20 | if:x:/@p5.web.widgets.find-first-like/*/*?value 21 | 22 | /* 23 | * Returning filepath of active editor to caller. 24 | */ 25 | get-widget-property:x:/@p5.web.widgets.find-first-like/*/*?value 26 | .editor 27 | return:x:/-/*/*?value 28 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.get-id.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file returns the widget ID of the active editor's CodeMirror wrapper widget. 3 | */ 4 | 5 | /* 6 | * Finding visible editor. 7 | */ 8 | p5.web.widgets.find-first-like:hyper-ide-editor-tab-editors 9 | .editor 10 | class:visible 11 | 12 | 13 | 14 | 15 | 16 | /* 17 | * Verifying above invocation returned something. 18 | */ 19 | if:x:/@p5.web.widgets.find-first-like/*/*?value 20 | 21 | /* 22 | * Returning ID of CodeMirror wrapper to caller. 23 | */ 24 | p5.web.widgets.find-first-like:x:/@p5.web.widgets.find-first-like/*/*?value 25 | class:micro-codemirror-wrapper 26 | return:x:/-/*/*?value 27 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.get-code.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file returns the code of the current active editor. 3 | */ 4 | 5 | /* 6 | * Finding CodeMirror editor and returning its code. 7 | */ 8 | hyper-ide.active-editor.get-id 9 | 10 | 11 | 12 | 13 | 14 | /* 15 | * Checking if above invocation returned anything. 16 | */ 17 | if:x:/@hyper-ide.active-editor.get-id?value 18 | 19 | /* 20 | * Retrieves active editor's code, and returning it to caller. 21 | */ 22 | micro.widgets.codemirror.get-value:x:/@hyper-ide.active-editor.get-id?value 23 | return:x:/@micro.widgets.codemirror.get-value/*?value 24 | 25 | else 26 | 27 | /* 28 | * Oops, no active editor. 29 | */ 30 | micro.windows.info:No active editor 31 | class:micro-windows-info warning 32 | -------------------------------------------------------------------------------- /configuration/README.md: -------------------------------------------------------------------------------- 1 | # Configuration folder for Hyper IDE 2 | 3 | Here you can find the global configuration settings for Hyper IDE. Among other 4 | things, you can find the mapping from file extensions to CodeMirror modes. 5 | In addition, you can optionally choose to create a new file in this folder, 6 | called _"plugins.hl"_. If you do, the existence of this file will explicitly 7 | turn **OFF** all plugins not explicitly mentioned in that file. 8 | 9 | To turn off all plugins, except for instance the `hyper-ide.plugins.hl.foo` plugin, 10 | you can create a file containing the following Hyperlambda code. 11 | 12 | ``` 13 | hyper-ide.plugins.hl.foo 14 | ``` 15 | 16 | The plugins can be found in the `/modules/hyper-ide/startup/plugins/` folder. 17 | This allows you to easily turn off all plugins you don't want any user to have access 18 | to for some reasons. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hyper IDE 2 | 3 | Hyper IDE is a web based IDE (Integrated Development Environment) that supports more than 100 programming 4 | languages out of the box for Phosphorus Five. You can use it on localhost, through e.g. Visual Studio, Mono Develop or Xamarin - 5 | Or install it on a web server, having easily access to your code, from anywhere in the world. 6 | 7 | ![screenshot](https://phosphorusfive.files.wordpress.com/2018/03/hyper-ide-screenshot1.png) 8 | 9 | ## Installation 10 | 11 | Hyper IDE is automatically installed when you install Phosphorus Five. 12 | 13 | ## License 14 | 15 | Hyper IDE is free and open source software, and licensed under the terms 16 | of the Gnu Public License, version 3, in addition to that a proprietary enabling license is available for a fee. 17 | 18 | * [Download and install Phosphorus Five here](https://github.com/polterguy/phosphorusfive/releases) 19 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.editors.activate-next-editor.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file activates the _"next"_ available editor that is already open. 3 | */ 4 | 5 | /* 6 | * Finding all "activate buttons". 7 | */ 8 | p5.web.widgets.find:hyper-ide-editor-tab-buttons 9 | .activate 10 | 11 | 12 | 13 | 14 | 15 | /* 16 | * Checking if are more than one button, and if there are, making sure we 17 | * "click" the next button in our chain. 18 | */ 19 | if:x:/@p5.web.widgets.find/*/*?count 20 | >:int:1 21 | 22 | /* 23 | * Activating the next editor in chain of open editors. 24 | */ 25 | get-widget-property:x:/@p5.web.widgets.find/*/*?value 26 | class 27 | get-widget-property:x:/@get-widget-property/*/*(/=~toggled)/./+?name 28 | .activate 29 | hyper-ide.editors.set-active-editor:x:/@get-widget-property/*/*?value 30 | 31 | /* 32 | * Returning success to caller. 33 | */ 34 | return:bool:true 35 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.editors.activate-previous-editor.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file activates the _"previous"_ available editor that is already open. 3 | */ 4 | 5 | /* 6 | * Finding all "activate buttons". 7 | */ 8 | p5.web.widgets.find:hyper-ide-editor-tab-buttons 9 | .activate 10 | 11 | 12 | 13 | 14 | 15 | /* 16 | * Checking if are more than one button, and if there are, making sure we 17 | * "click" the previous button in our chain. 18 | */ 19 | if:x:/@p5.web.widgets.find/*/*?count 20 | >:int:1 21 | 22 | /* 23 | * Activating the previous editor in chain of open editors. 24 | */ 25 | get-widget-property:x:/@p5.web.widgets.find/*/*?value 26 | class 27 | get-widget-property:x:/@get-widget-property/*/*(/=~toggled)/./-?name 28 | .activate 29 | hyper-ide.editors.set-active-editor:x:/@get-widget-property/*/*?value 30 | 31 | /* 32 | * Returning success to caller. 33 | */ 34 | return:bool:true 35 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.htmlmixed.preview.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.plugins.htmlmixed.preview]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event creates our _"preview HTML page plugin"_ button. This button is 7 | * only visible if the active object in your file explorer is an HTML file. 8 | * 9 | * When clicked, the button will open up a new browser tab, leading to the HTML 10 | * file's path, from your current active editor. 11 | */ 12 | create-event:hyper-ide.plugins.htmlmixed.preview 13 | return 14 | button 15 | innerValue:@"" 16 | title:Preview your HTML page in a new browser tab 17 | onclick 18 | 19 | /* 20 | * Retrieves active editor's file path, and opens it up in a new tab. 21 | */ 22 | hyper-ide.active-editor.get-filepath 23 | p5.web.send-javascript:@"window.open('{0}')" 24 | :x:/@hyper-ide.active-editor.get-filepath?value 25 | -------------------------------------------------------------------------------- /helpers/toolbars/main-toolbar/04-close-all-editors.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Close all editors toolbar button. 3 | */ 4 | button 5 | innerValue:@"" 6 | title:Close all editors 7 | disabled 8 | events 9 | 10 | 11 | /* 12 | * Raised when a file is to be edited. 13 | * We simply enable the close all button here. 14 | */ 15 | hyper-ide.on-file-edited 16 | 17 | /* 18 | * Enabling our "close all editors" button. 19 | */ 20 | delete-widget-property:x:/../*/_event?value 21 | disabled 22 | 23 | 24 | /* 25 | * Raised when a no file is edited. 26 | */ 27 | hyper-ide.on-all-editors-closed 28 | 29 | /* 30 | * Disabling our "close all editors" button. 31 | */ 32 | set-widget-property:x:/../*/_event?value 33 | disabled 34 | 35 | 36 | onclick 37 | 38 | /* 39 | * Making sure we close all editors. 40 | */ 41 | hyper-ide.editors.close 42 | filter:/ 43 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.hyperlambda.evaluate.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates the __[hyper-ide.plugins.hyperlambda.execute]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event creates our _"evaluate active editor's Hyperlambda file"_ plugin button. 8 | * This button is only visible if the active object in your file explorer is a 9 | * Hyperlambda file. 10 | */ 11 | create-event:hyper-ide.plugins.hyperlambda.execute 12 | return 13 | button 14 | innerValue:@"" 15 | title:Execute Hyperlambda file 16 | onclick 17 | 18 | /* 19 | * Retrieves editor's content. 20 | */ 21 | hyper-ide.active-editor.get-code 22 | hyper-ide.active-editor.get-filepath 23 | 24 | /* 25 | * Transforming Hyperlambda to lambda, and simply evaluating it. 26 | */ 27 | hyper2lambda:x:/@hyper-ide.active-editor.get-code?value 28 | set:x:/-?name 29 | src:x:/@hyper-ide.active-editor.get-filepath?value 30 | eval:x:/-2 31 | -------------------------------------------------------------------------------- /helpers/splash-screen-widget.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Initial _"splash"_ screen for Hyper IDE. Welcomes the user, 3 | * and gives some general information about the system. 4 | */ 5 | container:hyper-ide-splash 6 | class:air-inner shaded rounded hyper-ide-splash 7 | widgets 8 | h1 9 | innerValue:Hyper IDE {In the beginning there was Hyperlambda} 10 | p 11 | widgets 12 | span 13 | innerValue:@"A web based Integrated Development Environment, supporting 100+ programming languages out of the box. 14 | Hyper IDE contains strong plugin support, in addition to several different types of template projects, 15 | allowing you to literally start out your projects 'running'." 16 | p 17 | class:hyper-ide-copyright 18 | innerValue:@"Copyright © Thomas Hansen, thomas@gaiasoul.com, license GPLv3 ++" 19 | img 20 | src:"https://phosphorusfive.files.wordpress.com/2018/03/light-bulb-hyper-ide.png" 21 | class:hyper-ide-ufo 22 | title:Time to get Hyper 23 | alt:UFO 24 | 25 | -------------------------------------------------------------------------------- /helpers/toolbars/main-toolbar/03-settings.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Hyper IDE settings toolbar button. 3 | */ 4 | button 5 | innerValue:@"" 6 | title:Settings 7 | onclick 8 | 9 | /* 10 | * Allowing user to modify his settings. 11 | */ 12 | micro.codemirror.settings 13 | checkbox 14 | info:Browser scroll 15 | title:If true, will enable the browser scroll bars when document(s) overflows the size of viewport 16 | .data-field:page-scroll 17 | oninit 18 | 19 | /* 20 | * Making sure we retrieve existing value. 21 | */ 22 | .defaults 23 | page-scroll:bool:false 24 | p5.auth.my-settings.get 25 | if:x:(/@p5.auth.my-settings.get/*/codemirror/*/page-scroll|/../*/.defaults/*/page-scroll)/$?value 26 | =:bool:true 27 | set-widget-property:x:/../*/_event?value 28 | checked 29 | p 30 | innerValue:@"Notice, for Safari, tablets and phones, it is advisable to turn on browser scroll. 31 | In fact, in general terms, Hyper IDE works best with Google Chrome, on a computer, simply because it's faster." 32 | -------------------------------------------------------------------------------- /launch.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Launches Hyper IDE by including Hyper IDE's CSS file, creating 3 | * a wire frame, and instantiating __[hyper-ide.widgets.ide]__. 4 | * 5 | * **Notice**, almost the entirety of Hyper IDE is actually encapsulated 6 | * in the __[hyper-ide.widgets.ide]__ extension widget. 7 | */ 8 | 9 | 10 | 11 | 12 | 13 | /* 14 | * Setting title of our page. 15 | */ 16 | p5.web.page.set-title:Hyper IDE 17 | 18 | 19 | 20 | 21 | 22 | /* 23 | * Including main Micro CSS files. 24 | */ 25 | micro.css.include 26 | hyper-ide.version 27 | p5.web.include-css-file:@IDE/media/main.css?v={0} 28 | :x:/@hyper-ide.version?value 29 | 30 | 31 | 32 | 33 | 34 | /* 35 | * Creating main Hyper IDE container widget. 36 | */ 37 | create-widgets 38 | hyper-ide.widgets.ide 39 | class:container-fullscreen hyper-ide-container 40 | 41 | 42 | 43 | 44 | 45 | /* 46 | * Checking if client requested to open a specific file or path initially, 47 | * and if so, invoking file responsible for doing just that. 48 | */ 49 | p5.web.query.get:path 50 | if:x:/@p5.web.query.get/*?value 51 | eval-x:x:/+/* 52 | hyper-ide.file-explorer.select-path:x:/@p5.web.query.get/*?value 53 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.folder-plugin.refresh.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates our __[hyper-ide.folder-plugin.refresh]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event creates our refresh folder plugin button. This button will only 7 | * be visible if the currently selected object in your file explorer is a 8 | * folder, and not a file. 9 | * 10 | * When the button is clicked, it will _"refresh"_ the current active folder in 11 | * your file explorer, which implies refetching all files and folders beneath 12 | * the active folder, and re-build the children widgets for that folder in your 13 | * file explorer. 14 | * 15 | * This is useful if you have for instance evaluated some shell script, which 16 | * for some reasons creates new files, such as compiler services, etc - And you 17 | * need to see these files, or interact with them somehow. 18 | */ 19 | create-event:hyper-ide.folder-plugin.refresh 20 | return 21 | button 22 | innerValue:@"" 23 | title:Refresh folder in file explorer 24 | onclick 25 | 26 | /* 27 | * Refreshing active folder. 28 | */ 29 | hyper-ide.file-explorer.refresh-active-folder 30 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.set-code.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file sets the code for the active editor to the value of 3 | * the specified **[code]** argument. 4 | */ 5 | 6 | /* 7 | * Sanity checking arguments. 8 | */ 9 | micro.lambda.contract.min:x:/.. 10 | code:string 11 | 12 | 13 | 14 | 15 | 16 | /* 17 | * First finding active editor's CodeMirror widget. 18 | */ 19 | hyper-ide.active-editor.get-id 20 | 21 | 22 | 23 | 24 | 25 | /* 26 | * Checking if above invocation returned anything, at which point we 27 | * update editor's content. 28 | */ 29 | if:x:/@hyper-ide.active-editor.get-id?value 30 | 31 | /* 32 | * Updating value of CodeMirror instance on client side. 33 | */ 34 | eval-x:x:/+/* 35 | micro.widgets.codemirror.set-value:x:/@hyper-ide.active-editor.get-id?value 36 | value:x:/../*/code?value 37 | 38 | /* 39 | * Returning success to caller. 40 | */ 41 | return:bool:true 42 | 43 | else 44 | 45 | /* 46 | * Oops, no active editor. 47 | */ 48 | micro.windows.info:No active editor 49 | class:micro-windows-info warning 50 | 51 | /* 52 | * Returning failure to caller. 53 | */ 54 | return:bool:false 55 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.is-clean.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file returns a boolean _"true"_ if the active editor is clean, implying 3 | * it does not have unsaved changes. If the current active editor has unsaved 4 | * changes, this file will return _"false"_. 5 | */ 6 | 7 | /* 8 | * Retrieving active editor. 9 | */ 10 | hyper-ide.active-editor.get-id 11 | 12 | 13 | 14 | 15 | 16 | /* 17 | * Verifying editor exists. 18 | */ 19 | if:x:/@hyper-ide.active-editor.get-id?value 20 | 21 | /* 22 | * There is an active editor. 23 | */ 24 | p5.web.widgets.find-first:x:/@hyper-ide.active-editor.get-id?value 25 | element:input 26 | type:hidden 27 | 28 | /* 29 | * Checking if editor is clean. 30 | */ 31 | get-widget-property:x:/@p5.web.widgets.find-first/*/*?value 32 | value 33 | if:x:/-/*/*?value 34 | =:clean 35 | 36 | /* 37 | * Editor is clean. 38 | */ 39 | return:bool:true 40 | 41 | else 42 | 43 | /* 44 | * Editor is dirty. 45 | */ 46 | return:bool:false 47 | 48 | else 49 | 50 | /* 51 | * Oops, no such editor. 52 | */ 53 | micro.windows.info:No active editor 54 | class:micro-windows-info warning 55 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.file-explorer.refresh-active-folder.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file will refresh the file explorer's currently activated folder. 3 | * **Notice**, this file assumes that your currently selected object in your 4 | * file explorer actually is a folder. 5 | */ 6 | 7 | /* 8 | * First retrieving selected treeview item. 9 | */ 10 | hyper-ide.file-explorer.get-active-item 11 | 12 | 13 | 14 | 15 | 16 | /* 17 | * Then verifying that currently selected treeview item actually is a folder. 18 | */ 19 | if 20 | ends-with:x:/@hyper-ide.file-explorer.get-active-item?value 21 | src:/ 22 | 23 | /* 24 | * There's a folder currently selected. 25 | */ 26 | add:x:/+/*/items 27 | src:x:/@hyper-ide.file-explorer.get-active-item?value 28 | micro.widgets.tree.refresh-items:hyper-ide-folder-tree-browser 29 | items 30 | 31 | /* 32 | * Returning success to caller. 33 | */ 34 | return:bool:true 35 | 36 | else 37 | 38 | /* 39 | * No folder currently selected, warning user. 40 | */ 41 | micro.windows.info:No folder is currently selected 42 | class:micro-windows-info warning 43 | 44 | /* 45 | * Returning failure to caller. 46 | */ 47 | return:bool:false 48 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.file-explorer.refresh-folder.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file will refresh the file explorer's currently activated folder. 3 | * **Notice**, this file assumes that your currently selected object in your 4 | * file explorer actually is a folder. 5 | */ 6 | 7 | /* 8 | * Sanity checking invocation. 9 | */ 10 | micro.lambda.contract.min:x:/.. 11 | folder:string 12 | 13 | 14 | 15 | 16 | 17 | /* 18 | * Then verifying that specified [_arg] is a folder. 19 | */ 20 | if 21 | ends-with:x:/../*/folder?value 22 | src:/ 23 | =:bool:true 24 | and 25 | fetch:x:/0/0?value 26 | folder-exists:x:/../*/folder?value 27 | =:bool:true 28 | 29 | /* 30 | * Caller supplied the path to an existing folder. 31 | */ 32 | add:x:/+/*/items 33 | src:x:/../*/folder?value 34 | micro.widgets.tree.refresh-items:hyper-ide-folder-tree-browser 35 | items 36 | 37 | /* 38 | * Returning success to caller. 39 | */ 40 | return:bool:true 41 | 42 | else 43 | 44 | /* 45 | * No folder currently selected, warning user. 46 | */ 47 | micro.windows.info:No folder was given 48 | class:micro-windows-info warning 49 | 50 | /* 51 | * Returning failure to caller. 52 | */ 53 | return:bool:false 54 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.save.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file saves the current active editor. 3 | */ 4 | 5 | /* 6 | * First retrieving active editor, of any. 7 | */ 8 | hyper-ide.active-editor.get-filepath 9 | 10 | 11 | 12 | 13 | 14 | /* 15 | * Verifying there is an active editor. 16 | */ 17 | if:x:/@hyper-ide.active-editor.get-filepath?value 18 | 19 | /* 20 | * There is a currently active editor, saving its content. 21 | */ 22 | hyper-ide.active-editor.get-code 23 | save-file:x:/@hyper-ide.active-editor.get-filepath?value 24 | src:x:/@hyper-ide.active-editor.get-code?value 25 | 26 | /* 27 | * Making sure we update its "clean flag". 28 | */ 29 | hyper-ide.active-editor.set-clean:bool:true 30 | 31 | /* 32 | * Providing some feedback to user. 33 | */ 34 | micro.windows.info:Your code was successfully saved 35 | class:micro-windows-info success 36 | 37 | /* 38 | * Returning success to caller. 39 | */ 40 | return:bool:true 41 | 42 | else 43 | 44 | /* 45 | * No active editor, notifying user 46 | */ 47 | micro.windows.info:There are no active editors 48 | class:micro-windows-info warning 49 | 50 | /* 51 | * Returning failure to caller. 52 | */ 53 | return:bool:false 54 | -------------------------------------------------------------------------------- /helpers/toolbars/secondary-toolbar/04-download.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Downloads active file toolbar button. **Notice**, this button is only 3 | * visible if the current active object in your file explorer is a _file_. 4 | */ 5 | button 6 | innerValue:@"" 7 | title:Download file 8 | disabled 9 | events 10 | 11 | /* 12 | * Sink invoked when active item in file explorer has been changed. 13 | */ 14 | hyper-ide.file-explorer.item-changed 15 | 16 | /* 17 | * Checking if there is a selected item. 18 | */ 19 | if:x:/../*/_arg?value 20 | and 21 | ends-with:x:/../*/_arg?value 22 | src:/ 23 | not 24 | 25 | /* 26 | * Enabling button. 27 | */ 28 | delete-widget-property:x:/../*/_event?value 29 | disabled 30 | 31 | else 32 | 33 | /* 34 | * Disabling button since there is no active item in file explorer. 35 | */ 36 | set-widget-property:x:/../*/_event?value 37 | disabled 38 | 39 | onclick 40 | 41 | /* 42 | * Downloading file. 43 | */ 44 | hyper-ide.file-explorer.get-active-item 45 | micro.download.file:x:/@hyper-ide.file-explorer.get-active-item?value 46 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.close.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file closes the active editor, unless the editor has unsaved changes. 3 | * If you want to force closing of the editor, even if it has 4 | * unsaved changes, you can supply a **[force]** argument, and 5 | * set its value to boolean _"true"_. 6 | */ 7 | 8 | /* 9 | * Sanity checking arguments. 10 | */ 11 | micro.lambda.contract.optional:x:/.. 12 | force:bool 13 | 14 | 15 | 16 | 17 | 18 | /* 19 | * Retrieving active editor, and closing it. 20 | */ 21 | hyper-ide.active-editor.get-filepath 22 | if:x:/-?value 23 | not 24 | 25 | /* 26 | * Oops, no active editor. 27 | */ 28 | micro.windows.info:No active editor 29 | class:micro-windows-info warning 30 | 31 | /* 32 | * Returning failure to caller. 33 | */ 34 | return:bool:false 35 | 36 | 37 | 38 | 39 | 40 | /* 41 | * To stay "DRY", we invoke event that closes multiple editors, passing in 42 | * [exact] to make sure only active editor is closed. 43 | */ 44 | eval-x:x:/+/*/filter 45 | hyper-ide.editors.close 46 | filter:x:/@hyper-ide.active-editor.get-filepath?value 47 | exact:bool:true 48 | 49 | 50 | 51 | 52 | 53 | /* 54 | * Returning success to caller. 55 | */ 56 | return:x:/@hyper-ide.editors.close?value 57 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.javascript.evaluate.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates our __[hyper-ide.plugins.javascript.evaluate]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event creates our _"execute JavaScript file plugin"_ toolbar button. 8 | * This button is only visible if the active object in your file explorer 9 | * is a JavaScript file. 10 | * 11 | * __Notice__, this is a pretty useful plugin, since the CodeMirror's autocomplete object 12 | * is populated according to the context of the page. So if you need to use JavaScript AutoComplete 13 | * features, according to the file you're editing - You would probably want to evaluate its JavaScript 14 | * as you're editing your file. This plugin allows you to do just that. 15 | */ 16 | create-event:hyper-ide.plugins.javascript.evaluate 17 | return 18 | button 19 | innerValue:@"" 20 | title:Execute JavaScript file (useful for populating the AutoComplete object) 21 | onclick 22 | 23 | /* 24 | * Retrieves filename for currently active editor. 25 | */ 26 | hyper-ide.active-editor.get-filepath 27 | 28 | /* 29 | * Including it on page. 30 | */ 31 | p5.web.include-javascript-file:x:/@hyper-ide.active-editor.get-filepath?value 32 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.zip.unzip.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates the __[hyper-ide.plugins.zip.unzip]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event creates the _"unzip file plugin"_ button, which will unzip a zip 8 | * file in the folder where the zip file exists. This button is only visible if 9 | * the active object in your file explorer is a zip file. 10 | */ 11 | create-event:hyper-ide.plugins.zip.unzip 12 | return 13 | button 14 | innerValue:@"" 15 | title:Unzips file in its current folder 16 | onclick 17 | 18 | /* 19 | * Retrieves current path for file, and unzips it in place. 20 | */ 21 | hyper-ide.file-explorer.get-active-item 22 | micro.path.get-folder:x:/@hyper-ide.file-explorer.get-active-item?value 23 | unzip:x:/@hyper-ide.file-explorer.get-active-item?value 24 | dest:x:/@micro.path.get-folder?value 25 | 26 | /* 27 | * Refreshing current folder. 28 | */ 29 | hyper-ide.file-explorer.set-active-item:x:/@micro.path.get-folder?value 30 | hyper-ide.file-explorer.refresh-active-folder 31 | 32 | /* 33 | * Notifying user. 34 | */ 35 | micro.windows.info:File was successfully unzipped 36 | class:micro-windows-info success 37 | -------------------------------------------------------------------------------- /help-files/Hyper IDE/index.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Hyper IDE's main help index landing page. 3 | */ 4 | h2 5 | innerValue:Hyper IDE 6 | 7 | micro.widgets.file 8 | style:"float:right; margin-left: 1rem; margin-bottom: 1rem;" 9 | files 10 | /modules/hyper-ide/desktop.hl 11 | href:/hyper-ide/ 12 | 13 | p 14 | innerValue:@"Hyper IDE is a web based integrated development environment, in addition to also doubling as a file manager. If you're 15 | interested in creating your own Hyperlambda applications, or editing your files on your server - Hyper IDE should be your preferred starting point." 16 | 17 | p 18 | innerValue:@"Although Hyper IDE is very strong when creating Hyperlambda and Phosphorus Five apps and modules, 19 | it supports more than 100 programming languages out of the box, in addition to integration plugins, allowing 20 | you to create compiler services, integrate towards GIT, and many additional features. It arguably is a complete 21 | alternative to Visual Studio or Eclipse. Hyper IDE is extremely easily extended, allowing you to create your 22 | own plugins, and extend Hyper IDE in any ways you see fit." 23 | 24 | 25 | /* 26 | * All files at "root" of Camphora Five help folder. 27 | */ 28 | desktop.help.widgets.help-index 29 | folder:@IDE/help-files/Hyper IDE/ 30 | 31 | 32 | /* 33 | * Meta information for all files in module. 34 | */ 35 | desktop.help.widgets.file-meta 36 | folder:@IDE/ 37 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.folder-plugin.create-skin.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates the __[hyper-ide.folder-plugin.create-micro-skin]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event creates the _"create new skin"_ folder toolbar button, which allows 8 | * the user to create a new Micro CSS skin, by following a simple wizard, which 9 | * extracts all CSS variables from the _"micro.css"_ file, that can be overridden. 10 | * 11 | * This button is only visible if the currently selected folder is 12 | * the _"/modules/micro/media/skins/"_ folder. 13 | */ 14 | create-event:hyper-ide.folder-plugin.create-micro-skin 15 | 16 | /* 17 | * Verifying we're in our "/modules/" folder, and if not, returning early. 18 | * 19 | * This is to prevent this plugin to be visible in any other folders than our "/modules/" folder. 20 | */ 21 | hyper-ide.file-explorer.get-active-item 22 | if:x:/@hyper-ide.file-explorer.get-active-item?value 23 | !=:/modules/micro/media/skins/ 24 | return 25 | 26 | /* 27 | * Returning plugin button to caller. 28 | */ 29 | return 30 | button 31 | innerValue:@"" 32 | title:Create new skin 33 | onclick 34 | 35 | /* 36 | * Evaluates the file that is reponsible for guiding user through the process 37 | * of creating a new skin from a wizard. 38 | */ 39 | micro.evaluate.file:@IDE/helpers/create-skin.hl 40 | -------------------------------------------------------------------------------- /help-files/Hyper IDE/04 - Skinning your system.md: -------------------------------------------------------------------------------- 1 | 2 | ## Skinning your system 3 | 4 | Phosphorus Five is using a CSS framework called _"Micro"_. This is a _"microscopic"_ alternative to 5 | Bootstrap CSS, which easily allows you to skin it, according to your own needs. Hyper IDE contains a 6 | _"wizard"_ skin generator, which you can access if you select the _"/modules/micro/media/skins/"_ 7 | folder. Select this folder, and click the _"star"_ button in your toolbar - At which point your screen 8 | should resemble the following. 9 | 10 | https://phosphorusfive.files.wordpress.com/2018/03/screenshot-skin-wizard1.png 11 | 12 | The skinning wizard is fairly self explaining, and will allow you to manually edit its skin file after 13 | you have gone through it - At which point you can add up custom selectors, load fonts, etc, as you see fit. 14 | The above properties are simply all CSS variables that Micro is using, allowing you to override these 15 | from the core CSS file. The _"Preview"_ tab view will allow you to see how your variables will look like 16 | before you generate your skin file. When you click _"Generate"_, a new CSS file will be created, and 17 | opened for you in Hyper IDE, such that you can manually edit it if you want to. 18 | 19 | Since Phosphorus Five allows you to select a skin according to all files that it finds within the 20 | _"/modules/micro/media/skins/"_ folder, you can immediately start using your new skin, by choosing 21 | it from your Desktop module's settings. 22 | 23 | **Notice**, some basic CSS understanding is beneficial if you want to create your own skin. 24 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.active-editor.set-clean.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file sets the current active editor to clean or dirty, 3 | * depending upon the boolean value of the specified **[clean]** 4 | * argument. 5 | */ 6 | 7 | /* 8 | * Retrieving active editor. 9 | */ 10 | hyper-ide.active-editor.get-id 11 | 12 | 13 | 14 | 15 | 16 | /* 17 | * Sanity checking invocation. 18 | */ 19 | micro.lambda.contract.min:x:/.. 20 | clean:bool 21 | 22 | 23 | 24 | 25 | 26 | /* 27 | * Verifying editor exists. 28 | */ 29 | if:x:/@hyper-ide.active-editor.get-id?value 30 | 31 | /* 32 | * There is an active editor. 33 | */ 34 | p5.web.widgets.find-first:x:/@hyper-ide.active-editor.get-id?value 35 | element:input 36 | type:hidden 37 | 38 | /* 39 | * Checking if caller want to set the clean flag, or set it to dirty. 40 | */ 41 | if:x:/../*/clean?value 42 | 43 | /* 44 | * Setting editor to clean. 45 | */ 46 | set-widget-property:x:/@p5.web.widgets.find-first/*/*?value 47 | value:clean 48 | 49 | else 50 | 51 | /* 52 | * Setting editor to dirty. 53 | */ 54 | set-widget-property:x:/@p5.web.widgets.find-first/*/*?value 55 | value:dirty 56 | 57 | /* 58 | * Returning success to caller. 59 | */ 60 | return:bool:true 61 | 62 | else 63 | 64 | /* 65 | * Oops, no such editor. 66 | */ 67 | micro.windows.info:No active editor 68 | class:micro-windows-info warning 69 | 70 | /* 71 | * Returning failure to caller. 72 | */ 73 | return:bool:false 74 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.folder-plugin.download-as-zip-file.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates the __[hyper-ide.folder-plugin.download-as-zip-file]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event creates the _"download an entire folder as a zip file"_ folder toolbar button. 8 | * 9 | * The button is only visible if the currently selected object in your file explorer is 10 | * a folder, and not a file. 11 | */ 12 | create-event:hyper-ide.folder-plugin.download-as-zip-file 13 | return 14 | button 15 | innerValue:@"" 16 | title:Downloads the entire folder as a zip file 17 | onclick 18 | 19 | /* 20 | * Retrieving current folder. 21 | */ 22 | p5.web.widgets.find-first-ancestor:x:/../*/_event?value 23 | .folder 24 | get-widget-property:x:/-/*/*?value 25 | .folder 26 | 27 | /* 28 | * Checking if destination file name exists, and if so,deleting it. 29 | */ 30 | split:x:/@get-widget-property/*/*?value 31 | =:/ 32 | if 33 | fetch:x:/0/0?value 34 | file-exists:~/temp/{0}.zip 35 | :x:/@split/0/-?name 36 | delete-file:~/temp/{0}.zip 37 | :x:/@split/0/-?name 38 | 39 | /* 40 | * Creating our zip file, and downloading it to client. 41 | */ 42 | zip:~/temp/{0}.zip 43 | :x:/@split/0/-?name 44 | src:x:/@get-widget-property/*/*?value 45 | micro.download.file:~/temp/{0}.zip 46 | :x:/@split/0/-?name 47 | -------------------------------------------------------------------------------- /helpers/file-explorer/select-folder.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is invoked when a folder is selected in your file explorer. 3 | * 4 | * The file expects a __[folder]__ argument being the path to the selected folder. 5 | * This file will create a toolbar allowing the user to edit the folder's properties, 6 | * such as renaming it, deleting it, etc - In addition to loading up all folder plugins, 7 | * and injecting these into your _"folder object toolbar"_. 8 | */ 9 | 10 | 11 | 12 | 13 | 14 | /* 15 | * Sanity checking arguments. 16 | */ 17 | micro.lambda.contract.min:x:/.. 18 | folder:string 19 | 20 | 21 | 22 | 23 | 24 | /* 25 | * Deleting any previously created edit active file object toolbars. 26 | */ 27 | if 28 | fetch:x:/0/0?value 29 | widget-exists:hyper-ide-active-folder-toolbar 30 | delete-widget:hyper-ide-active-folder-toolbar 31 | 32 | 33 | 34 | 35 | 36 | /* 37 | * Hiding any previously shown edit file toolbars. 38 | */ 39 | p5.web.widgets.find-first-like 40 | .toolbar 41 | class:visible 42 | micro.css.toggle:x:/-/*/*?value 43 | class:hide visible 44 | 45 | 46 | 47 | 48 | 49 | /* 50 | * Adding all folder specific plugins. 51 | */ 52 | add:x:/../*/create-widgets/*/micro.widgets.file/*/widgets 53 | micro.evaluate.file:@IDE/helpers/get-plugins.hl 54 | type:hyper-ide.folder-plugin 55 | 56 | 57 | 58 | 59 | 60 | /* 61 | * Making sure we create our active folder toolbar. 62 | */ 63 | create-widgets 64 | micro.widgets.file:hyper-ide-active-folder-toolbar 65 | folder:@IDE/helpers/toolbars/folder-editor/ 66 | after:hyper-ide-toolbars 67 | .folder:x:/../*/folder?value 68 | class:strip right hyper-ide-toolbar 69 | widgets 70 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.editors.get-open-editors.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file returns the paths to all open editors. 3 | */ 4 | 5 | /* 6 | * Finding all editors, and retrieving their filenames. 7 | */ 8 | p5.web.widgets.find:hyper-ide-editor-tab-editors 9 | .editor 10 | get-widget-property:x:/@p5.web.widgets.find/*/*?value 11 | .editor 12 | 13 | 14 | 15 | 16 | 17 | /* 18 | * Iterating through all filenames returned above, and making sure we return 19 | * them to caller, adding the [clean] flag for each of them in the process. 20 | */ 21 | for-each:x:/@get-widget-property/*/* 22 | 23 | /* 24 | * Adding currently iterated editor to [return] below. 25 | */ 26 | add:x:/../*/return 27 | src:x:/@_dp/#?value 28 | 29 | /* 30 | * Retrieving the "clean" flag for currently iterated editor. 31 | */ 32 | p5.web.widgets.find-first:x:/@_dp/#/.?name 33 | element:input 34 | type:hidden 35 | 36 | /* 37 | * Adding [id] for currently iterated editor. 38 | */ 39 | eval-x:x:/+/*/* 40 | add:x:/../*/return/0/- 41 | src 42 | id:x:/@_dp/#/.?name 43 | 44 | /* 45 | * Checking if currently iterated editor is clean. 46 | */ 47 | get-widget-property:x:/@p5.web.widgets.find-first/*/*?value 48 | value 49 | if:x:/@get-widget-property/*/*?value 50 | =:clean 51 | 52 | /* 53 | * Editor is clean. 54 | */ 55 | add:x:/../*/return/0/- 56 | src 57 | clean:bool:true 58 | 59 | else 60 | 61 | /* 62 | * Editor is dirty. 63 | */ 64 | add:x:/../*/return/0/- 65 | src 66 | clean:bool:false 67 | 68 | 69 | 70 | 71 | 72 | /* 73 | * Returning editors to caller. 74 | */ 75 | return 76 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.global-plugin.launch-hypereval.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates the __[hyper-ide.global-plugin.launch-hypereval]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event creates our _"launch Hypereval"_ plugin button. When clicked, 8 | * Hypereval will be launched, and injected at the bottom of your page. 9 | */ 10 | create-event:hyper-ide.global-plugin.launch-hypereval 11 | if 12 | hypereval.version 13 | return 14 | button 15 | innerValue:@"" 16 | title:Launch Hypereval 17 | onclick 18 | 19 | /* 20 | * Toggling button. 21 | */ 22 | micro.css.toggle:x:/../*/_event?value 23 | class:toggled 24 | 25 | /* 26 | * Checking if Hypereval is already loaded, at which point we delete it from page, 27 | * and return early. 28 | */ 29 | if 30 | fetch:x:/0/0?value 31 | widget-exists:hypereval-hyper-ide-plugin 32 | delete-widget:hypereval-hyper-ide-plugin 33 | return 34 | 35 | /* 36 | * Launching Hypereval. 37 | */ 38 | create-widget:hypereval-hyper-ide-plugin 39 | class:container-fullscreen 40 | widgets 41 | div 42 | class:row 43 | widgets 44 | div 45 | class:col 46 | widgets 47 | hypereval.widgets.eval 48 | auto-focus:false 49 | 50 | /* 51 | * Srolling Hypereval into view. 52 | */ 53 | micro.page.scroll-into-view:hypereval-hyper-ide-plugin 54 | -------------------------------------------------------------------------------- /help-files/Hyper IDE/03 - Create an AngularJS and MySQL app in 1 second.md: -------------------------------------------------------------------------------- 1 | ## Create an AngularJS and MySQL app in 1 second 2 | 3 | Select your `/modules/` folder. Then click the `+` button in your toolbar, assuming you 4 | have enabled the plugin that allows you to create a new module. Then name your app _"todo"_, 5 | and select the `angular-todo` type. At which point your screen should resemble the following. 6 | 7 | https://phosphorusfive.files.wordpress.com/2018/03/angular-todo-screenshot.png 8 | 9 | Then simply click the _"Create"_ button, and you're done. If you want to try out your app, 10 | you can [click this link](/todo). The above process will create a new module for you, having the following files. 11 | 12 | * _"index.html"_ - Your Angular HTML file 13 | * _"controller.js"_ - Your Angular controller 14 | * _"styles.css"_ - Some default styling 15 | * _"desktop.hl"_ - A desktop icon for Phosphorus Five 16 | * _"launch.hl"_ - Your app's launcher file 17 | * _"startup.hl"_ - Your app's startup file 18 | * _"install.hl"_ - Evaluated when your app is installed 19 | * _"uninstall.hl"_ - Evaluated when your app is uninstalled 20 | 21 | In the video below, I walk you through the main features of the app you just created, explaining the 22 | different parts of your app. Unless you're already an AngularJS guru, you will probably benefit from 23 | watching it. And even for an AngularJS guru, there are a couple of points you would want to understand 24 | which are a part of Phosphorus Five, and not Angular features. The app is using Hyper Core on the server 25 | side, to persist your changes into your MySQL database. You can find the documentation for Hyper Core 26 | in the _"Hyper Core"_ section. 27 | 28 | https://www.youtube.com/watch?v=Zr5f7oweed8 29 | -------------------------------------------------------------------------------- /helpers/file-explorer/select-file.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is invoked when the user clicks a file in the file explorer. 3 | * The file expects a __[file]__ argument being the fully qualified path 4 | * of the file user clicked, or selected somehow. 5 | * 6 | * This file will edit the specified __[file]__, using its associated 7 | * CodeMirror editor - If a mapping between the file's file extension and a 8 | * CodeMirror mode exists. 9 | */ 10 | 11 | 12 | 13 | 14 | 15 | /* 16 | * Signal node to separate arguments from the rest of our lambda. 17 | */ 18 | .signal 19 | 20 | 21 | 22 | 23 | 24 | /* 25 | * Sanity checking arguments. 26 | */ 27 | micro.lambda.contract.min:x:/.. 28 | file:string 29 | 30 | 31 | 32 | 33 | 34 | /* 35 | * Deleting any previously created edit active folder object toolbars. 36 | */ 37 | if 38 | fetch:x:/0/0?value 39 | widget-exists:hyper-ide-active-folder-toolbar 40 | 41 | /* 42 | * A folder is currently edited, deleting active file object toolbar for 43 | * the folder that is edited. 44 | */ 45 | delete-widget:hyper-ide-active-folder-toolbar 46 | 47 | 48 | 49 | 50 | 51 | /* 52 | * Checking if file is already open, at which point we simply activate existing 53 | * editor. 54 | */ 55 | p5.web.widgets.find:hyper-ide-editor-tab-buttons 56 | .activate:x:/../*/file?value 57 | if:x:/@p5.web.widgets.find/*/*?value 58 | 59 | /* 60 | * Editor for file is already open, activating existing editor only. 61 | */ 62 | eval-x:x:/+/* 63 | micro.evaluate.file:@IDE/helpers/activate-editor.hl 64 | file:x:/../*/file?value 65 | 66 | else 67 | 68 | /* 69 | * Editing file. 70 | */ 71 | add:x:/+ 72 | src:x:/@.signal/--/<- 73 | micro.evaluate.file:@IDE/helpers/edit-file.hl 74 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.css.beautify.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.plugins.css.beautify]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event creates our _"beautify CSS file plugin"_ button. This button is 7 | * only visible if the active object in your file explorer is a CSS file. 8 | * 9 | * When clicked, the button will _"beautify"_ the CSS contents of the 10 | * currently Active Editor. 11 | */ 12 | create-event:hyper-ide.plugins.css.beautify 13 | return 14 | button 15 | innerValue:@"" 16 | title:Beautifies your CSS 17 | onclick 18 | 19 | /* 20 | * Sends JavaScript necessary to beautify CSS to client. 21 | * 22 | * First finding active editor. 23 | */ 24 | hyper-ide.active-editor.get-id 25 | 26 | /* 27 | * Then finding active editor's textarea widget, which is necessary to 28 | * be able to reference CodeMirror instance on client side. 29 | */ 30 | p5.web.widgets.find-first:x:/@hyper-ide.active-editor.get-id?value 31 | element:textarea 32 | 33 | /* 34 | * Including Sencha's "CSS beautify" JavaScript on client side. 35 | */ 36 | p5.web.include-javascript-file:@IDE/media/cssbeautify.js 37 | 38 | /* 39 | * Sends JavaScript to client that beautifies CSS, and updates CodeMirror 40 | * instance with beautified CSS. 41 | */ 42 | p5.web.send-javascript:@" 43 | var css = p5['{0}'].getDoc().getValue(); 44 | var res = cssbeautify(css); 45 | p5['{0}'].getDoc().setValue(res); 46 | " 47 | :x:/@p5.web.widgets.find-first/*/*?value 48 | 49 | /* 50 | * Giving user some feedback. 51 | */ 52 | micro.windows.info:CSS was successfully beautified 53 | class:micro-windows-info success 54 | -------------------------------------------------------------------------------- /helpers/toolbars/secondary-toolbar/03-bookmark.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Bookmark toolbar button. This button creates a textbox containing the URL to open up 3 | * currently active file, allowing the user to copy this URL to his clipboard. 4 | */ 5 | button 6 | innerValue:@"" 7 | title:Copy URL to current path 8 | disabled 9 | events 10 | 11 | /* 12 | * Sink invoked when active item in file explorer has been changed. 13 | */ 14 | hyper-ide.file-explorer.item-changed 15 | 16 | /* 17 | * Checking if there is a selected item. 18 | */ 19 | if:x:/../*/_arg?value 20 | 21 | /* 22 | * Enabling button. 23 | */ 24 | delete-widget-property:x:/../*/_event?value 25 | disabled 26 | 27 | else 28 | 29 | /* 30 | * Disabling button since there is no active item in file explorer. 31 | */ 32 | set-widget-property:x:/../*/_event?value 33 | disabled 34 | 35 | onclick 36 | 37 | /* 38 | * Shows the URL for the current path to the user. 39 | */ 40 | create-widget:hyper-ide-bookmark-url 41 | element:input 42 | type:text 43 | class:hyper-ide-bookmark-textbox 44 | onkeydown:@"if (event.keyCode == 13 || event.keyCode == 27) {p5.$('hyper-ide-bookmark-url').raise('.onclose');return false;}" 45 | onblur 46 | 47 | /* 48 | * Simply invoking [.onclose] when widget looses focus. 49 | */ 50 | p5.web.widgets.ajax-events.raise:x:/../*/_event?value 51 | .onclose 52 | 53 | .onclose 54 | 55 | /* 56 | * Deleting widget. 57 | */ 58 | delete-widget:x:/../*/_event?value 59 | 60 | oninit 61 | 62 | /* 63 | * Figuring out the URL for current path, and selecting all text. 64 | */ 65 | hyper-ide.file-explorer.get-active-item 66 | p5.web.get-location-url 67 | set-widget-property:x:/../*/_event?value 68 | value:{0}?path={1} 69 | :x:/@p5.web.get-location-url?value 70 | :x:/@hyper-ide.file-explorer.get-active-item?value 71 | micro.page.set-focus:x:/../*/_event?value 72 | -------------------------------------------------------------------------------- /helpers/upload-files.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Responsible for handling upload requests initiated by user. 3 | * Expects __[files]__ being a bunch of files that is being uploaded. 4 | * Will save all specified files to the currently selected folder in 5 | * the _"file explorer"_ of Hyper IDE. 6 | */ 7 | 8 | 9 | 10 | 11 | 12 | /* 13 | * Sanity checking arguments. 14 | */ 15 | micro.lambda.contract.min:x:/.. 16 | files 17 | 18 | 19 | 20 | 21 | 22 | /* 23 | * Retrieving selected folder, and making sure user has selected a folder. 24 | */ 25 | hyper-ide.file-explorer.get-active-item 26 | if 27 | ends-with:x:/@hyper-ide.file-explorer.get-active-item?value 28 | src:/ 29 | not 30 | 31 | /* 32 | * Oops, user hasn't selected a folder. 33 | * Warning user and returning early. 34 | */ 35 | micro.windows.info:You must select a folder to be able to upload files 36 | class:micro-windows-info warning 37 | return 38 | 39 | 40 | 41 | 42 | 43 | /* 44 | * Iterating through each file in request. 45 | */ 46 | for-each:x:/../*/files/* 47 | 48 | /* 49 | * Checking if file already exists from before, at which point we delete it. 50 | * 51 | * This makes sure an upload request will always overwrite existing files with 52 | * the same name(s). 53 | */ 54 | if 55 | fetch:x:/0/0?value 56 | file-exists:{0}{1} 57 | :x:/@hyper-ide.file-explorer.get-active-item?value 58 | :x:/@_dp/#/*/original-filename?value 59 | 60 | /* 61 | * Destination file already exists, making sure we delete it. 62 | */ 63 | delete-file:{0}{1} 64 | :x:/@hyper-ide.file-explorer.get-active-item?value 65 | :x:/@_dp/#/*/original-filename?value 66 | 67 | /* 68 | * Moving file from temporary folder to destination folder. 69 | */ 70 | move-file:x:/@_dp/#?value 71 | dest:{0}{1} 72 | :x:/@hyper-ide.file-explorer.get-active-item?value 73 | :x:/@_dp/#/*/original-filename?value 74 | 75 | 76 | 77 | 78 | 79 | /* 80 | * Refresh our destination folder. 81 | */ 82 | hyper-ide.file-explorer.refresh-active-folder 83 | 84 | 85 | 86 | 87 | 88 | /* 89 | * Providing some feedback to user. 90 | */ 91 | micro.windows.info:{0} files successfully uploaded 92 | :x:/../*/files/*?count 93 | class:micro-windows-info success 94 | -------------------------------------------------------------------------------- /configuration/extension2cm-instance.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Maps file extensions to CodeMirror modes. Edit this file to add support for 3 | * additional file extensions. The file extension is the name of the node, and 4 | * the associated CodeMirror editor _"mode"_ is the value. 5 | */ 6 | hl:hyperlambda 7 | groovy:groovy 8 | go:go 9 | ini:properties 10 | properties:properties 11 | css:css 12 | scss:css 13 | html:htmlmixed 14 | htm:htmlmixed 15 | shtm:htmlmixed 16 | shtml:htmlmixed 17 | xhtml:htmlmixed 18 | cfm:htmlmixed 19 | cfml:htmlmixed 20 | cfc:htmlmixed 21 | dhtml:htmlmixed 22 | xht:htmlmixed 23 | tpl:htmlmixed 24 | twig:htmlmixed 25 | hbs:htmlmixed 26 | handlebars:htmlmixed 27 | kit:htmlmixed 28 | jsp:htmlmixed 29 | aspx:htmlmixed 30 | ascx:htmlmixed 31 | asp:htmlmixed 32 | master:htmlmixed 33 | cshtml:htmlmixed 34 | vbhtml:htmlmixed 35 | ejs:htmlembedded 36 | dust:htmlembedded 37 | erb:htmlembedded 38 | js:javascript 39 | jsx:javascript 40 | jsm:javascript 41 | _js:javascript 42 | vbs:vbscript 43 | vb:vb 44 | json:javascript 45 | xml:xml 46 | svg:xml 47 | wxs:xml 48 | wxl:xml 49 | wsdl:xml 50 | rss:xml 51 | atom:xml 52 | rdf:xml 53 | xslt:xml 54 | xsl:xml 55 | xul:xml 56 | xbl:xml 57 | mathml:xml 58 | config:xml 59 | plist:xml 60 | xaml:xml 61 | csproj:xml 62 | vbproj:xml 63 | sln:xml 64 | php:php 65 | php3:php 66 | php4:php 67 | php5:php 68 | phtm:php 69 | phtml:php 70 | ctp:php 71 | c:clike 72 | h:clike 73 | i:clike 74 | cc:clike 75 | cp:clike 76 | cpp:clike 77 | c++:clike 78 | cxx:clike 79 | hh:clike 80 | hpp:clike 81 | hxx:clike 82 | h++:clike 83 | ii:clike 84 | ino:clike 85 | cs:clike 86 | asax:clike 87 | ashx:clike 88 | java:clike 89 | scala:clike 90 | sbt:clike 91 | coffee:coffeescript 92 | cf:coffeescript 93 | cson:coffeescript 94 | _coffee:coffeescript 95 | clj:clojure 96 | cljs:clojure 97 | cljx:clojure 98 | pl:perl 99 | pm:perl 100 | rb:ruby 101 | ru:ruby 102 | gemspec:ruby 103 | rake:ruby 104 | py:python 105 | pyw:python 106 | wsgi:python 107 | sass:sass 108 | lua:lua 109 | sql:sql 110 | diff:diff 111 | patch:diff 112 | md:markdown 113 | markdown:markdown 114 | mdown:markdown 115 | mkdn:markdown 116 | yaml:yaml 117 | yml:yaml 118 | hx:haxe 119 | sh:shell 120 | command:shell 121 | bash:shell 122 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.javascript.minify.hl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Creates the __[hyper-ide.plugins.javascript.minify]__ Active Event. 4 | */ 5 | 6 | /* 7 | * This event creates our _"minify JavaScript plugin"_ button. This button is 8 | * only visible if the active object in your file explorer is a JavaScript file. 9 | */ 10 | create-event:hyper-ide.plugins.javascript.minify 11 | return 12 | button 13 | innerValue:@"" 14 | title:Minifies your JavaScript 15 | onclick 16 | 17 | /* 18 | * Retrieves code for currently visible editor, minifies it, and updates 19 | * value of editor. 20 | * 21 | * Notice, we also calculate length of both original version and minified version, 22 | * to give user some feedback about how many percent/KB of the code was eliminated. 23 | */ 24 | hyper-ide.active-editor.get-code 25 | length:x:/@hyper-ide.active-editor.get-code?value 26 | p5.web.javascript.minify:x:/@hyper-ide.active-editor.get-code?value 27 | length:x:/@p5.web.javascript.minify/*?value 28 | 29 | /* 30 | * Unless we could remove something during minification, we inform user, 31 | * and return early. 32 | */ 33 | if:x:/../*/length/[0,1]?value 34 | =:x:/../*/length/[1,2]?value 35 | 36 | /* 37 | * No further minification is possible. 38 | */ 39 | micro.windows.info:No further minification is possible 40 | class:micro-windows-info warning 41 | return 42 | 43 | /* 44 | * Updating code. 45 | */ 46 | hyper-ide.active-editor.set-code:x:/@p5.web.javascript.minify/*?value 47 | 48 | /* 49 | * Notifying user, making sure we inform him of how many percent of the code was removed. 50 | */ 51 | -:x:/../*/length/[0,1]?value.decimal 52 | _:x:/../*/length/[1,2]?value.decimal 53 | /:x:/-?value.decimal 54 | _:1024 55 | /:x:/../*/length/[1,2]?value.decimal 56 | _:x:/../*/length/[0,1]?value.decimal 57 | -:decimal:1 58 | _:x:/./-?value 59 | *:x:/-?value 60 | _:100 61 | micro.windows.info:"JavaScript successfully minified, we saved {0}% and {1:0.#}KB" 62 | :x:/@*?value.int 63 | :x:/./-4?value 64 | class:micro-windows-info success 65 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.css.minify.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.plugins.css.minify]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event creates our _"minify CSS plugin"_ button. This button is only 7 | * visible if the active object in your file explorer is a CSS file. 8 | * 9 | * When clicked, the button will _"minify"_ the CSS contents of the 10 | * currently Active Editor. 11 | */ 12 | create-event:hyper-ide.plugins.css.minify 13 | return 14 | button 15 | innerValue:@"" 16 | title:Minifies your CSS 17 | onclick 18 | 19 | /* 20 | * Retrieves code for currently visible editor, minifies it, and updates 21 | * value of editor. 22 | * 23 | * Notice, we also calculate length of both original version and minified version, 24 | * to give user some feedback about how many percent of the code was eliminated. 25 | */ 26 | hyper-ide.active-editor.get-code 27 | length:x:/@hyper-ide.active-editor.get-code?value 28 | p5.web.css.minify:x:/@hyper-ide.active-editor.get-code?value 29 | length:x:/@p5.web.css.minify/*?value 30 | 31 | /* 32 | * Unless we could remove something during minification, we inform user, 33 | * and return early. 34 | */ 35 | if:x:/../*/length/[0,1]?value 36 | =:x:/../*/length/[1,2]?value 37 | 38 | /* 39 | * No further minification is possible. 40 | */ 41 | micro.windows.info:No further minification is possible 42 | class:micro-windows-info warning 43 | return 44 | 45 | /* 46 | * Updating code. 47 | */ 48 | hyper-ide.active-editor.set-code:x:/@p5.web.css.minify/*?value 49 | 50 | /* 51 | * Notifying user, making sure we inform him of how many percent of the code was removed. 52 | */ 53 | -:x:/../*/length/[0,1]?value.decimal 54 | _:x:/../*/length/[1,2]?value.decimal 55 | /:x:/-?value.decimal 56 | _:1024 57 | /:x:/../*/length/[1,2]?value.decimal 58 | _:x:/../*/length/[0,1]?value.decimal 59 | -:decimal:1 60 | _:x:/./-?value 61 | *:x:/-?value 62 | _:100 63 | micro.windows.info:"CSS successfully minified, we saved {0}% and {1:0.#}KB" 64 | :x:/@*?value.int 65 | :x:/./-4?value 66 | class:micro-windows-info success 67 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.markdown.preview.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.plugins.markdown.preview]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event creates the _"Markdown preview plugin"_ button. This button is 7 | * only visible if the active object in your file explorer is a Markdown file. 8 | * 9 | * When clicked, the button will open up a modal widget, displaying the Markdown 10 | * transformed into HTML in _"preview mode"_. 11 | */ 12 | create-event:hyper-ide.plugins.markdown.preview 13 | return 14 | button 15 | innerValue:@"" 16 | title:Preview your Markdown 17 | onclick 18 | 19 | /* 20 | * Retrieves code and filename. 21 | * 22 | * The latter is necessary to figure out relative URL to use 23 | * for fetching relative images, etc. 24 | */ 25 | hyper-ide.active-editor.get-code 26 | hyper-ide.active-editor.get-filepath 27 | 28 | /* 29 | * Figuring out root URL for document. 30 | */ 31 | split:x:/@hyper-ide.active-editor.get-filepath?value 32 | =:/ 33 | set:x:/@split/0/- 34 | join:x:/@split/*?name 35 | sep:/ 36 | set:x:/@join?value 37 | src:/{0}/ 38 | :x:/@join?value 39 | trim:x:/@join?value 40 | chars:// 41 | 42 | /* 43 | * Transforming content to Markdown. 44 | */ 45 | markdown2html:x:/@hyper-ide.active-editor.get-code?value 46 | root-url:{0} 47 | :x:/@join?value 48 | 49 | /* 50 | * Opens a modal window, displaying the Markdown as HTML. 51 | */ 52 | eval-x:x:/+/*/*/*/div/*/innerHtml 53 | create-widgets 54 | micro.widgets.modal:hyper-ide-markdown-preview-modal 55 | widgets 56 | text:@"" 57 | div 58 | innerValue:x:/@markdown2html?value 59 | div 60 | class:right 61 | widgets 62 | div 63 | class:strip 64 | widgets 65 | button 66 | innerValue:Close 67 | onclick 68 | 69 | /* 70 | * Deleting modal widget. 71 | */ 72 | delete-widget:hyper-ide-markdown-preview-modal 73 | -------------------------------------------------------------------------------- /helpers/file-explorer/expand-file-explorer-path.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file opens up the specified __[path]__ in Hyper IDE, by expanding 3 | * the tree view (if possible), and opening the file, if the specified 4 | * __[path]__ points to a file. 5 | */ 6 | micro.lambda.contract.min:x:/.. 7 | path:string 8 | 9 | 10 | 11 | 12 | 13 | /* 14 | * Checking if item is already open, at which point we simply activate it, 15 | * and return early. 16 | */ 17 | p5.web.widgets.find-first:hyper-ide-editor-tab-buttons 18 | .activate:x:/../*/path?value 19 | if:x:/@p5.web.widgets.find-first/*/*?value 20 | 21 | /* 22 | * Fiven [path] is a file, and it is already being edited. 23 | * Hence, simply activating existing editor, and returning early. 24 | */ 25 | get-widget-property:x:/@p5.web.widgets.find-first/*/*?value 26 | .activate 27 | hyper-ide.file-explorer.set-active-item:x:/@get-widget-property/*/*?value 28 | return 29 | 30 | 31 | 32 | 33 | 34 | 35 | /* 36 | * These two next ones will contain the folder, and the file name (if any). 37 | */ 38 | .folder 39 | .file 40 | 41 | 42 | 43 | 44 | 45 | /* 46 | * Splitting given path on each "/", to retrieve all entities, for then to 47 | * iterate through them all, making sure we expand our tree view. 48 | */ 49 | split:x:/../*/path?value 50 | =:/ 51 | 52 | 53 | 54 | 55 | 56 | /* 57 | * Checking is the specified [path] points to a folder or a file. 58 | */ 59 | split:x:/@split/0/-?name 60 | =:. 61 | if:x:/@split/*?count 62 | >:int:1 63 | 64 | /* 65 | * [path] points to a file. 66 | * 67 | * Removing the file parts, and putting it into our above [.file] node's value. 68 | */ 69 | set:x:/@.file?value 70 | src:x:/@split/@split/0/-?name 71 | set:x:/@split/@split/0/- 72 | 73 | 74 | 75 | 76 | 77 | /* 78 | * Looping through each entity of our path, making sure we expand the tree view 79 | * for that item. 80 | */ 81 | for-each:x:/@split/@split/*?name 82 | 83 | /* 84 | * Appending currently iterated entity into our [.folder] variable, 85 | * such that we can incrementally expand our ways into the specified path. 86 | */ 87 | set:x:/@.folder?value 88 | src:{0}/{1} 89 | :x:/@.folder?value 90 | :x:/@_dp?value 91 | 92 | /* 93 | * Toggling the item, forcing it to expand. 94 | */ 95 | add:x:/+/*/items 96 | src:{0}/ 97 | :x:/@.folder?value 98 | micro.widgets.tree.toggle-items:hyper-ide-folder-tree-browser 99 | force-expand:bool:true 100 | items 101 | 102 | 103 | 104 | 105 | 106 | /* 107 | * Making sure we select our final resulting item 108 | */ 109 | hyper-ide.file-explorer.set-active-item:x:/../*/path?value 110 | -------------------------------------------------------------------------------- /help-files/Hyper IDE/02 - The fastest Hello World tutorial in the world.md: -------------------------------------------------------------------------------- 1 | ## The fastest Hello World tutorial in the world 2 | 3 | The easiest way to get started with Hyper IDE, is to select the `/modules/` folder, for then to click 4 | the _"star"_ button in your toolbar, assuming you have enabled the plugin that allows you to create new modules. 5 | Then name your app _"hello-world"_, and select the `hello-world` type. At which point your screen should resemble 6 | the following. 7 | 8 | https://phosphorusfive.files.wordpress.com/2018/03/hell-world-template-screenshot.png 9 | 10 | Then simply click the _"Create"_ button, and you're done. If you want to try out your app, 11 | you can [click this link](/hello-world). Your app consists of 5 files, most of which only 12 | serves as a starting ground for your own apps. 13 | 14 | * _"desktop.hl"_ - A _"desktop"_ icon 15 | * _"launch.hl"_ - Your app's launcher file 16 | * _"startup.hl"_ - Your app's startup file 17 | * _"install.hl"_ - Evaluated when your app is installed, through for instance the _"Bazar"_ 18 | * _"uninstall.hl"_ - Evaluated when your app is uninstalled 19 | 20 | The app is a _"Hyperlambda"_ web app. Hyperlambda is a programming language that is native to Phosphorus Five, 21 | and thoroughly documented in the _"Hyperlambda"_ section of this help system. 22 | 23 | ### The code 24 | 25 | Most of the above files are simply created as a wire frame for your own apps. However, the _"launch.hl"_ file 26 | contains a couple of important constructs. The code for your _"launch.hl"_ file first includes Micro's CSS 27 | files. Micro is a grid based CSS framework, that is native to Phosphorus Five. We will look at Micro in 28 | other parts of this documentation. 29 | 30 | After it has included Micro, it creates a `container/row/col` wireframe for us, which you'll probably recognise 31 | if you have done some Bootstrap CSS development. Basically this part creates a _"container"_, which contains 32 | one _"row"_, having two _"columns"_, where each column is 100% width. This means that the last column will 33 | be shown beneath the first one. 34 | 35 | Inside our second column, we create a wrapper div, which adds some shading and chrome for us, before we include 36 | an 'h3' element, followed by a bulleted list, and a button. Our button has an **[onclick]** Ajax event 37 | handler, which once clicked, will change the **[innerValue]** of our button to _"Hello World"_. If you [try your app](/hello-world), 38 | you can view its source, and probably understand the relationship between the above Hyperlambda, and the HTML 39 | it generates. 40 | 41 | **Notice**, the _"Hyperlambda"_ parts of this documentation goes through this app in much more detail in 42 | one of its chapters, than we do here. 43 | 44 | ### Distributing your app 45 | 46 | At this point, you can distribute your app, by simply zipping your folder, and give away this zip file to 47 | anyone who wants to install your app on their own server. Installation of such apps, is easily done through 48 | the Desktop module. 49 | -------------------------------------------------------------------------------- /helpers/get-plugins.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Returns all existing Hyper IDE plugins that are enabled in installation for the specified 3 | * __[type]__. 4 | * 5 | * The file expects __[type]__ being the type of plugins to retrieve. **Notice**, the 6 | * __[type]__ argument is expected to be the fully qualified namespace 7 | * of which types of plugins to retrieve, such as e.g. __[hyper-ide.plugins.css]__ - 8 | * At which point all plugins starting with `hyper-ide.plugins.css` will be returned 9 | * to caller. 10 | * 11 | * In general there exists three main different categories of plugins you can create 12 | * for Hyper IDE, which are as follows. 13 | * 14 | * - __[hyper-ide.folder-plugin.xxx]__ - Plugins loaded only if a folder is selected in your file explorer 15 | * - __[hyper-ide.global-plugin.xxx]__ - Global plugins, always available, regardless of what object you have selected in your file explorer 16 | * - __[hyper-ide.plugins.yyy.xxx]__ - File _"mode"_ type of plugin, where the _"yyy"_ parts are your CodeMirror _"mode"_ 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | /* 24 | * Sanity checking invocation. 25 | */ 26 | micro.lambda.contract.min:x:/.. 27 | type:string 28 | 29 | 30 | 31 | 32 | 33 | /* 34 | * Retrieving active events that will create "global" plugin buttons. 35 | * 36 | * Making sure we check for the existence of a configuration file, and if it exists, 37 | * we turn OFF everything not explicitly turned on in that file. 38 | */ 39 | vocabulary:~{0}. 40 | :x:/../*/type?value 41 | if 42 | fetch:x:/0/0?value 43 | file-exists:@IDE/configuration/plugins.hl 44 | load-file:@IDE/configuration/plugins.hl 45 | 46 | /* 47 | * Removing all plugins not explicitly mentioned in plugin configuration file. 48 | */ 49 | for-each:x:/@vocabulary/* 50 | 51 | /* 52 | * Checking if currently iterated plugin is explicitly turned ON in 53 | * configuration file. 54 | */ 55 | if:x:/@load-file/*/*/{0} 56 | :x:/@_dp/#?value 57 | not 58 | 59 | /* 60 | * Currently iterated plugin was not explicitly mentioned in plugin 61 | * configuration file. 62 | */ 63 | set:x:/@_dp/# 64 | 65 | 66 | 67 | 68 | 69 | /* 70 | * Adding all plugin active events into [.plugins] lambda object below, such that 71 | * we can easily evaluate all plugin events, which are expected to return some 72 | * sort of widget(s) which we append into toolbar for Hyper IDE. 73 | */ 74 | .plugins 75 | return:x:/../*/* 76 | for-each:x:/@vocabulary/*?value 77 | insert-before:x:/@.plugins/0/- 78 | src:x:/@_dp?value 79 | 80 | 81 | 82 | 83 | 84 | /* 85 | * Evaluating [.plugins] lambda, which will invoke all plugin button events for us, 86 | * and return its result. 87 | */ 88 | eval:x:/@.plugins 89 | 90 | 91 | 92 | 93 | 94 | /* 95 | * Returning all plugins to caller. 96 | */ 97 | add:x:/+ 98 | src:x:/@eval/* 99 | return 100 | -------------------------------------------------------------------------------- /helpers/file-explorer/get-file-explorer-objects.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file retrieves all files and folders beneath the specified __[folder]__, 3 | * and returns these to caller. It is used by Hyper IDE's file explorer when 4 | * it needs to retrieve items for some specific folder node. 5 | */ 6 | 7 | 8 | 9 | 10 | 11 | /* 12 | * Sanity checking arguments. 13 | */ 14 | micro.lambda.contract.min:x:/.. 15 | folder:string 16 | 17 | 18 | 19 | 20 | 21 | /* 22 | * Lists all folders beneath specified [folder], and iterates through them, 23 | * making sure we return one item for each. 24 | */ 25 | list-folders:x:/../*/folder?value 26 | for-each:x:/@list-folders/*?name 27 | 28 | /* 29 | * Figuring out name of folder, and making sure we create one return value for it. 30 | */ 31 | split:x:/@_dp?value 32 | =:/ 33 | add:x:/../*/return 34 | src:@"{0}:{1}" 35 | :x:/@split/0/-?name 36 | :x:/@_dp?value 37 | 38 | /* 39 | * Skipping "/db/" folder, since it's illegal to browse. 40 | */ 41 | if:x:/@_dp?value 42 | =:/db/ 43 | continue 44 | 45 | /* 46 | * Checking if currently iterated folder is a "leaf folder", meaning having no 47 | * children folders and files of its own. 48 | * 49 | * This is important since it modifies the CSS class of the item in our TreeView. 50 | */ 51 | .leaf:bool:false 52 | try 53 | 54 | /* 55 | * Checking if folder has any children folders. 56 | */ 57 | list-folders:x:/@_dp?value 58 | if:x:/@list-folders/* 59 | not 60 | 61 | /* 62 | * Then checking if it has any files. 63 | */ 64 | list-files:x:/@_dp?value 65 | if:x:/-/* 66 | not 67 | set:x:/@.leaf?value 68 | src:bool:true 69 | 70 | catch 71 | 72 | /* 73 | * Since user doesn't have read access to folder, we default it to a leaf folder. 74 | */ 75 | set:x:/.leaf?value 76 | src:bool:true 77 | /* 78 | * Checking if anything above made our folder to a "leaf" folder. 79 | */ 80 | if:x:/@.leaf?value 81 | add:x:/../*/return/0/- 82 | src 83 | class:tree-leaf 84 | 85 | 86 | 87 | 88 | 89 | /* 90 | * Then listing all files beneath currently iterated folder, and making sure 91 | * we return one item for each file. 92 | */ 93 | list-files:x:/../*/folder?value 94 | for-each:x:/@list-files/*?name 95 | 96 | /* 97 | * Figuring out name of file, and making sure we create one return value for it. 98 | */ 99 | split:x:/@_dp?value 100 | =:/ 101 | add:x:/../*/return 102 | src:@"{0}:{1}" 103 | :x:/@split/0/-?name 104 | :x:/@_dp?value 105 | 106 | /* 107 | * Making sure we return file as a file, and not a folder. 108 | */ 109 | add:x:/../*/return/0/- 110 | src 111 | class:file tree-leaf 112 | 113 | 114 | 115 | 116 | 117 | /* 118 | * Returning items to caller. 119 | */ 120 | return -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.editors.set-active-editor.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file sets the active editor to the given **[editor]** value, which can either 3 | * be the path to an already open editor, or a CodeMirror widget wrapper ID for an editor 4 | * that is already open. 5 | */ 6 | 7 | /* 8 | * Sanity checking arguments. 9 | */ 10 | micro.lambda.contract.min:x:/.. 11 | editor:string 12 | 13 | 14 | 15 | 16 | 17 | /* 18 | * Checking if specified [editor] argument is a filepath, and if not, assuming 19 | * it's the ID to its CodeMirror editor, and making sure we turn it into a filepath. 20 | */ 21 | if 22 | starts-with:x:/../*/editor?value 23 | src:/ 24 | not 25 | 26 | /* 27 | * Specified [editor] argument is not a filepath, assuming it's the ID of our 28 | * CodeMirror editor, hence retrieving CodeMirror editor's filepath, which can 29 | * be found in CodeMirror editor's parent widgets [.editor] attribute. 30 | */ 31 | p5.web.widgets.get-parent:x:/../*/editor?value 32 | get-widget-property:x:/@p5.web.widgets.get-parent/*/*?value 33 | .editor 34 | 35 | /* 36 | * Updating [editor] argument to reflect filepath of editor caller 37 | * wants to activate. 38 | */ 39 | set:x:/../*/editor?value 40 | src:x:/@get-widget-property/*/*?value 41 | 42 | 43 | 44 | 45 | 46 | /* 47 | * Checking if editor caller wants to activate is already the active editor, at 48 | * which point we don't go through the entire activation process, but only a part of it. 49 | */ 50 | if 51 | hyper-ide.active-editor.get-filepath 52 | =:x:/../*/editor?value 53 | 54 | /* 55 | * Notice, we still need to make sure the toolbar is the currently active toolbar. 56 | */ 57 | p5.web.widgets.find-first:hyper-ide-toolbar-wrapper 58 | .toolbar:x:/../*/editor?value 59 | get-widget-property:x:/@p5.web.widgets.find-first/*/*?value 60 | class 61 | if:x:/@get-widget-property/*/*?value 62 | !~:visible 63 | 64 | /* 65 | * Need to activate editor's toolbar. 66 | */ 67 | p5.web.widgets.find-first-like:hyper-ide-toolbar-wrapper 68 | class:visible 69 | 70 | /* 71 | * Finding any previously activated toolbars, and hiding them. 72 | */ 73 | if:x:/@p5.web.widgets.find-first-like/*/*?value 74 | micro.css.toggle:x:/@p5.web.widgets.find-first-like/*/*?value 75 | class:visible hide 76 | 77 | /* 78 | * Displaying current file's toolbar. 79 | */ 80 | micro.css.toggle:x:/@p5.web.widgets.find-first/*/*?value 81 | class:visible hide 82 | 83 | /* 84 | * Checking if there's a folder toolbar open, and if so, deleting it. 85 | */ 86 | if 87 | fetch:x:/0/0?value 88 | widget-exists:hyper-ide-active-folder-toolbar 89 | delete-widget:hyper-ide-active-folder-toolbar 90 | 91 | /* 92 | * Returning early. 93 | */ 94 | return:bool:true 95 | 96 | 97 | 98 | 99 | 100 | /* 101 | * Retrieving editor wrapper widget for requested editor. 102 | */ 103 | p5.web.widgets.find-first:hyper-ide-editor-tab-editors 104 | .editor:x:/../*/editor?value 105 | 106 | 107 | 108 | 109 | 110 | /* 111 | * Verifying specified [editor] exists. 112 | */ 113 | if:x:/@p5.web.widgets.find-first/*/*?value 114 | 115 | /* 116 | * Editor passed in as [editor] was found. 117 | * 118 | * For simplicity reasons, we simply select tree view item associated 119 | * with editor, since this will map up everything automatically for us. 120 | */ 121 | add:x:/+/*/items 122 | src:x:/../*/editor?value 123 | micro.widgets.tree.select-items:hyper-ide-folder-tree-browser 124 | items 125 | 126 | /* 127 | * Raising our folder changed event. 128 | */ 129 | hyper-ide.file-explorer.item-changed:x:/../*/editor?value 130 | 131 | /* 132 | * Returning success to caller. 133 | */ 134 | return:bool:true 135 | 136 | else 137 | 138 | /* 139 | * No such editor. 140 | */ 141 | micro.windows.info:No such open editor 142 | class:micro-windows-info warning 143 | 144 | /* 145 | * Returning failure to caller. 146 | */ 147 | return:bool:false 148 | -------------------------------------------------------------------------------- /helpers/toolbars/folder-editor/02-new-folder.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Create new folder toolbar button. 3 | */ 4 | button 5 | innerValue:@"" 6 | title:Create a new folder 7 | onclick 8 | 9 | /* 10 | * Creating new folder, asking user for name for his new folder. 11 | */ 12 | create-widgets 13 | micro.widgets.modal:hyper-ide-create-new-folder-modal 14 | widgets 15 | h3 16 | innerValue:Name of new folder 17 | micro.widgets.wizard-form:hyper-ide-create-new-folder-form 18 | text:hyper-ide-new-folder-name 19 | info:Name 20 | .data-field:name 21 | placeholder:Name for your new folder ... 22 | onkeydown:@"if (event.keyCode == 13) {p5.$('hyper-ide-new-folder-btn').raise('onclick');return false;} else if (event.keyCode == 27) {p5.$('hyper-ide-new-folder-cancel').raise('onclick');return false;}" 23 | oninit 24 | 25 | /* 26 | * Setting initial focus to "Yes" button. 27 | */ 28 | micro.page.set-focus:x:/../*/_event?value 29 | 30 | div 31 | class:right 32 | widgets 33 | div 34 | class:strip 35 | widgets 36 | button:hyper-ide-new-folder-btn 37 | innerValue:OK 38 | onclick 39 | 40 | /* 41 | * Serializing form data and sanity checking name of new folder. 42 | * 43 | * Notice, we only accept a-z, 0-9, _, . and - characters, and no capital letters. 44 | * 45 | * We don't accept capital letters to avoid windows/xNix confusion in paths. 46 | */ 47 | micro.form.serialize:hyper-ide-create-new-folder-form 48 | match:x:/@micro.form.serialize/*/name?value 49 | src:regex:/^[-_a-z0-9\ ]+$/i 50 | if:x:/@match/*?count 51 | =:int:0 52 | or:x:/@match/0?name 53 | =: 54 | 55 | /* 56 | * Not a legal name for a folder. 57 | */ 58 | micro.css.add:hyper-ide-new-folder-name 59 | class:error 60 | micro.windows.info:Only use a-z, _, ., - and 0-9 in your name 61 | class:micro-windows-info warning 62 | micro.page.set-focus:hyper-ide-new-folder-name 63 | return 64 | 65 | /* 66 | * Creating our new folder as a sub folder of currently selected folder. 67 | */ 68 | get-widget-property:hyper-ide-active-folder-toolbar 69 | .folder 70 | create-folder:{0}{1}/ 71 | :x:/@get-widget-property/*/*?value 72 | :x:/@micro.form.serialize/*/name?value 73 | 74 | /* 75 | * Making sure we refresh our tree view. 76 | */ 77 | hyper-ide.file-explorer.refresh-active-folder 78 | 79 | /* 80 | * Making sure we select our newly created folder 81 | */ 82 | hyper-ide.file-explorer.set-active-item:{0}{1}/ 83 | :x:/@get-widget-property/*/*?value 84 | :x:/@micro.form.serialize/*/name?value 85 | 86 | /* 87 | * Deleting modal widget, and giving user some feedback. 88 | */ 89 | delete-widget:hyper-ide-create-new-folder-modal 90 | 91 | button:hyper-ide-new-folder-cancel 92 | innerValue:Cancel 93 | onclick 94 | 95 | /* 96 | * Simply deleting modal widget 97 | */ 98 | delete-widget:hyper-ide-create-new-folder-modal 99 | -------------------------------------------------------------------------------- /helpers/toolbars/folder-editor/01-new-file.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Create new file toolbar button. 3 | */ 4 | button 5 | innerValue:@"" 6 | title:Create a new file 7 | onclick 8 | 9 | /* 10 | * Creating new file, asking user for name for his new file. 11 | */ 12 | create-widgets 13 | micro.widgets.modal:hyper-ide-create-new-file-modal 14 | widgets 15 | h3 16 | innerValue:Name of new file 17 | micro.widgets.wizard-form:hyper-ide-create-new-file-form 18 | text:hyper-ide-new-file-name 19 | info:Name 20 | .data-field:name 21 | placeholder:Name for your new file ... 22 | onkeydown:@"if (event.keyCode == 13) {p5.$('hyper-ide-new-file-btn').raise('onclick');return false;} else if (event.keyCode == 27) {p5.$('hyper-ide-new-file-cancel').raise('onclick');return false;}" 23 | oninit 24 | 25 | /* 26 | * Setting initial focus to "Yes" button. 27 | */ 28 | micro.page.set-focus:x:/../*/_event?value 29 | 30 | div 31 | class:right 32 | widgets 33 | div 34 | class:strip 35 | widgets 36 | button:hyper-ide-new-file-btn 37 | innerValue:OK 38 | onclick 39 | 40 | /* 41 | * Serializing form data and sanity checking name of new file. 42 | * 43 | * Notice, we only accept a-z, 0-9, ., _ and - characters. 44 | */ 45 | micro.form.serialize:hyper-ide-create-new-file-form 46 | match:x:/@micro.form.serialize/*/name?value 47 | src:regex:/^[-_a-z0-9 ]+\.{1}[-_a-z0-9\.]+$/i 48 | if:x:/@match/*?count 49 | =:int:0 50 | or:x:/@match/0?name 51 | =: 52 | 53 | /* 54 | * Not a legal name for a file. 55 | */ 56 | micro.css.add:hyper-ide-new-file-name 57 | class:error 58 | micro.windows.info:Only use a-z, ., _, - and 0-9 in your name 59 | class:micro-windows-info warning 60 | micro.page.set-focus:hyper-ide-new-file-name 61 | return 62 | 63 | /* 64 | * Creating our new file as a sub file of currently selected folder. 65 | */ 66 | get-widget-property:hyper-ide-active-folder-toolbar 67 | .folder 68 | save-file:{0}{1} 69 | :x:/@get-widget-property/*/*?value 70 | :x:/@micro.form.serialize/*/name?value 71 | src: 72 | 73 | /* 74 | * Making sure we refresh our tree view. 75 | */ 76 | hyper-ide.file-explorer.refresh-active-folder 77 | 78 | /* 79 | * Making sure we select our newly created file, and open 80 | * it for editing. 81 | * 82 | * Notice, this is done by selecting the same tree node twice. 83 | */ 84 | hyper-ide.file-explorer.set-active-item:{0}{1} 85 | :x:/@get-widget-property/*/*?value 86 | :x:/@micro.form.serialize/*/name?value 87 | 88 | /* 89 | * Deleting modal widget, and giving user some feedback. 90 | */ 91 | delete-widget:hyper-ide-create-new-file-modal 92 | 93 | button:hyper-ide-new-file-cancel 94 | innerValue:Cancel 95 | onclick 96 | 97 | /* 98 | * Simply deleting modal widget 99 | */ 100 | delete-widget:hyper-ide-create-new-file-modal 101 | -------------------------------------------------------------------------------- /helpers/activate-editor.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Activating editor for specified **[file]** in Hyper IDE, assuming 3 | * it's already open in a non-active editor. This file is evaluated 4 | * when some (already open) editor is for some reasons being explicitly 5 | * activated. 6 | */ 7 | 8 | 9 | 10 | 11 | 12 | /* 13 | * Sanity checking arguments. 14 | */ 15 | micro.lambda.contract.min:x:/.. 16 | file:string 17 | 18 | 19 | 20 | 21 | 22 | /* 23 | * Verifying that the editor caller is trying to activate is not the editor that 24 | * already is activated. 25 | */ 26 | p5.web.widgets.find-first:hyper-ide-editor-tab-buttons 27 | .activate:x:/../*/file?value 28 | get-widget-property:x:/@p5.web.widgets.find-first/*/*?value 29 | class 30 | if:x:/@get-widget-property/*/*?value 31 | ~:toggled 32 | 33 | /* 34 | * Editor is already active, but there might be another active file explorer 35 | * item, at which point we still need to make the editor's toolbar visible. 36 | */ 37 | if 38 | hyper-ide.active-editor.get-filepath 39 | != 40 | hyper-ide.file-explorer.get-active-item 41 | 42 | /* 43 | * Although editor is already active, we still need to make its toolbar 44 | * visible. 45 | */ 46 | p5.web.widgets.find-first-like:hyper-ide-toolbar-wrapper 47 | .toolbar:x:/../*/file?value 48 | micro.css.add:x:/@p5.web.widgets.find-first-like/*/*?value 49 | class:visible 50 | micro.css.delete:x:/@p5.web.widgets.find-first-like/*/*?value 51 | class:hide 52 | 53 | /* 54 | * Returning success to caller. 55 | */ 56 | return:bool:true 57 | 58 | /* 59 | * Editor is already activated, returning early, signaling "failure" to caller. 60 | */ 61 | return:bool:false 62 | 63 | 64 | 65 | 66 | 67 | /* 68 | * Making sure correct activate button becomes toggled. 69 | * This is done by making sure we remove the "toggled" class from all 70 | * activate buttons, except the one caller is trying to activate. 71 | * 72 | * First finding the activate button that is currently toggled, and deleting 73 | * its "toggled" class. 74 | */ 75 | p5.web.widgets.find-first-like:hyper-ide-editor-tab-buttons 76 | .activate 77 | class:toggled 78 | 79 | 80 | 81 | 82 | 83 | /* 84 | * Deleting the "toggled" class for the currently activated activate button. 85 | */ 86 | micro.css.delete:x:/@p5.web.widgets.find-first-like/*/*?value 87 | class:toggled 88 | 89 | 90 | 91 | 92 | 93 | /* 94 | * Then adding the "toggled" class to it to the activate button for editor 95 | * caller wants to activate. 96 | */ 97 | micro.css.add:x:/../*/p5.web.widgets.find-first/[0,1]/*/*?value 98 | class:toggled 99 | 100 | 101 | 102 | 103 | 104 | /* 105 | * Then making sure the correct editor becomes visible. 106 | * 107 | * First we find the currently visible editor, and make it invisible. 108 | */ 109 | p5.web.widgets.find-first-like:hyper-ide-editor-tab-editors 110 | .editor 111 | class:visible 112 | micro.css.toggle:x:/@p5.web.widgets.find-first-like/*/*?value 113 | class:visible hide 114 | 115 | 116 | 117 | 118 | 119 | /* 120 | * Then finding the editor caller wants to activate, and setting it to visible. 121 | */ 122 | p5.web.widgets.find-first:hyper-ide-editor-tab-editors 123 | .editor:x:/../*/file?value 124 | micro.css.toggle:x:/@p5.web.widgets.find-first/*/*?value 125 | class:hide visible 126 | 127 | 128 | 129 | 130 | 131 | /* 132 | * Then making sure we disable all non-active editors. 133 | * 134 | * This is done to avoid having disabled editors send their code on each Ajax request, 135 | * reducing the bandwidth consumption in general. 136 | */ 137 | p5.web.widgets.find-first:x:/@p5.web.widgets.find-first-like/*/*?value 138 | element:textarea 139 | set-widget-property:x:/@p5.web.widgets.find-first/*/*?value 140 | disabled 141 | 142 | 143 | 144 | 145 | 146 | /* 147 | * Then making sure we enable the currently activated editor. 148 | */ 149 | p5.web.widgets.find-first:x:/@p5.web.widgets.find-first/@p5.web.widgets.find-first/*/*?value 150 | element:textarea 151 | delete-widget-property:x:/@p5.web.widgets.find-first/*/*?value 152 | disabled 153 | 154 | 155 | 156 | 157 | 158 | /* 159 | * Then making sure correct toolbar becomes visible. 160 | * 161 | * First finding toolbar we should hide. 162 | */ 163 | p5.web.widgets.find-first-like:hyper-ide-toolbar-wrapper 164 | .toolbar 165 | class:visible 166 | micro.css.toggle:x:/@p5.web.widgets.find-first-like/*/*?value 167 | class:hide visible 168 | 169 | 170 | 171 | 172 | 173 | /* 174 | * Then finding the toolbar we should show and displaying it. 175 | */ 176 | p5.web.widgets.find-first:hyper-ide-toolbar-wrapper 177 | .toolbar:x:/../*/file?value 178 | micro.css.toggle:x:/@p5.web.widgets.find-first/*/*?value 179 | class:hide visible 180 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.plugins.shell.execute.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.plugins.shell.execute]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event creates our _"execute shell command plugin"_ button. This button 7 | * is only visible if the active object in your file explorer is a shell file, 8 | * ending with the extension of _".sh"_. 9 | * 10 | * When clicked, this button will execute your shell file, from your current 11 | * active editor. 12 | */ 13 | create-event:hyper-ide.plugins.shell.execute 14 | return 15 | button 16 | innerValue:@"" 17 | title:Execute script 18 | onclick 19 | 20 | /* 21 | * Retrieves editor's content. 22 | */ 23 | hyper-ide.active-editor.get-code 24 | 25 | /* 26 | * Creates a temporary file, containing the current code from the active 27 | * editor, which is the file we actually execute. 28 | * This is done since the file might not necessarily be saved, and we 29 | * assume user wants to execute the code from his editor, and not 30 | * necessarily the code from his physical file. 31 | * 32 | * However, first checking platform, since we might need to convert 33 | * from CR/LF to only LF, in case we're on MacOSX 34 | */ 35 | p5.system.platform 36 | if:x:/@p5.system.platform?value 37 | =:Unix 38 | or:x:/@p5.system.platform?value 39 | =:MacOSX 40 | 41 | /* 42 | * Replacing CR/LF before we save file. 43 | */ 44 | p5.system.platform.normalize-string:x:/@hyper-ide.active-editor.get-code?value 45 | save-file:~/temp/temp-bash.sh 46 | src:x:/@p5.system.platform.normalize-string?value 47 | 48 | else 49 | 50 | /* 51 | * Saving file with CR/LF as new line characters. 52 | */ 53 | save-file:~/temp/temp-bash.sh 54 | src:x:/@hyper-ide.active-editor.get-code?value 55 | 56 | /* 57 | * Then making sure we wrap our execution inside of a try/catch block, 58 | * such that we can be certain of that our temporary file is always deleted, 59 | * since it might contain passwords and such, while we track the result 60 | * from our execution. 61 | */ 62 | .result 63 | .class 64 | try 65 | 66 | /* 67 | * Figuring out "working folder", which is the folder where the original 68 | * file can be found. 69 | */ 70 | hyper-ide.active-editor.get-filepath 71 | split:x:/@hyper-ide.active-editor.get-filepath?value 72 | =:/ 73 | set:x:/@split/0/- 74 | join:x:/@split/*?name 75 | sep:/ 76 | trim-left:x:/@join?value 77 | chars:/ 78 | 79 | /* 80 | * Executing temp file, with working folder being folder where original 81 | * file is physically located. 82 | */ 83 | p5.system.platform.execute-file:~/temp/temp-bash.sh 84 | working-folder:/{0} 85 | :x:/@trim-left?value 86 | 87 | /* 88 | * Setting result to result of invocation above. 89 | */ 90 | set:x:/@.result?value 91 | src:x:/@p5.system.platform.execute-file/*?value 92 | set:x:/@.class?value 93 | src:success 94 | 95 | catch 96 | 97 | /* 98 | * Setting result to exception message. 99 | */ 100 | set:x:/@.result?value 101 | src:x:/@message?value 102 | set:x:/@.class?value 103 | src:warning 104 | 105 | finally 106 | 107 | /* 108 | * Deleting temp file. 109 | */ 110 | delete-file:~/temp/temp-bash.sh 111 | 112 | /* 113 | * Opens a modal window, displaying the results of our execution, making 114 | * sure we HTML encode any result. 115 | */ 116 | p5.html.html-encode:x:/@.result?value 117 | eval-x:x:/+/*/*/*/div/*/innerHtml|/+/**/pre/*/class 118 | create-widgets 119 | micro.widgets.modal:hyper-ide-execute-output 120 | widgets 121 | h3 122 | innerValue:Result 123 | pre 124 | innerValue:x:/@p5.html.html-encode?value 125 | style:"font-size:.7rem;" 126 | class:air-top {0} 127 | :x:/@.class?value 128 | div 129 | class:right 130 | widgets 131 | div 132 | class:strip 133 | widgets 134 | button 135 | innerValue:Close 136 | oninit 137 | 138 | /* 139 | * Making sure we set initial focus to "Close" button. 140 | */ 141 | micro.page.set-focus:x:/../*/_event?value 142 | 143 | onclick 144 | 145 | /* 146 | * Deleting modal widget. 147 | */ 148 | delete-widget:hyper-ide-execute-output 149 | -------------------------------------------------------------------------------- /helpers/app-templates/hello-world.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Template for a new _"Hello World module"_. 3 | * 4 | * This file creates a simple _"Hello World"_ type of application. 5 | * The file requires a __[name]__ argument as the name of new module to create. 6 | * 7 | * This file is used by the __[hyper-ide.folder-plugin.create-module]__ 8 | * plugin when the user creates a new module by following a wizard. 9 | */ 10 | 11 | 12 | 13 | 14 | 15 | /* 16 | * Sanity checking arguments. 17 | */ 18 | micro.lambda.contract.min:x:/.. 19 | name:string 20 | 21 | 22 | 23 | 24 | 25 | /* 26 | * Creates our new module. 27 | * 28 | * First making sure our main module folder exists. 29 | */ 30 | create-folder:/modules/{0}/ 31 | :x:/../*/name?value 32 | 33 | 34 | 35 | 36 | 37 | /* 38 | * Then creating our module's files, first the "launch.hl" file. 39 | */ 40 | save-file:/modules/{0}/launch.hl 41 | :x:/../*/name?value 42 | src:@" 43 | /* 44 | * Includes CSS for our module. 45 | */ 46 | micro.css.include 47 | 48 | 49 | /* 50 | * Creating main wire frame for module. 51 | */ 52 | create-widget 53 | class:container 54 | widgets 55 | div 56 | class:row 57 | widgets 58 | div 59 | class:col-100 60 | widgets 61 | div 62 | class:right strip toolbar 63 | widgets 64 | button 65 | innerValue:@"""" 66 | onclick 67 | 68 | /* 69 | * Redirecting user to server's root URL. 70 | */ 71 | p5.web.get-root-location 72 | p5.web.set-location:x:/-?value 73 | 74 | div 75 | class:col-100 76 | widgets 77 | div 78 | class:air-inner shaded rounded bg 79 | widgets 80 | h3 81 | innerValue:Hello World 82 | p 83 | innerValue:@""Here is a template for your convenience, creating a default startup module wire frame for you. 84 | It contains 4 files."" 85 | ul 86 | widgets 87 | li 88 | innerValue:'launch.hl' - This is the file that is evaluated when your module is launched 89 | li 90 | innerValue:'desktop.hl' - This creates a 'desktop icon' for your module 91 | li 92 | innerValue:'startup.hl' - Evaluated when the server is started 93 | li 94 | innerValue:'install.hl' - Evaluated when your module is installed 95 | li 96 | innerValue:'uninstall.hl' - Evaluated when your module is uninstalled 97 | button:foo-button 98 | innerValue:Click me! 99 | onclick 100 | set-widget-property:foo-button 101 | innerValue:Hello World 102 | " 103 | 104 | 105 | 106 | 107 | 108 | /* 109 | * Then creating our "desktop.hl" file. 110 | */ 111 | save-file:/modules/{0}/desktop.hl 112 | :x:/../*/name?value 113 | src:@" 114 | /* 115 | * Desktop widget. 116 | * 117 | * This becomes your module's 'desktop icon'. 118 | */ 119 | container 120 | element:a 121 | class:jumbo-button 122 | title:This module says Hello World! 123 | widgets 124 | span 125 | innerValue:Hello 126 | literal 127 | element:span 128 | class:icon-happy 129 | " 130 | 131 | 132 | 133 | 134 | 135 | /* 136 | * Then creating our "startup.hl" file. 137 | */ 138 | to-upper:x:/../*/name?value 139 | save-file:/modules/{0}/startup.hl 140 | :x:/../*/name?value 141 | src:@" 142 | /* 143 | * Provide whatever startup logic your module requires here, if any. 144 | * 145 | * For instance, create Active Events necessary to wire up your module. 146 | * Below is an example of creating a 'path' event for instance, which unrolls 147 | * the path declaration of @YOUR-APP-NAME to your module's main folder. 148 | */ 149 | split:x:/..?name 150 | =:/ 151 | set:x:/@split/0/- 152 | join:x:/@split/*?name 153 | sep:/ 154 | eval-x:x:/+/* 155 | create-event:p5.io.unroll-path.@{0} 156 | return:/{{0}} 157 | :x:/@join?value 158 | " 159 | :x:/@to-upper?value 160 | 161 | 162 | 163 | 164 | 165 | /* 166 | * Then creating our "uninstall.hl" file. 167 | */ 168 | save-file:/modules/{0}/install.hl 169 | :x:/../*/name?value 170 | src:@" 171 | /* 172 | * Provide whatever installation logic your module requires here, if any. 173 | * 174 | * Common tasks for this file, is to create your database (if any), etc. 175 | * This file is empty, since this particular example currently doesn't have 176 | * any installation logic. 177 | */ 178 | .foo 179 | " 180 | 181 | 182 | 183 | 184 | 185 | /* 186 | * Then creating our "uninstall.hl" file. 187 | */ 188 | save-file:/modules/{0}/uninstall.hl 189 | :x:/../*/name?value 190 | src:@" 191 | /* 192 | * Provide whatever uninstall logic your module requires here, if any. 193 | * 194 | * Common tasks for this file, is to delete all Active Events created by 195 | * your module, such as the following example illustrates. 196 | */ 197 | delete-event:p5.io.unroll-path.@{0} 198 | " 199 | :x:/@to-upper?value 200 | -------------------------------------------------------------------------------- /helpers/file-explorer/file-explorer-widget.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file wraps Hyper IDE's _"file explorer"_, that allows the user to browse 3 | * his or her folders/files on his server, and select files for editing its content, 4 | * and/or manipulate his or hers folders somehow. 5 | * 6 | * The file explorer for Hyper IDE is implemented using the __[micro.widgets.tree]__ 7 | * extension widget. 8 | */ 9 | micro.widgets.tree:hyper-ide-folder-tree-browser 10 | class:micro-widgets-tree hyper-ide-tree-view 11 | items 12 | /:/ 13 | 14 | oninit 15 | 16 | /* 17 | * Expanding root item. 18 | */ 19 | micro.widgets.tree.toggle-items:hyper-ide-folder-tree-browser 20 | items 21 | / 22 | 23 | /* 24 | * Callback invoked when TreeView wants more items. 25 | */ 26 | .onexpand 27 | 28 | /* 29 | * Making sure we wrap our stuff inside of a try/catch block, 30 | * since this will prevent the default exception handler from 31 | * being evaluated, in case user tries to access file objects 32 | * he does not have permission to access. 33 | */ 34 | try 35 | 36 | /* 37 | * We need to track whether or not an exception occurs, from 38 | * our [.onexpand], and into our [.onselect]. We do this by setting 39 | * a "signal" viewstate value if an exception occurs. 40 | * 41 | * However, we need to default its value to empty, in case 42 | * no exception occurs. 43 | */ 44 | p5.web.viewstate.set:hyper-ide.no-select 45 | 46 | /* 47 | * Checking if this is a request for a folder. 48 | */ 49 | if 50 | ends-with:x:/../*/_item-id?value 51 | src:/ 52 | 53 | /* 54 | * Invoking file responsible for actually retrieving files 55 | * and folders structure, and returning items to caller. 56 | */ 57 | eval-x:x:/+/* 58 | micro.evaluate.file:@IDE/helpers/file-explorer/get-file-explorer-objects.hl 59 | folder:x:/../*/_item-id?value 60 | add:x:/..if/*/return/*/items 61 | src:x:/@micro.evaluate.file/* 62 | return 63 | items 64 | 65 | catch 66 | 67 | /* 68 | * Giving user some feedback, and making sure we delete any 69 | * additional toolbars that was created. 70 | */ 71 | micro.windows.info:x:/@message?value 72 | class:micro-windows-info warning 73 | if 74 | fetch:x:/0/0?value 75 | widget-exists:hyper-ide-active-folder-toolbar 76 | delete-widget:hyper-ide-active-folder-toolbar 77 | 78 | /* 79 | * Making sure we don't try to select item in any ways 80 | * further down in file. 81 | */ 82 | p5.web.viewstate.set:hyper-ide.no-select 83 | src:bool:true 84 | 85 | /* 86 | * Callback invoked when an item ise selected. 87 | */ 88 | .onselect 89 | 90 | /* 91 | * Checking if we had an exception while invoking our [.onexpand], 92 | * at which point we don't evaluate this lambda. 93 | */ 94 | p5.web.viewstate.get:hyper-ide.no-select 95 | if:x:/-/*?value 96 | 97 | /* 98 | * Re-setting exception signal and returning early. 99 | */ 100 | p5.web.viewstate.set:hyper-ide.no-select 101 | return 102 | 103 | /* 104 | * Making sure we wrap our stuff inside of a try/catch block, 105 | * since this will prevent the default exception handler from 106 | * being evaluated, in case user tries to access file objects 107 | * he does not have permission to access. 108 | */ 109 | try 110 | 111 | /* 112 | * Checking if this is a de-select invocation. 113 | */ 114 | if:x:/../*/items/*?count 115 | =:int:0 116 | 117 | /* 118 | * De-select invocation. 119 | */ 120 | return 121 | 122 | /* 123 | * Checking if this is a request for a folder or a file. 124 | */ 125 | if 126 | ends-with:x:/../*/items/0?name 127 | src:/ 128 | 129 | /* 130 | * Request for folder. 131 | * 132 | * Invoking file responsible for selecting the folder. 133 | */ 134 | eval-x:x:/+/* 135 | micro.evaluate.file:@IDE/helpers/file-explorer/select-folder.hl 136 | folder:x:/../*/items/0?name 137 | 138 | else 139 | 140 | /* 141 | * Request for file. 142 | * 143 | * Invoking file responsible for selecting the file. 144 | */ 145 | eval-x:x:/+/* 146 | micro.evaluate.file:@IDE/helpers/file-explorer/select-file.hl 147 | file:x:/../*/items/0?name 148 | 149 | /* 150 | * Raising the file explorer "active event changed" event. 151 | */ 152 | hyper-ide.file-explorer.item-changed:x:/../*/items/0?name 153 | 154 | catch 155 | 156 | /* 157 | * Giving user some feedback, and making sure we delete any 158 | * additional toolbars that was created. 159 | */ 160 | micro.windows.info:x:/@message?value 161 | class:micro-windows-info warning 162 | if 163 | fetch:x:/0/0?value 164 | widget-exists:hyper-ide-active-folder-toolbar 165 | delete-widget:hyper-ide-active-folder-toolbar 166 | 167 | /* 168 | * Returning false to let caller know we don't want to invoke 169 | * our [.onexpand] lambda callback. 170 | */ 171 | return:bool:false 172 | -------------------------------------------------------------------------------- /media/main.css: -------------------------------------------------------------------------------- 1 | .hyper-ide-container { 2 | padding-top: 0; 3 | } 4 | 5 | .hyper-ide-container .micro-codemirror-wrapper { 6 | margin-bottom: 0; 7 | } 8 | 9 | /* All Hyper IDE toolbars */ 10 | .hyper-ide-toolbar { 11 | margin-bottom: 0; 12 | margin-top: .5rem; 13 | } 14 | 15 | /* Bookmark textbox */ 16 | .hyper-ide-bookmark-textbox { 17 | position: absolute; 18 | top: 1rem; 19 | right: 1rem; 20 | max-width: 100%; 21 | width: 500px !important; 22 | box-shadow: 0 0 15px rgba(128,128,0,.7) !important; 23 | } 24 | 25 | /* Main content */ 26 | .hyper-ide-content { 27 | height: auto; 28 | } 29 | @media screen and (min-width:800px) { 30 | .hyper-ide-content { 31 | height: calc(100vh - 2rem - var(--form-el-pad) * 2 - .5rem); 32 | margin-bottom: -.5rem; 33 | } 34 | .micro-widgets-modal-content .hyper-ide-content { 35 | height: calc(100vh - 7rem - var(--form-el-pad) * 2 - .5rem); 36 | } 37 | } 38 | .micro-widgets-modal-content .hyper-ide-content { 39 | margin-bottom: 1rem; 40 | } 41 | 42 | /* If user wants to use "page scroll" instead of editor/treeview scroll, then this class will apply */ 43 | .hyper-ide-page-scroll { 44 | padding-bottom: 0; 45 | } 46 | .hyper-ide-page-scroll .hyper-ide-content { 47 | height: auto; 48 | min-height: calc(100vh - 2rem - var(--form-el-pad) * 2 - .5rem); 49 | margin-bottom: .5rem; 50 | overflow: visible; 51 | } 52 | 53 | /* TreeView wrapper for browsing files (column wrapper) */ 54 | .hyper-ide-solution-explorer-col { 55 | min-height: calc(100% - var(--form-el-pad) * 2); 56 | margin-bottom: 0; 57 | margin-top: .5rem; 58 | } 59 | 60 | /* TreeView wrapper for browsing files (inside of column) */ 61 | .hyper-ide-solution-explorer { 62 | height: 100%; 63 | margin-bottom: 0; 64 | overflow: auto; 65 | } 66 | 67 | /* Actual TreeView (file explorer) CSS class */ 68 | .hyper-ide-tree-view { 69 | overflow: scroll; 70 | height: 100%; 71 | margin-right: -1rem; 72 | padding-right: 1rem; 73 | min-width: fit-content; 74 | padding-bottom: 2rem; 75 | margin-bottom: 0; 76 | } 77 | 78 | /* Wrapper column around editors (and splash screen) */ 79 | .hyper-ide-editor-col { 80 | min-height: calc(100% - var(--form-el-pad) * 2); 81 | margin-top: .5rem; 82 | } 83 | 84 | @media screen and (min-width:800px) { 85 | .hyper-ide-editor-col { 86 | margin-bottom: 0; 87 | } 88 | } 89 | 90 | /* Hyper IDE splash screen, which you see when you initially start Hyper IDE */ 91 | .hyper-ide-splash { 92 | height: auto; 93 | min-height: 100%; 94 | position: relative; 95 | margin-bottom: 0; 96 | } 97 | 98 | /* "Tab control" wrapping editor (both tab buttons, and editor surface) */ 99 | .hyper-ide-editor-tab { 100 | height: 100%; 101 | } 102 | .hyper-ide-page-scroll .hyper-ide-editor-tab { 103 | overflow: hidden; 104 | } 105 | 106 | /* "Tab control buttons" wrapper */ 107 | .hyper-ide-editor-tab-buttons { 108 | overflow: auto; 109 | white-space: nowrap; 110 | } 111 | 112 | /* "Tab control buttons", inside of editor "tab control" */ 113 | .hyper-ide-editor-tab-buttons > span { 114 | border-bottom-left-radius: 0; 115 | border-bottom-right-radius: 0; 116 | border: none; 117 | width: 10rem; 118 | text-align: left; 119 | overflow: hidden; 120 | text-overflow: ellipsis; 121 | white-space: nowrap; 122 | position: relative; 123 | font-style: italic; 124 | margin-left: .2rem; 125 | margin-top: 1px; 126 | margin-bottom: -1px; 127 | font-size: .7rem; 128 | padding-right: 2rem; 129 | cursor: pointer; 130 | background-image: var(--button-toggled-bg); 131 | } 132 | .hyper-ide-editor-tab-buttons > span:first-child { 133 | margin-left: var(--border-radius); 134 | } 135 | 136 | .hyper-ide-editor-tab-buttons > .toggled { 137 | z-index: 1; 138 | font-weight: bold; 139 | font-style: normal; 140 | background-image: var(--button-bg); 141 | } 142 | 143 | .hyper-ide-editor-tab-buttons > span > span.hyper-ide-close { 144 | position: absolute; 145 | font-size: .5rem; 146 | top: calc(var(--border-radius) / 2); 147 | right: calc(var(--border-radius) / 2); 148 | padding: .25rem; 149 | border-radius: .25rem; 150 | min-width: unset; 151 | width: auto; 152 | height: auto; 153 | } 154 | 155 | /* "Tab control" content wrapper */ 156 | .hyper-ide-editor-tab-content { 157 | height: calc(100% - 1.7rem - 1px); 158 | margin-bottom: 0; 159 | } 160 | 161 | /* Making sure we modify main CodeMirror (Micro) wrapper class */ 162 | .micro-codemirror-wrapper { 163 | height: 100%; 164 | } 165 | 166 | /* Wraps CodeMirror instance(s) */ 167 | .hyper-ide-codemirror-wrapper { 168 | height: calc(100vh - 5.5rem); 169 | box-sizing: content-box; 170 | } 171 | .hyper-ide-page-scroll .hyper-ide-codemirror-wrapper { 172 | height: auto; 173 | min-height: calc(100vh - 5.5rem); 174 | } 175 | 176 | /* CodeMirror instance, inside of editors */ 177 | .hyper-ide-codemirror-wrapper .CodeMirror { 178 | height: 100% !important; 179 | min-height: 100%; 180 | } 181 | 182 | /* Our animation for our UFO on our splash screen */ 183 | @keyframes hyper-ide-ufo { 184 | 0% { 185 | transform: rotate(-90deg) scale(0.1); 186 | margin-top: -500px; 187 | } 188 | 189 | 100% { 190 | transform: rotate(0deg) scale(1); 191 | margin-top: 0; 192 | } 193 | } 194 | /* UFO styles (image on splash screen) */ 195 | .hyper-ide-ufo { 196 | margin-left: auto; 197 | margin-right: auto; 198 | display: block; 199 | max-width: 50%; 200 | animation-name: hyper-ide-ufo; 201 | animation-duration: .5s; 202 | animation-fill-mode: forwards; 203 | margin-bottom: 2rem; 204 | } 205 | 206 | .hyper-ide-copyright { 207 | position: absolute; 208 | bottom: 0; 209 | right: 1rem; 210 | margin-bottom: .5rem; 211 | font-style: italic; 212 | font-size: .7rem; 213 | } 214 | -------------------------------------------------------------------------------- /help-files/Hyper IDE/01 - Introduction.md: -------------------------------------------------------------------------------- 1 | ## Introduction to Hyper IDE 2 | 3 | Hyper IDE is a web based integrated development environment. Even though it's main purpose is to allow for 4 | development in primarily Hyperlambda, HTML, CSS and JavaScript - It supports more than 100 programming 5 | languages, to a varying degree. It also works on clients such as your phone and tablet, althought it's 6 | probably best used in combination with a normal computer. Hyper IDE is highly modularised, and easily 7 | extendible, and also allows you to easily customise it. Hyper IDE is entirely built in 8 | Hyperlambda, which probably serves as a testimonial to Hyperlambda's _"powers"_. Hyper IDE is using 9 | CodeMirror as its front end code editor. Hyper IDE also doubles as a file manager. 10 | 11 | ### The file explorer 12 | 13 | To the left in Hyper IDE, you can find a _"tree view widget"_. We will refer to this widget as your 14 | _"file explorer"_. It displays all the files on your server, and allows you to select and open files 15 | for editing, in addition to modify and edit your folders. The first time you click a folder in the tree view, 16 | it will automatically expand the folder, and display its sub-folders and files. If you choose to explicitly 17 | close the folder later, by clicking the folder icon, you will have to click the folder icon again to 18 | expand it. 19 | 20 | As you select a file in the file explorer, Hyper IDE will find the correct CodeMirror mode, according to the file 21 | extension of your file. The mapping between file extensions and CodeMirror modes can be found 22 | in your `/hyper-ide/configuration/extension2cm-instance.hl` file, and you can edit this file to add support for 23 | additional file extensions, and/or CodeMirror modes. 24 | 25 | Unless you have explicitly disabled the _"bookmark"_ plugin, you can also retrieve the URL to the currently 26 | selected item from your file explorer, which might be a folder, or a file, which allows you to bookmark files 27 | and folders, or send them to colleagues or friends as URLs. 28 | 29 | As you browse your folders and files on your server, the toolbar changes according to which file or folder 30 | you have selected, providing context sensitive toolbar items. If you choose the _"/micro/media/skins/"_ folder 31 | for instance, you'll have a _"Create new skin wizard"_ toolbar item. 32 | 33 | ### The Toolbar 34 | 35 | At the top of Hyper IDE, you can find a toolbar. This toolbar is _"context sensitive"_, and will change 36 | according to what type of object you have selected. If you select a folder, you will be given the option to 37 | create a new file, and/or a sub-folder. If you select a file, you will not be given these options. Hence, 38 | to create a new file or folder, you must first select the folder where you want to place your file. 39 | Try to select back and forth between a file and a folder to see how it changes. Both files and folders 40 | can be renamed. If you hover your mouse over a toolbar button, you will get some information about what 41 | that particular button does. 42 | 43 | **Notice**, depending upon what plugins you have (turned on) in your installation, you might 44 | have additional buttons, such as the _"Create new template module"_ plugin, which allows you to create 45 | new apps, by following a _"wizard"_. This button will only be visible when you have selected the `/modules/` 46 | folder. Some plugins are _"context sensitive"_, and only available for 47 | specific folders, and/or specific file extensions. You can also easily extend this toolbar, and create 48 | your own plugins. 49 | 50 | ### Keyboard shortcuts 51 | 52 | Hyper IDE has many keyboard shortcuts. Most of these are created as CodeMirror shortcuts, which implies that 53 | some sort of CodeMirror editor must be active, and have focus, for the keyboard shortcut to work. 54 | Below is a list of these keyboard shortcuts. 55 | 56 | * __Alt+S__ - Saves the active document 57 | * __Alt+W__ - Activates the next open document 58 | * __Alt+Q__ - Activates the previous open document 59 | * __Alt+X__ - Closes the active document 60 | * __Alt+M__ - Maximize the active editor 61 | * __Cx+Space__ - Displays the AutoCompleter 62 | * __Tab__ - Indents selected code 2 more spaces 63 | * __Shift+Tab__ - De-indents selected code 2 spaces 64 | * __Alt+F__ - Search, _"sticky"_ version (regex support) 65 | * __Cx+F__ - Search, _"highlight"_ version (regex support) 66 | * __Cx+Alt+F__ - Replace in file 67 | * __Alt+G__ - Go to line number 68 | * __Cx+Z__ - Undo 69 | * __Cx+Shift+Z__ - Redo 70 | 71 | **Notice**, on a Mac OS X computer, you'll have to use the **CMD** key where it says _"Cx"_ above, while on other 72 | types of systems, you must use the **CTRL** key. In addition to the above explicit keyboard shortcuts, most modal widgets 73 | can be closed with the _"Escape"_ key and the _"OK"_ button will be clicked with the Carriage Return key. 74 | 75 | ### Settings 76 | 77 | Hyper IDE comes with 57 themes out of the box. These are for the most parts themes that are distributed with 78 | CodeMirror, and allows you to change the background color, font size, etc, of your CodeMirror editor. In 79 | addition Hyper IDE will use your chosen Phosphorus Five skin, which allows you to change its Micro skin 80 | by changing the skin that Phosphorus Five is using for your user. 81 | 82 | ### Plugins 83 | 84 | Most features in Hyper IDE can be turned on or off, and some features are only available if you are logged in 85 | as root. In addition, plugins can be turned on or off according to the declarations of plugins in the 86 | file `/modules/hyper-ide/configuration/plugins.hl`. If you want to enable all plugins, you can simply 87 | delete this file, if it exists, since all plugins are enabled by default. If you want to turn off all 88 | plugins, you can create an empty _"plugins.hl"_ file. If you want to only allow some specific plugin, 89 | you can create a `plugins.hl` file, and declare which plugins you want to enable as items in this file. 90 | 91 | The available plugins in your installation, can for the most parts be found in your 92 | `/modules/hyper-ide/startup/plugins/` folder - However, this depends upon your installation, and which 93 | additional modules you have installed. Plugins are Active Events, and resolved according to their namespace - 94 | So any Hyperlambda file, and/or C# module, might in theory create plugins for Hyper IDE. This allows you 95 | to extend Hyper IDE, without modifying any of the files inside of your Hyper IDE folder - Which allows 96 | you to easily upgrade to newer versions later, without loosing your custom extensions. 97 | 98 | If you want to see all available plugins for your current installation, you can evaluate the following snippet. 99 | 100 | ```hyperlambda-snippet 101 | .plugins 102 | ~hyper-ide.folder-plugins. 103 | ~hyper-ide.plugins. 104 | ~hyper-ide.global-plugin. 105 | vocabulary:x:/-/*?name 106 | create-widgets 107 | micro.widgets.modal:all-plugins 108 | widgets 109 | h3 110 | innerValue:Available plugins 111 | pre 112 | innerValue:x:/@vocabulary 113 | div 114 | class:right 115 | widgets 116 | button 117 | innerValue:Close 118 | onclick 119 | delete-widget:all-plugins 120 | ``` 121 | 122 | ### Responsiveness 123 | 124 | Although Hyper IDE is remarkably responsive, at least compared to Visual Studio, it is a web based IDE. 125 | This for obvious reasons have some benefits, and some disadvantages. One of the disadvantages is that if 126 | you expand a huge amount of folders in your file explorer, and also edit a lot of files at the same time - 127 | You might feel that Hyper IDE starts acting slow. If Hyper IDE starts acting slow on you, then you might 128 | benefit from saving your work, and reloading your page, to make sure you have less active widgets on your 129 | page. Typically, you probably wouldn't want to edit more than a handful of files at the same time, 130 | since this would result in that Hyper IDE becomes less responsive. 131 | 132 | Hyper IDE's purpose also is to mainly be an IDE for web application development. 133 | -------------------------------------------------------------------------------- /helpers/lambda-events/hyper-ide.editors.close.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file closes all editors who's paths starts with the given **[filter]**, unless they 3 | * have unsaved changes. If you want to force closing also editors with unsaved changes, 4 | * you can supply a **[force]** argument, and set its value to boolean _"true"_. 5 | * 6 | * If you provide a boolean _"true"_ value for **[exact]**, only the editor being 7 | * an exact match for the specified **[filter]** argument will be closed. 8 | */ 9 | 10 | /* 11 | * Separates arguments from the rest of our lambda. 12 | */ 13 | .signal 14 | 15 | 16 | 17 | 18 | 19 | /* 20 | * Sanity checking arguments. 21 | */ 22 | micro.lambda.contract.optional:x:/.. 23 | exact:bool 24 | filter:string 25 | force:bool 26 | 27 | 28 | 29 | 30 | 31 | /* 32 | * Defaults. 33 | */ 34 | .defaults 35 | filter:/ 36 | 37 | 38 | 39 | 40 | 41 | /* 42 | * Retrieving all open editors, and checking that there actually are any 43 | * open editors, and if not, returning early. 44 | */ 45 | hyper-ide.editors.get-open-editors 46 | if:x:/@hyper-ide.editors.get-open-editors/*?count 47 | =:int:0 48 | 49 | /* 50 | * No open editors, returning early to avoid evaluating the rest of our lambda. 51 | */ 52 | micro.windows.info:There are no open editors 53 | class:micro-windows-info warning 54 | return:bool:false 55 | 56 | 57 | 58 | 59 | 60 | /* 61 | * Retrieving active editor, since we'll need to track if it was closed or 62 | * not during our lambda evaluation. 63 | */ 64 | hyper-ide.active-editor.get-filepath 65 | 66 | 67 | 68 | 69 | 70 | /* 71 | * Used to track dirty editors we are not closing. 72 | */ 73 | .dirty 74 | 75 | 76 | 77 | 78 | 79 | /* 80 | * Used to track if active editor is closed. 81 | */ 82 | _active-deleted:bool:false 83 | 84 | 85 | 86 | 87 | 88 | /* 89 | * Iterating through all open editors. 90 | */ 91 | for-each:x:/@hyper-ide.editors.get-open-editors/* 92 | 93 | /* 94 | * Checking if currently iterated editor is a match for our [filter] condition. 95 | */ 96 | if:x:/@_dp/#?name 97 | =:x:(/../*/filter|/@.defaults/*/filter)/$?value 98 | or:x:/../*/exact?value.bool 99 | !=:bool:true 100 | and 101 | starts-with:x:/@_dp/#?name 102 | src:x:(/../*/filter|/@.defaults/*/filter)/$?value 103 | 104 | /* 105 | * Checking if currently iterated editor is dirty, and [force] is not true. 106 | */ 107 | if:x:/@_dp/#/*/clean?value 108 | =:bool:false 109 | and:x:/../*/force?value.bool 110 | !=:bool:true 111 | 112 | /* 113 | * Currently iterated editor is dirty, and user did not want to [force] closing, 114 | * hence we do not close it, but store the editor in our [.dirty] list, and 115 | * continue our iteration. 116 | */ 117 | add:x:/@.dirty 118 | src:x:/@_dp/#?name 119 | continue 120 | 121 | /* 122 | * Checking if this was our active editor. 123 | */ 124 | if:x:/@_dp/#?name 125 | =:x:/@hyper-ide.active-editor.get-filepath?value 126 | 127 | /* 128 | * This is our active editor, making sure we track the fact that it 129 | * was closed. 130 | */ 131 | set:x:/@_active-deleted?value 132 | src:bool:true 133 | 134 | /* 135 | * This is where the actual deletion of our editor is done. 136 | * 137 | * We'll need to delete the editor's toolbar, activate tab view button, 138 | * and actual editor. 139 | */ 140 | 141 | /* 142 | * Deleting actual editor. 143 | */ 144 | p5.web.widgets.find-first:hyper-ide-editor-tab-editors 145 | .editor:x:/@_dp/#?name 146 | delete-widget:x:/@p5.web.widgets.find-first/*/*?value 147 | 148 | /* 149 | * Then its activate button. 150 | */ 151 | p5.web.widgets.find-first:hyper-ide-editor-tab-buttons 152 | .activate:x:/@_dp/#?name 153 | delete-widget:x:/@p5.web.widgets.find-first/*/*?value 154 | 155 | /* 156 | * Then its toolbar. 157 | */ 158 | p5.web.widgets.find-first 159 | .toolbar:x:/@_dp/#?name 160 | delete-widget:x:/@p5.web.widgets.find-first/*/*?value 161 | 162 | /* 163 | * Removing currently iterated editor from our list of editors. 164 | * 165 | * This is done such that we end up with a list of available editors, 166 | * after we have closed all editors caller wants to close, which (might) be 167 | * used to determine which editor we should activate, if any. 168 | */ 169 | set:x:/@_dp/# 170 | 171 | 172 | 173 | 174 | 175 | /* 176 | * Checking if there was dirty editors, that were not closed, and if so, 177 | * showing a modal widget, warning user, asking him if he really wants to 178 | * close these editors, setting the last dirty editor to active, and returning 179 | * early to avoid evaluation of the rest of our lambda. 180 | */ 181 | if:x:/@.dirty/* 182 | 183 | /* 184 | * Dirty editors exists, and they were not closed, even though caller 185 | * requested to have these editors closed. 186 | * 187 | * Hence, we display a modal window to caller, allowing him to force closing, 188 | * sets the last dirty editor to active, and return early, to avoid evaluating 189 | * the rest of our lambda. 190 | * 191 | * First passing in all arguments to our "recursive" invocation, to make sure 192 | * we get our [exact] and [filter] arguments correctly mapped up in our second 193 | * invocation. 194 | */ 195 | add:x:/+/**/hyper-ide.editors.close 196 | src:x:/@.signal/--/<- 197 | micro.windows.confirm 198 | header:You have unsaved changes 199 | body:Some of your editors have unsaved changes, are you sure you want to close these? If you do, your changes will not be saved. 200 | onok 201 | 202 | /* 203 | * Invoking "self" with [force] argument, deleting modal widget first. 204 | */ 205 | hyper-ide.editors.close 206 | force:bool:true 207 | 208 | /* 209 | * Checking if we need to activate our last dirty editor. 210 | */ 211 | if:x:/@hyper-ide.active-editor.get-filepath?value 212 | !=:x:/@.dirty/0/-?name 213 | 214 | /* 215 | * We need to set our last dirty editor to active. 216 | */ 217 | hyper-ide.editors.set-active-editor:x:/@.dirty/0/-?name 218 | 219 | /* 220 | * Returning "failure" to caller. 221 | */ 222 | return:bool:false 223 | 224 | 225 | 226 | 227 | 228 | /* 229 | * Checking if active editor was deleted, and if it was, we'll need to 230 | * either load up another editor, or load our splash screen, depending 231 | * upon whether or not there are anymore available editors. 232 | */ 233 | if:x:/@_active-deleted?value 234 | 235 | /* 236 | * Active editor was closed. 237 | * 238 | * Checking if there are anymore editors left. 239 | */ 240 | if:x:/@hyper-ide.editors.get-open-editors/*?count 241 | >:int:0 242 | 243 | /* 244 | * Setting the last available editor as our active editor. 245 | */ 246 | hyper-ide.editors.set-active-editor:x:/@hyper-ide.editors.get-open-editors/0/-?name 247 | 248 | /* 249 | * Raising changed event. 250 | */ 251 | hyper-ide.file-explorer.item-changed:x:/@hyper-ide.editors.get-open-editors/0/-?name 252 | 253 | else 254 | 255 | /* 256 | * No more editors, deleting editor wrapper, and loading our splash screen. 257 | */ 258 | delete-widget:hyper-ide-editor-tab 259 | hyper-ide._load-splash 260 | 261 | /* 262 | * Raising our "all editors closed" event. 263 | */ 264 | hyper-ide.on-all-editors-closed 265 | 266 | /* 267 | * Checking if active item in file explorer is a file, and if it is, we make 268 | * sure we de-select it. 269 | */ 270 | hyper-ide.file-explorer.get-active-item 271 | if 272 | ends-with:x:/@hyper-ide.file-explorer.get-active-item?value 273 | src:/ 274 | not 275 | 276 | /* 277 | * Active file explorer item is a file, hence we de-select it. 278 | */ 279 | hyper-ide.file-explorer.set-active-item 280 | 281 | 282 | 283 | 284 | 285 | /* 286 | * Returning "success" to caller. 287 | */ 288 | return:bool:true 289 | -------------------------------------------------------------------------------- /helpers/app-templates/angular-todo.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Template for a new _"AngularJS module"_. 3 | * 4 | * This file creates a simple _"TODO"_ type of AngularJS application. 5 | * The file requires a __[name]__ argument being the name of new module to create, which 6 | * will become your module's URL. 7 | * 8 | * This file is used by the __[hyper-ide.folder-plugin.create-module]__ 9 | * plugin when the user creates a new module by following a wizard. 10 | */ 11 | 12 | 13 | 14 | 15 | 16 | /* 17 | * Sanity checking arguments. 18 | */ 19 | micro.lambda.contract.min:x:/.. 20 | name:string 21 | 22 | 23 | 24 | 25 | 26 | /* 27 | * Creates our new module. 28 | * 29 | * First making sure our main module folder exists. 30 | */ 31 | create-folder:/modules/{0}/ 32 | :x:/../*/name?value 33 | 34 | 35 | 36 | 37 | 38 | /* 39 | * We'll need the module name in UPPERCASE later down the road. 40 | */ 41 | to-upper:x:/../*/name?value 42 | 43 | 44 | 45 | 46 | 47 | /* 48 | * Creating our "desktop.hl" file. 49 | */ 50 | save-file:/modules/{0}/desktop.hl 51 | :x:/../*/name?value 52 | src:@" 53 | /* 54 | * Desktop widget. 55 | * 56 | * This becomes your module's 'desktop icon'. 57 | */ 58 | container 59 | element:a 60 | class:desktop-app button shaded 61 | title:A simple AngularJS TODO app 62 | widgets 63 | span 64 | class:desktop-app-name 65 | widgets 66 | literal 67 | element:span 68 | class:icon-happy desktop-app-icon 69 | span 70 | class:desktop-app-text 71 | innerValue:TODO 72 | " 73 | 74 | 75 | 76 | 77 | 78 | /* 79 | * Then creating our "startup.hl" file. 80 | */ 81 | to-upper:x:/../*/name?value 82 | save-file:/modules/{0}/startup.hl 83 | :x:/../*/name?value 84 | src:@" 85 | /* 86 | * Provide whatever startup logic your module requires here, if any. 87 | * 88 | * For instance, create Active Events necessary to wire up your module. 89 | * Below is an example of creating a 'path' event for instance, which unrolls 90 | * the path declaration of @YOUR-APP-NAME to your module's main folder. 91 | */ 92 | split:x:/..?name 93 | =:/ 94 | set:x:/@split/0/- 95 | join:x:/@split/*?name 96 | sep:/ 97 | eval-x:x:/+/* 98 | create-event:p5.io.unroll-path.@{0} 99 | return:/{{0}} 100 | :x:/@join?value 101 | " 102 | :x:/@to-upper?value 103 | 104 | 105 | 106 | 107 | 108 | /* 109 | * Then creating our "install.hl" file. 110 | */ 111 | save-file:/modules/{0}/install.hl 112 | :x:/../*/name?value 113 | src:@" 114 | 115 | 116 | /* 117 | * Creates our database. 118 | * 119 | * Notice, if the schema exists from before, this will throw an exception, 120 | * which we simply silently catch. 121 | */ 122 | try 123 | p5.config.get:p5.data.prefix 124 | p5.mysql.connect:[sys] 125 | p5.mysql.execute:create schema `{{0}}{0}` 126 | :x:/@p5.config.get/*?value 127 | p5.mysql.connect:[{0}] 128 | p5.mysql.execute:@"" 129 | create table if not exists `items` ( 130 | `id` int(10) unsigned not null auto_increment, 131 | `description` varchar(1024) collate utf8mb4_unicode_ci not null, 132 | primary key (`id`) 133 | ) engine=InnoDB auto_increment=0 default charset=utf8mb4 collate=utf8mb4_unicode_ci;"" 134 | catch 135 | 136 | /* 137 | * Database exists from before. 138 | */ 139 | " 140 | :x:/../*/name?value 141 | 142 | 143 | 144 | 145 | 146 | /* 147 | * Then creating our "uninstall.hl" file. 148 | */ 149 | save-file:/modules/{0}/uninstall.hl 150 | :x:/../*/name?value 151 | src:@" 152 | /* 153 | * Provide whatever uninstall logic your module requires here, if any. 154 | * 155 | * Common tasks for this file, is to delete all Active Events created by 156 | * your module, such as the following example illustrates. 157 | */ 158 | delete-event:p5.io.unroll-path.@{0} 159 | " 160 | :x:/@to-upper?value 161 | 162 | 163 | 164 | 165 | 166 | /* 167 | * Then creating our "launch.hl" file. 168 | */ 169 | save-file:/modules/{0}/launch.hl 170 | :x:/../*/name?value 171 | src:@" 172 | p5.web.echo-file:@{0}/index.html 173 | " 174 | :x:/@to-upper?value 175 | 176 | 177 | 178 | 179 | 180 | /* 181 | * Then creating our "index.html" file. 182 | */ 183 | save-file:/modules/{0}/index.html 184 | :x:/../*/name?value 185 | src:@" 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 |
197 |
198 |
199 |
200 |

Todo

201 |
202 |
203 | 204 | 205 |
206 |
207 |
208 |
    209 |
  • {{{{todo.description}}}}
  • 210 |
211 |
212 |
213 |
214 |
215 |
216 | 217 | 218 | " 219 | :x:/../*/name?value 220 | 221 | 222 | 223 | 224 | 225 | /* 226 | * Then creating our "controller.js" file. 227 | */ 228 | save-file:/modules/{0}/controller.js 229 | :x:/../*/name?value 230 | src:@" 231 | 232 | /* 233 | * Main module for our Angular app. 234 | */ 235 | angular.module ('todoApp', []) 236 | 237 | /* 238 | * Our only controller, responsible for invoking our server side back end, 239 | * and databinding our view. 240 | */ 241 | .controller ('TodoListController', function ($scope, $http) {{ 242 | 243 | /* 244 | * Fetching existing items from our server. 245 | */ 246 | var todoList = this; 247 | $http.get ('/hyper-core/mysql/{0}/items/select'). 248 | then (function successCallback (response) {{ 249 | todoList.todos = response.data; 250 | }}); 251 | 252 | /* 253 | * Invoked by our view when a new item has been added by user. 254 | * Updates our view with the item, and invokes server-side back end, 255 | * by issuing an 'insert' command towards our REST ORM. 256 | */ 257 | todoList.addTodo = function () {{ 258 | 259 | /* 260 | * Invoking our server-side method, to insert item into our database. 261 | * 262 | * Notice, server-side back end requires a 'PUT' request. 263 | */ 264 | $http ({{ 265 | method:'PUT', 266 | url: '/hyper-core/mysql/{0}/items/insert', 267 | 268 | /* 269 | * Our server-side requires the data for our insert operation to be URL encoded, 270 | * hence we'll need to transform from the default serialization logic of Angular, 271 | * which is JSON, to URL encoded data. 272 | */ 273 | headers: {{'Content-Type': 'application/x-www-form-urlencoded'}}, 274 | transformRequest: function (obj) {{ 275 | var str = []; 276 | for (var p in obj) {{ 277 | str.push (encodeURIComponent (p) + '=' + encodeURIComponent (obj [p])); 278 | }} 279 | return str.join ('&'); 280 | }}, 281 | data: {{description: document.getElementById ('newItem').value}} 282 | }}).then (function successCallback (response) {{ 283 | 284 | /* 285 | * Pushing our new item into our list of items, and making sure 286 | * we set our textbox' value to empty. 287 | */ 288 | todoList.todos.push ({{ 289 | description: todoList.todoText, 290 | id:response.data.id 291 | }}); 292 | todoList.todoText = ''; 293 | }}); 294 | }}; 295 | 296 | /* 297 | * Invoked by our view when an item is deleted. 298 | */ 299 | todoList.delete = function (id) {{ 300 | 301 | /* 302 | * Deleting our clicked item from our list of items from our view. 303 | */ 304 | for(var idx = 0; idx < todoList.todos.length; idx++) {{ 305 | if (todoList.todos [idx].id === id) {{ 306 | todoList.todos.splice (idx,1); 307 | break; 308 | }} 309 | }} 310 | 311 | /* 312 | * Invoking our server-side method, to delete the item from our database. 313 | * 314 | * Notice, server-side back end requires a 'DELETE' request. 315 | */ 316 | $http.delete('/hyper-core/mysql/{0}/items/delete?id=' + id); 317 | }} 318 | }}); 319 | " 320 | :x:/../*/name?value 321 | 322 | 323 | 324 | 325 | 326 | /* 327 | * Then creating our "styles.css" file. 328 | */ 329 | save-file:/modules/{0}/styles.css 330 | :x:/../*/name?value 331 | src:@" 332 | 333 | .bg { 334 | position:relative; 335 | } 336 | 337 | .new-item { 338 | position:absolute; 339 | bottom:0; 340 | right:1rem; 341 | } 342 | 343 | .submit-button { 344 | width:auto; 345 | } 346 | 347 | ul.todos { 348 | list-style:none; 349 | margin-left:0; 350 | margin-bottom:3rem; 351 | } 352 | 353 | ul.todos>li { 354 | font-size:1.5rem; 355 | margin-bottom:.5rem; 356 | cursor:no-drop; 357 | } 358 | " 359 | -------------------------------------------------------------------------------- /helpers/toolbars/secondary-toolbar/02-delete.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Deletes active file or folder toolbar button. 3 | */ 4 | button 5 | innerValue:@"" 6 | title:Deletes file or folder 7 | disabled 8 | events 9 | 10 | /* 11 | * Sink invoked when active item in file explorer has been changed. 12 | */ 13 | hyper-ide.file-explorer.item-changed 14 | 15 | /* 16 | * Checking if there is a selected item. 17 | */ 18 | if:x:/../*/_arg?value 19 | 20 | /* 21 | * Enabling button. 22 | */ 23 | delete-widget-property:x:/../*/_event?value 24 | disabled 25 | 26 | else 27 | 28 | /* 29 | * Disabling button since there is no active item in file explorer. 30 | */ 31 | set-widget-property:x:/../*/_event?value 32 | disabled 33 | 34 | /* 35 | * Deletes a file. 36 | */ 37 | hyper-ide._delete-file 38 | 39 | /* 40 | * Retrieving file name. 41 | */ 42 | hyper-ide.file-explorer.get-active-item 43 | 44 | /* 45 | * Then passing filename into modal widget. 46 | */ 47 | eval-x:x:/+/**/.filename 48 | create-widgets 49 | micro.widgets.modal:hyper-ide-confirm-delete-file 50 | widgets 51 | h3 52 | innerValue:Confirm deletion 53 | literal 54 | element:p 55 | style:"float:left;font-size:5rem;margin-right:.5rem;" 56 | class:icon-bin 57 | p 58 | innerValue:@"Are you sure you want to delete the {0} file? I need you to confirm this action before I allow you to do this." 59 | :x:/@hyper-ide.file-explorer.get-active-item?value 60 | p 61 | innerValue:@"Warning, this action is permanent!" 62 | div 63 | class:right 64 | widgets 65 | div 66 | class:strip 67 | widgets 68 | button 69 | innerValue:Yes 70 | oninit 71 | 72 | /* 73 | * Setting initial focus to "Yes" button. 74 | */ 75 | micro.page.set-focus:x:/../*/_event?value 76 | 77 | onclick 78 | 79 | /* 80 | * Forward evaluated above. 81 | */ 82 | .filename:x:/../*/hyper-ide.file-explorer.get-active-item?value 83 | 84 | /* 85 | * Deleting actual file. 86 | */ 87 | delete-file:x:/@.filename?value 88 | 89 | /* 90 | * Deleting selected item from tree. 91 | * 92 | * Notice, selected tree view item will always be the file 93 | * user is trying to delete. 94 | */ 95 | micro.widgets.tree.get-selected-items:hyper-ide-folder-tree-browser 96 | add:x:/../*/micro.widgets.tree.delete-items 97 | src:x:/@micro.widgets.tree.get-selected-items/* 98 | micro.widgets.tree.delete-items:hyper-ide-folder-tree-browser 99 | 100 | /* 101 | * Making sure we close editor for file, if there exists 102 | * at least one editor that is open. 103 | */ 104 | hyper-ide.editors.get-open-editors 105 | if:x:/@hyper-ide.editors.get-open-editors/*?count 106 | >:int:0 107 | eval-x:x:/+/* 108 | hyper-ide.editors.close 109 | filter:x:/@.filename?value 110 | exact:bool:true 111 | force:bool:true 112 | 113 | /* 114 | * Notice, in case file that was deleted didn't have a CodeMirror 115 | * editor for its file extension, there might still exist 116 | * a toolbar for it. Hence, checking if it does, and deleting 117 | * the toolbar, if it exists. 118 | */ 119 | p5.web.widgets.find-first:hyper-ide-toolbar-wrapper 120 | .toolbar:x:/@.filename?value 121 | if:x:/@p5.web.widgets.find-first/*/*?value 122 | delete-widget:x:/@p5.web.widgets.find-first/*/*?value 123 | 124 | /* 125 | * Deleting modal window. 126 | */ 127 | delete-widget:hyper-ide-confirm-delete-file 128 | 129 | button 130 | innerValue:No 131 | onclick 132 | 133 | /* 134 | * Simply deleting modal widget. 135 | */ 136 | delete-widget:hyper-ide-confirm-delete-file 137 | 138 | /* 139 | * Deletes a folder. 140 | */ 141 | hyper-ide._delete-folder 142 | 143 | /* 144 | * Retrieving folder name. 145 | */ 146 | hyper-ide.file-explorer.get-active-item 147 | 148 | /* 149 | * Deleting folder, asking user to confirm the action. 150 | */ 151 | create-widgets 152 | micro.widgets.modal:hyper-ide-confirm-delete-folder 153 | widgets 154 | h3 155 | innerValue:Confirm deletion 156 | literal 157 | element:p 158 | style:"float:left;font-size:5rem;margin-right:.5rem;" 159 | class:icon-bin 160 | p 161 | innerValue:@"Are you sure you want to delete the {0} folder? This will delete all files and sub-folders, 162 | and close all editors that are editing files inside of your folder. I need you to confirm this action before I allow you to do this." 163 | :x:/@hyper-ide.file-explorer.get-active-item?value 164 | p 165 | innerValue:@"Warning, this action is permanent!" 166 | div 167 | class:right 168 | widgets 169 | div 170 | class:strip 171 | widgets 172 | button 173 | innerValue:Yes 174 | oninit 175 | 176 | /* 177 | * Setting initial focus to "Yes" button. 178 | */ 179 | micro.page.set-focus:x:/../*/_event?value 180 | 181 | onclick 182 | 183 | /* 184 | * Figuring out which folder user is trying to delete. 185 | */ 186 | get-widget-property:hyper-ide-active-folder-toolbar 187 | .folder 188 | 189 | /* 190 | * Deleting actual folder. 191 | */ 192 | delete-folder:x:/@get-widget-property/*/*?value 193 | 194 | /* 195 | * Deleting selected item from tree. 196 | * 197 | * Notice, selected tree view item will always be the file or folder 198 | * user is trying to delete, since selecting a tree node, 199 | * changes the active file object edited. 200 | */ 201 | micro.widgets.tree.get-selected-items:hyper-ide-folder-tree-browser 202 | add:x:/../*/micro.widgets.tree.delete-items 203 | src:x:/@micro.widgets.tree.get-selected-items/* 204 | micro.widgets.tree.delete-items:hyper-ide-folder-tree-browser 205 | 206 | /* 207 | * Making sure we close all editors that are editing files beneath 208 | * currently deleted folder. 209 | */ 210 | eval-x:x:/+/* 211 | hyper-ide.editors.close 212 | filter:x:/@get-widget-property/*/*?value 213 | force:bool:true 214 | 215 | /* 216 | * Checking if folder toolbar exists, and deleting it if it does. 217 | */ 218 | if 219 | fetch:x:/0/0?value 220 | widget-exists:hyper-ide-active-folder-toolbar 221 | delete-widget:hyper-ide-active-folder-toolbar 222 | 223 | /* 224 | * Deleting modal window. 225 | */ 226 | delete-widget:hyper-ide-confirm-delete-folder 227 | 228 | button 229 | innerValue:No 230 | onclick 231 | 232 | /* 233 | * Simply deleting modal widget. 234 | */ 235 | delete-widget:hyper-ide-confirm-delete-folder 236 | 237 | onclick 238 | 239 | /* 240 | * Checking if user is trying to delete a file, or a folder. 241 | */ 242 | hyper-ide.file-explorer.get-active-item 243 | if 244 | ends-with:x:/@hyper-ide.file-explorer.get-active-item?value 245 | src:/ 246 | 247 | /* 248 | * Deletes a folder. 249 | */ 250 | hyper-ide._delete-folder 251 | 252 | else 253 | 254 | /* 255 | * Deletes a file. 256 | */ 257 | hyper-ide._delete-file 258 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.folder-plugin.execute.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.folder-plugin.execute]__ Active Event. 3 | */ 4 | 5 | /* 6 | * This event creates our execute shell script in folder plugin button. This 7 | * button is only visible if the currently selected object in your folder 8 | * explorer is a folder, and not a file. 9 | * 10 | * When the button is clicked, it will create a modal window, allowing the 11 | * user to type in some bash script, or select a template script taken from 12 | * the _"/modules/hyper-ide/helpers/shell-snippets/"_ folder, and execute 13 | * that shell script with the current path being the selected folder from 14 | * the file explorer. 15 | * 16 | * **Notice**, whether or not the user has permissions to actually execute 17 | * shell scripts, depends upon how the authorization objects in your system 18 | * have been setup. 19 | */ 20 | create-event:hyper-ide.folder-plugin.execute 21 | return 22 | button 23 | innerValue:@"" 24 | title:Open terminal window 25 | onclick 26 | 27 | /* 28 | * Retrieving current folder. 29 | */ 30 | p5.web.widgets.find-first-ancestor:x:/../*/_event?value 31 | .folder 32 | get-widget-property:x:/-/*/*?value 33 | .folder 34 | 35 | /* 36 | * Retrieving active code. 37 | */ 38 | p5.web.session.get:hyper-ide.terminal-code 39 | if:x:/@p5.web.session.get/*?value 40 | set:x:/../*/.code?value 41 | src:x:/@p5.web.session.get/*?value 42 | .code: 43 | 44 | /* 45 | * Opens a modal window, asking user for command(s) he wants to execute. 46 | */ 47 | eval-x:x:/+/**/.folder|/+/**/.code 48 | create-widgets 49 | micro.widgets.modal:hyper-ide-execute-modal 50 | widgets 51 | micro.widgets.cover:hyper-ide-eval-shell-obscurer 52 | style:"display:none;" 53 | message:Executing your script ... 54 | h3 55 | innerValue:Shell script 56 | oninit 57 | 58 | /* 59 | * Forward evaluated above. 60 | */ 61 | .folder:x:/../*/get-widget-property/*/*?value 62 | 63 | /* 64 | * Displaying working folder as part of header. 65 | */ 66 | set-widget-property:x:/../*/_event?value 67 | innerValue:x:/@.folder?value 68 | 69 | div 70 | class:strip fill air-top 71 | widgets 72 | 73 | /* 74 | * Template snippets selector. 75 | */ 76 | label 77 | innerValue:Template 78 | select 79 | oninit 80 | 81 | /* 82 | * Listing all files in "shell-snippets" folder, and creating 83 | * one option element for each. 84 | */ 85 | list-files:@IDE/helpers/shell-snippets/ 86 | filter:.sh 87 | for-each:x:/@list-files/*?name 88 | split:x:/@_dp?value 89 | =:/ 90 | =:. 91 | create-widget 92 | element:option 93 | parent:x:/../*/_event?value 94 | innerValue:x:/@split/0/-2?name 95 | value:x:/@_dp?value 96 | 97 | onchange 98 | 99 | /* 100 | * Loading file, and setting value of CodeMirror editor. 101 | */ 102 | get-widget-property:x:/../*/_event?value 103 | value 104 | load-file:x:/@get-widget-property/*/*?value 105 | replace:x:/@load-file/*?value 106 | src:` 107 | dest:\` 108 | replace:x:/@replace?value 109 | src:$ 110 | dest:\$ 111 | p5.web.widgets.find:hyper-ide-terminal-commands 112 | element:textarea 113 | p5.web.send-javascript:@"p5['{0}'].getDoc().setValue(`{1}`);" 114 | :x:/@p5.web.widgets.find/*/*?value 115 | :x:/@replace?value 116 | 117 | widgets 118 | option 119 | innerValue:Select template snippet ... 120 | 121 | micro.widgets.codemirror:hyper-ide-terminal-commands 122 | .data-field:code 123 | auto-focus:true 124 | mode:shell 125 | value:x:/../*/.code?value 126 | 127 | div 128 | class:right air-top 129 | widgets 130 | div 131 | class:strip 132 | widgets 133 | 134 | /* 135 | * Execute button. 136 | */ 137 | button:hyper-ide-execute-shell-script-button 138 | innerValue:Execute 139 | onclick 140 | 141 | /* 142 | * Making sure we show obscurer, for then to invoke "real" implementation. 143 | */ 144 | set-widget-property:hyper-ide-eval-shell-obscurer 145 | style:"display:block;position:absolute;" 146 | p5.web.send-javascript:@"p5.$('hyper-ide-execute-shell-script-button').raise('.onclick');" 147 | 148 | .onclick 149 | 150 | /* 151 | * Forward evaluated above. 152 | */ 153 | .folder:x:/../*/get-widget-property/*/*?value 154 | 155 | /* 156 | * Retrieving script. 157 | */ 158 | micro.form.serialize:hyper-ide-execute-modal 159 | 160 | /* 161 | * Saving current code in session, since it's highly likely that 162 | * user wants to execute similar code the next time he or she opens this window. 163 | */ 164 | p5.web.session.set:hyper-ide.terminal-code 165 | src:x:/@micro.form.serialize/*/code?value 166 | 167 | /* 168 | * Checking platform, since we might need to convert 169 | * from CR/LF to only LF, in case we're on MacOSX or Unix. 170 | */ 171 | p5.system.platform 172 | if:x:/@p5.system.platform?value 173 | =:Unix 174 | or:x:/@p5.system.platform?value 175 | =:MacOSX 176 | 177 | /* 178 | * Replacing CR/LF before we save file to get platform specific CR sequence. 179 | */ 180 | p5.system.platform.normalize-string:x:/@micro.form.serialize/*/code?value 181 | save-file:~/temp/temp-bash.sh 182 | src:x:/@p5.system.platform.normalize-string?value 183 | 184 | else 185 | 186 | /* 187 | * Saving file with CR/LF as new line characters. 188 | */ 189 | save-file:~/temp/temp-bash.sh 190 | src:x:/@micro.form.serialize/*/code?value 191 | 192 | /* 193 | * In case temp file contains passwords and such, we want 194 | * to make 100% certain of that we can successfully delete 195 | * it after execution, even if an exception occurs. 196 | */ 197 | try 198 | 199 | /* 200 | * Executing file with current folder being the currently open folder. 201 | */ 202 | p5.system.platform.execute-file:~/temp/temp-bash.sh 203 | working-folder:x:/@.folder?value 204 | 205 | /* 206 | * Displaying results of evaluation, making sure we 207 | * HTML encode it, to be sure. 208 | */ 209 | p5.html.html-encode:x:/@p5.system.platform.execute-file/*?value 210 | set-widget-property:hyper-ide-execute-result 211 | visible:true 212 | class:success air-top 213 | innerValue:x:/@p5.html.html-encode?value 214 | 215 | catch 216 | 217 | /* 218 | * Displaying error to user. 219 | */ 220 | p5.html.html-encode:x:/@message?value 221 | set-widget-property:hyper-ide-execute-result 222 | visible:true 223 | class:warning air-top 224 | innerValue:x:/@p5.html.html-encode?value 225 | 226 | finally 227 | 228 | /* 229 | * Deleting temporary file. 230 | */ 231 | delete-file:~/temp/temp-bash.sh 232 | 233 | /* 234 | * Making sure we hide obscurer. 235 | */ 236 | set-widget-property:hyper-ide-eval-shell-obscurer 237 | style:"display:none;" 238 | 239 | /* 240 | * Close window button. 241 | */ 242 | button 243 | innerValue:Close 244 | onclick 245 | 246 | /* 247 | * Simply closing modal window, making sure we save the active code 248 | * in our session at the same time. 249 | */ 250 | delete-widget:hyper-ide-execute-modal 251 | 252 | literal:hyper-ide-execute-result 253 | class:air-top 254 | style:"font-size:.7rem;" 255 | element:pre 256 | visible:false 257 | -------------------------------------------------------------------------------- /helpers/edit-file.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Edits the specified __[file]__, using some sort of CodeMirror editor, 3 | * according to which mappings exists in Hyper IDE for the file's extension. 4 | * This file is being evaluated when the user selects a file node in 5 | * his file explorer, and the file is not open from before in a (non-active) 6 | * editor. 7 | */ 8 | 9 | 10 | 11 | 12 | 13 | /* 14 | * Making sure user has access to file. 15 | */ 16 | if 17 | p5.io.authorize.read-file:x:/../*/file?value 18 | =:bool:false 19 | 20 | /* 21 | * User doesn't have access to read this file. 22 | */ 23 | micro.windows.info:You don't have access to read this file 24 | class:micro-windows-info warning 25 | return 26 | 27 | 28 | 29 | 30 | 31 | /* 32 | * Hiding any previously shown edit file toolbars. 33 | */ 34 | p5.web.widgets.find-first-like:hyper-ide-toolbar-wrapper 35 | .toolbar 36 | class:visible 37 | micro.css.delete:x:/@p5.web.widgets.find-first-like/*/*?value 38 | class:visible 39 | micro.css.add:x:/@p5.web.widgets.find-first-like/*/*?value 40 | class:hide 41 | 42 | 43 | 44 | 45 | 46 | /* 47 | * Making sure we load correct editor according to file extension. 48 | * 49 | * First loading file extension to CM mode mapping file. 50 | * This file contains a bunch of file extensions, that are "mapped" towards 51 | * CodeMirror modes. 52 | * 53 | * Hence, we load the file, do a loopkup for our file extension, at which point 54 | * we end up with a CodeMirror mode. 55 | */ 56 | load-file:@IDE/configuration/extension2cm-instance.hl 57 | 58 | 59 | 60 | 61 | 62 | /* 63 | * Checking if mode exists for file extension. 64 | * 65 | * First figuring our file extension of file caller wants to edit. 66 | */ 67 | .file-type 68 | split:x:/../*/file?value 69 | =:. 70 | if:x:/@load-file/*/*/{0} 71 | :x:/@split/0/-?name 72 | 73 | /* 74 | * There exists a CodeMirror mode for file type. 75 | */ 76 | set:x:/@.file-type?value 77 | src:x:/@load-file/*/*/{0}?value 78 | :x:/@split/0/-?name 79 | 80 | /* 81 | * Checking if splash screen is open, and closing it if it is. 82 | */ 83 | if 84 | fetch:x:/0/0?value 85 | widget-exists:hyper-ide-splash 86 | delete-widget:hyper-ide-splash 87 | 88 | /* 89 | * Making sure our "tab control" exists. 90 | * 91 | * The "tab control" widget will "wrap" all of our editors. 92 | */ 93 | if 94 | fetch:x:/0/0?value 95 | widget-exists:hyper-ide-editor-tab 96 | not 97 | 98 | /* 99 | * Creating our "tab control" wrapper. 100 | */ 101 | create-widget:hyper-ide-editor-tab 102 | parent:hyper-ide-file-editor 103 | class:hyper-ide-editor-tab 104 | widgets 105 | container:hyper-ide-editor-tab-buttons 106 | class:hyper-ide-editor-tab-buttons 107 | container:hyper-ide-editor-tab-editors 108 | class:hyper-ide-editor-tab-content shaded rounded 109 | 110 | /* 111 | * Making sure we hide any previously created editors. 112 | */ 113 | p5.web.widgets.find-first-like:hyper-ide-file-editor 114 | .editor 115 | class:visible 116 | micro.css.delete:x:/@p5.web.widgets.find-first-like/*/*?value 117 | class:visible 118 | micro.css.add:x:/@p5.web.widgets.find-first-like/*/*?value 119 | class:hide 120 | 121 | /* 122 | * Notice, to prevent non-active editors' content being serialised back from 123 | * client upon consecutive Ajax requests, we disable all non-active editors' 124 | * textarea. 125 | * 126 | * This will preserve a lot of bandwidth, and hence make Hyper IDE more responsive. 127 | */ 128 | p5.web.widgets.find-first:x:/@p5.web.widgets.find-first-like/*/*?value 129 | element:textarea 130 | set-widget-property:x:/@p5.web.widgets.find-first/*/*?value 131 | disabled 132 | 133 | /* 134 | * "Un-toggling" existing toggled tab button. 135 | */ 136 | p5.web.widgets.find-first-like:hyper-ide-editor-tab-buttons 137 | .activate 138 | class:toggled 139 | micro.css.delete:x:/@p5.web.widgets.find-first-like/*/*?value 140 | class:toggled 141 | 142 | /* 143 | * Loading file, such that we can pass its content into our editor instance. 144 | * 145 | * Making sure we do not convert the file. 146 | */ 147 | load-file:x:/../*/file?value 148 | convert:false 149 | 150 | /* 151 | * CodeMirror mode for file's extension exists. 152 | * 153 | * Adding CodeMirror editor with correct mode to our [widgets] collection below. 154 | */ 155 | eval-x:x:/+/*/*/* 156 | add:x:/../*/create-widgets/*/div/*/widgets/=editor 157 | src 158 | micro.widgets.codemirror 159 | .data-field:content 160 | mode:x:/@load-file/@load-file/*/*/{0}?value 161 | :x:/@split/0/-?name 162 | value:x:/@load-file/*?value 163 | auto-focus:true 164 | keys 165 | Alt-S:p5.$('hyper-ide-file-editor').raise('.onsave'); 166 | Alt-X:p5.$('hyper-ide-file-editor').raise('.onclose'); 167 | Alt-W:p5.$('hyper-ide-file-editor').raise('.onnext'); 168 | Alt-Q:p5.$('hyper-ide-file-editor').raise('.onprevious'); 169 | 170 | else 171 | 172 | /* 173 | * No CodeMirror editor exists for file type. 174 | */ 175 | split:x:/../*/file?value 176 | =:. 177 | set:x:/@.file-type?value 178 | src:x:/@split/0/-?name 179 | 180 | /* 181 | * Removing instantiation of actual editor. 182 | */ 183 | set:x:/../*/create-widgets(/2|/1)|/../*/hyper-ide.on-file-edited|/../*/create-widgets/*/micro.widgets.file/*/folder 184 | 185 | 186 | 187 | 188 | 189 | /* 190 | * Making sure we hide any previously created file toolbars. 191 | */ 192 | p5.web.widgets.find-first-like 193 | .toolbar 194 | class:visible 195 | micro.css.delete:x:/@p5.web.widgets.find-first-like/*/*?value 196 | class:visible 197 | micro.css.add:x:/@p5.web.widgets.find-first-like/*/*?value 198 | class:hide 199 | 200 | 201 | 202 | 203 | 204 | /* 205 | * Adding all file specific plugins. 206 | */ 207 | eval-x:x:/+/*/* 208 | add:x:/../*/create-widgets/**/micro.widgets.file/*/widgets 209 | micro.evaluate.file:@IDE/helpers/get-plugins.hl 210 | type:hyper-ide.plugins.{0} 211 | :x:/@.file-type?value 212 | 213 | 214 | 215 | 216 | 217 | /* 218 | * Figuring out filename of file, without its folder. 219 | */ 220 | split:x:/../*/file?value 221 | =:/ 222 | 223 | 224 | 225 | 226 | 227 | /* 228 | * Creating our widgets. 229 | * 230 | * We create one "tab control button", then we add one editor into "tab control editors", 231 | * before we finally create one toolbar for saving file, etc. The latter will also contain 232 | * all plugins for current mode. 233 | */ 234 | create-widgets 235 | 236 | 237 | /* 238 | * Toolbar for saving editor's content, closing it, etc. 239 | */ 240 | micro.widgets.file 241 | folder:@IDE/helpers/toolbars/file-editor/ 242 | after:hyper-ide-toolbars 243 | class:strip right hyper-ide-toolbar visible 244 | .toolbar:x:/../*/file?value 245 | events 246 | 247 | /* 248 | * Invoked when for some reasons active file changes name. 249 | * 250 | * This event is invoked when for instance the file is renamed, etc. 251 | */ 252 | hyper-ide.set-active-filename 253 | 254 | /* 255 | * Checking if this is our active editor, and if not, returning early. 256 | */ 257 | get-widget-property:x:/../*/_event?value 258 | class 259 | if:x:/@get-widget-property/*/*?value 260 | ~:hide 261 | return 262 | 263 | /* 264 | * Updating [.file] attribute for widget. 265 | */ 266 | set-widget-property:x:/../*/_event?value 267 | .toolbar:x:/../*/_arg?value 268 | 269 | widgets 270 | 271 | 272 | /* 273 | * Activate tab/editor button. 274 | */ 275 | span 276 | parent:hyper-ide-editor-tab-buttons 277 | class:hyper-ide-activate-tab-button toggled button 278 | role:button 279 | .activate:x:/../*/file?value 280 | title:x:/../*/file?value 281 | events 282 | 283 | 284 | /* 285 | * Invoked when for some reasons active file changes name. 286 | */ 287 | hyper-ide.set-active-filename 288 | 289 | /* 290 | * Checking if this is our active file, and if not, returning early. 291 | */ 292 | get-widget-property:x:/../*/_event?value 293 | class 294 | if:x:/@get-widget-property/*/*?value 295 | !~:toggled 296 | return 297 | 298 | /* 299 | * Updating [.file] attribute for widget. 300 | */ 301 | split:x:/../*/_arg?value 302 | =:/ 303 | p5.web.widgets.get-children:x:/../*/_event?value 304 | set-widget-property:x:/-/*/0?value 305 | innerValue:x:/@split/0/-?name 306 | set-widget-property:x:/../*/_event?value 307 | .activate:x:/../*/_arg?value 308 | title:x:/../*/_arg?value 309 | 310 | onclick 311 | 312 | /* 313 | * Getting filename for editor. 314 | */ 315 | get-widget-property:x:/../*/_event?value 316 | .activate 317 | 318 | /* 319 | * Activating editor, and verifying invocation was a success. 320 | */ 321 | hyper-ide.editors.set-active-editor:x:/@get-widget-property/*/*?value 322 | 323 | widgets 324 | span 325 | innerValue:x:/@split/0/-?name 326 | 327 | /* 328 | * Close editor button. 329 | */ 330 | literal 331 | element:span 332 | class:hyper-ide-close icon-cross button 333 | title:Close editor 334 | role:button 335 | onclick 336 | 337 | /* 338 | * Closing active editor. 339 | */ 340 | p5.web.widgets.get-parent:x:/../*/_event?value 341 | get-widget-property:x:/-/*/*?value 342 | .activate 343 | eval-x:x:/+/* 344 | hyper-ide.editors.close 345 | filter:x:/@get-widget-property/*/*?value 346 | 347 | 348 | /* 349 | * Actual editor for file. 350 | * 351 | * Dynamically created above according to file extension. 352 | */ 353 | div 354 | parent:hyper-ide-editor-tab-editors 355 | class:hyper-ide-codemirror-wrapper visible 356 | .editor:x:/../*/file?value 357 | data-editor:x:/../*/file?value 358 | events 359 | 360 | 361 | /* 362 | * Invoked when for some reasons active file changes name. 363 | */ 364 | hyper-ide.set-active-filename 365 | 366 | /* 367 | * Checking if this is our active editor, and if not, returning early. 368 | */ 369 | get-widget-property:x:/../*/_event?value 370 | class 371 | if:x:/@get-widget-property/*/*?value 372 | ~:hide 373 | return 374 | 375 | /* 376 | * Updating [.file] attribute for widget. 377 | */ 378 | set-widget-property:x:/../*/_event?value 379 | .editor:x:/../*/_arg?value 380 | 381 | 382 | widgets:editor 383 | 384 | 385 | 386 | 387 | 388 | /* 389 | * Raising our "file edited" event. 390 | */ 391 | hyper-ide.on-file-edited 392 | -------------------------------------------------------------------------------- /helpers/toolbars/secondary-toolbar/01-rename.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Renaming file or folder toolbar button. 3 | */ 4 | button 5 | innerValue:@"" 6 | title:Renames your active file or folder 7 | disabled 8 | events 9 | 10 | /* 11 | * Sink invoked when active item in file explorer has been changed. 12 | */ 13 | hyper-ide.file-explorer.item-changed 14 | 15 | /* 16 | * Checking if there is a selected item. 17 | */ 18 | if:x:/../*/_arg?value 19 | 20 | /* 21 | * Enabling button. 22 | */ 23 | delete-widget-property:x:/../*/_event?value 24 | disabled 25 | 26 | else 27 | 28 | /* 29 | * Disabling button since there is no active item in file explorer. 30 | */ 31 | set-widget-property:x:/../*/_event?value 32 | disabled 33 | 34 | /* 35 | * Renames the currently active file explorer's folder. 36 | */ 37 | hyper-ide._rename-folder 38 | 39 | /* 40 | * Retrieving folder name. 41 | */ 42 | hyper-ide.file-explorer.get-active-item 43 | split:x:/@hyper-ide.file-explorer.get-active-item?value 44 | =:/ 45 | 46 | /* 47 | * Renaming folder. 48 | */ 49 | eval-x:x:/+/**(/.folder-name|/.value) 50 | create-widgets 51 | micro.widgets.modal:hyper-ide-confirm-rename-folder 52 | widgets 53 | h3 54 | innerValue:New name 55 | micro.widgets.wizard-form:hyper-ide-rename-folder-form 56 | text:hyper-ide-new-folder-name 57 | info:Name 58 | .data-field:name 59 | placeholder:New name for your folder ... 60 | onkeydown:@"if (event.keyCode == 13) {p5.$('hyper-ide-rename-folder-btn').raise('onclick');return false;} else if (event.keyCode == 27) {p5.$('hyper-ide-rename-cancel').raise('onclick');return false;}" 61 | oninit 62 | 63 | /* 64 | * Forward evaluated above. 65 | */ 66 | .folder-name:x:/../*/split/0/-?name 67 | 68 | /* 69 | * Setting initial focus to "Yes" button, and setting 70 | * initial value to old name. 71 | */ 72 | set-widget-property:x:/../*/_event?value 73 | value:x:/@.folder-name?value 74 | micro.page.set-focus:x:/../*/_event?value 75 | 76 | div 77 | class:right 78 | widgets 79 | div 80 | class:strip 81 | widgets 82 | button:hyper-ide-rename-folder-btn 83 | innerValue:OK 84 | onclick 85 | 86 | /* 87 | * Forward evaluated above. 88 | */ 89 | .value:x:/../*/hyper-ide.file-explorer.get-active-item?value 90 | 91 | /* 92 | * Closing all files matching filter, with [force] argument. 93 | */ 94 | eval-x:x:/+/* 95 | hyper-ide.editors.close 96 | filter:x:/@.value?value 97 | force:bool:true 98 | 99 | /* 100 | * Serializing form, figuring out new name for folder, 101 | * and changing its name. 102 | */ 103 | micro.form.serialize:hyper-ide-rename-folder-form 104 | split:x:/@.value?value 105 | =:/ 106 | set:x:/@split/0/- 107 | join:x:/@split/*?name 108 | sep:/ 109 | set:x:/@join?value 110 | src:/{0}/{1}/ 111 | :x:/@join?value 112 | :x:/@micro.form.serialize/*/name?value 113 | trim:x:/@join?value 114 | chars:/ 115 | move-folder:x:/@.value?value 116 | dest:/{0}/ 117 | :x:/@trim?value 118 | 119 | /* 120 | * Refreshing tree, and de-selecting folder. 121 | */ 122 | split:x:/@.value?value 123 | =:/ 124 | set:x:/@split/0/- 125 | join:x:/@split/*?name 126 | sep:/ 127 | hyper-ide.file-explorer.set-active-item:/{0}/ 128 | :x:/@join?value 129 | hyper-ide.file-explorer.refresh-active-folder 130 | hyper-ide.file-explorer.set-active-item:/{0}/ 131 | :x:/@trim?value 132 | eval-x:x:/+/* 133 | add:x:/+/* 134 | src:/{0}/ 135 | :x:/@trim?value 136 | micro.widgets.tree.toggle-items:hyper-ide-folder-tree-browser 137 | items 138 | 139 | /* 140 | * Deleting modal widget, and giving user some feedback. 141 | */ 142 | delete-widget:hyper-ide-confirm-rename-folder 143 | 144 | button:hyper-ide-rename-cancel 145 | innerValue:Cancel 146 | onclick 147 | 148 | /* 149 | * Simply deleting modal widget. 150 | */ 151 | delete-widget:hyper-ide-confirm-rename-folder 152 | 153 | /* 154 | * Renames the currently active file explorer's file. 155 | */ 156 | hyper-ide._rename-file 157 | 158 | /* 159 | * Retrieving file name. 160 | */ 161 | hyper-ide.file-explorer.get-active-item 162 | 163 | /* 164 | * Then passing filename into modal widget. 165 | */ 166 | eval-x:x:/+/**/.filename 167 | create-widgets 168 | micro.widgets.modal:hyper-ide-confirm-rename-file 169 | widgets 170 | h3 171 | innerValue:New name 172 | micro.widgets.wizard-form:hyper-ide-rename-file-form 173 | text:hyper-ide-new-file-name 174 | info:Name 175 | .data-field:name 176 | placeholder:New name for your file ... 177 | onkeydown:@"if (event.keyCode == 13) {p5.$('hyper-ide-rename-file-btn').raise('onclick');return false;} else if (event.keyCode == 27) {p5.$('hyper-ide-rename-cancel').raise('onclick');return false;}" 178 | oninit 179 | 180 | /* 181 | * Forward evaluated above. 182 | */ 183 | .filename:x:/../*/hyper-ide.file-explorer.get-active-item?value 184 | split:x:/-?value 185 | =:/ 186 | 187 | /* 188 | * Setting initial focus to "Yes" button, and setting 189 | * initial value to old name. 190 | */ 191 | set-widget-property:x:/../*/_event?value 192 | value:x:/@split/0/-?name 193 | micro.page.set-focus:x:/../*/_event?value 194 | 195 | div 196 | class:right 197 | widgets 198 | div 199 | class:strip 200 | widgets 201 | button:hyper-ide-rename-file-btn 202 | innerValue:OK 203 | onclick 204 | 205 | /* 206 | * Forward evaluated above. 207 | */ 208 | .filename:x:/../*/hyper-ide.file-explorer.get-active-item?value 209 | 210 | /* 211 | * Finding file's folder name. 212 | * 213 | * Making sure we get it in canonised form. 214 | */ 215 | .folder 216 | split:x:/@.filename?value 217 | =:/ 218 | set:x:/@split/0/- 219 | join:x:/@split/*?name 220 | sep:/ 221 | set:x:/@join?value 222 | src:/{0}/ 223 | :x:/@join?value 224 | trim-left:x:/@join?value 225 | chars:/ 226 | set:x:/@.folder?value 227 | src:/{0} 228 | :x:/@trim-left?value 229 | 230 | /* 231 | * Serializing form to figure out new name for file. 232 | */ 233 | micro.form.serialize:hyper-ide-rename-file-form 234 | 235 | /* 236 | * Renaming file. 237 | */ 238 | move-file:x:/@.filename?value 239 | dest:{0}{1} 240 | :x:/@.folder?value 241 | :x:/@micro.form.serialize/*/name?value 242 | 243 | /* 244 | * Refreshing tree, since folder's content now has changed. 245 | */ 246 | hyper-ide.file-explorer.refresh-folder:x:/@.folder?value 247 | 248 | /* 249 | * Updating item in editor. 250 | */ 251 | hyper-ide.set-active-filename:{0}{1} 252 | :x:/@.folder?value 253 | :x:/@micro.form.serialize/*/name?value 254 | 255 | /* 256 | * Since refreshing the folder changes the active item 257 | * in our tree view, we set it again here. 258 | */ 259 | hyper-ide.file-explorer.set-active-item:{0}{1} 260 | :x:/@.folder?value 261 | :x:/@micro.form.serialize/*/name?value 262 | 263 | /* 264 | * Deleting modal widget, and giving user some feedback. 265 | */ 266 | delete-widget:hyper-ide-confirm-rename-file 267 | 268 | button:hyper-ide-rename-cancel 269 | innerValue:Cancel 270 | onclick 271 | 272 | /* 273 | * Simply deleting modal widget. 274 | */ 275 | delete-widget:hyper-ide-confirm-rename-file 276 | 277 | onclick 278 | 279 | /* 280 | * Checking if user is trying to rename a file, or a folder. 281 | */ 282 | hyper-ide.file-explorer.get-active-item 283 | if 284 | ends-with:x:/@hyper-ide.file-explorer.get-active-item?value 285 | src:/ 286 | 287 | /* 288 | * Renaming a folder. 289 | */ 290 | hyper-ide._rename-folder 291 | 292 | else 293 | 294 | /* 295 | * Renaming a file. 296 | */ 297 | hyper-ide._rename-file 298 | -------------------------------------------------------------------------------- /help-files/Hyper IDE/05 - Hyper IDE API.md: -------------------------------------------------------------------------------- 1 | ## Hyper IDE's API 2 | 3 | Hyper IDE has a rich API, which allows you to automate tasks, and extend it as you see fit. Below is a list 4 | of all Active Events that are available when Hyper IDE is open. 5 | 6 | * __[hyper-ide.is-open]__ - Return true if Hyper IDE is open 7 | * __[hyper-ide.file-explorer.select-path]__ - Expands the specified __[\_arg]__ path in your file explorer, and starts the correct editor, if you are giving it a path to a file 8 | * __[hyper-ide.file-explorer.set-active-item]__ - Sets the active file explorer item. Notice, will not expand folders as the above event will, but expects the specified __[\_arg]__ folder/file to already have been loaded in your file explorer 9 | * __[hyper-ide.file-explorer.get-active-item]__ - Returns the active file explorer item to caller 10 | * __[hyper-ide.file-explorer.refresh-active-folder]__ - Reloads the currently active item in your file explorer 11 | * __[hyper-ide.active-editor.get-filepath]__ - Returns the path of the currently edited file, if any 12 | * __[hyper-ide.active-editor.get-id]__ - Returns the ID of the currently active editor, if any 13 | * __[hyper-ide.active-editor.get-code]__ - Returns the code for the currently active editor, if any 14 | * __[hyper-ide.active-editor.set-code]__ - Sets the code for the currently active editor 15 | * __[hyper-ide.active-editor.is-clean]__ - Returns false if your currently active editor has unsaved changes 16 | * __[hyper-ide.active-editor.set-clean]__ - Sets the clean flag for your currently active editor, pass in "true" or "false" 17 | * __[hyper-ide.active-editor.save]__ - Saves your currently active editor 18 | * __[hyper-ide.active-editor.close]__ - Closes your currently active editor 19 | * __[hyper-ide.editors.get-open-editors]__ - Returns the file path to all open editors 20 | * __[hyper-ide.editors.set-active-editor]__ - Sets the currently active editor, requires the editor to already have been opened 21 | * __[hyper-ide.editors.activate-previous-editor]__ - Activates the previous available editor 22 | * __[hyper-ide.editors.activate-next-editor]__ - Activates the next available editor 23 | * __[hyper-ide.editors.close]__ - Closes one or more editors. Pass in __[filter]__ being a file/folder path which will declare which editors it will close, and __[exact]__ being boolean true, if you only want to close the editor with the exact matching __[filter]__ path 24 | * __[desktop.help.display]__ - Displays the help files for Hyper IDE. Optionally pass in __[file]__ to open a specific help file. 25 | 26 | Notice that Hyper IDE will also raise the **[hyper-ide.file-explorer.item-changed]** Active Event when the file 27 | explorer's active item has been changed. The new item selected in the file explorer, will be available as **[\_arg]** 28 | from within your lambda event. 29 | 30 | ### Creating plugins for Hyper IDE 31 | 32 | Hyper IDE easily allows you to create your own plugins. These plugins can be global plugins, at which point 33 | they're available all the time - Or they can be plugins that are only available if some specific type of editor 34 | is your active editor. Below is an example of a plugin that will show an information bubble window, but which will 35 | only be available if your edited file is an HTML type of file. 36 | 37 | ```hyperlambda-snippet 38 | /* 39 | * Creates our bubble window HTML plugin. 40 | */ 41 | create-event:hyper-ide.plugins.htmlmixed.is-html-file 42 | return 43 | button 44 | innerValue:@"" 45 | title:Shows an information window 46 | onclick 47 | 48 | /* 49 | * Displays an information "bubble" window. 50 | */ 51 | micro.windows.info:This is an HTML file! 52 | ``` 53 | 54 | If you evaluate the code above, for then to edit an HTML file, you will see that you've got an additional 55 | toolbar button, which once clicked displays an information bubble window for you. 56 | 57 | Hyper IDE will automatically figure out which plugins to load according to their Active Event names. The naming 58 | convention for this is as follows `hyper-ide.plugins.code-mirror-mode.plugin-name`. From our above example, 59 | `htmlmixed` is the CodeMirror mode name for files that are HTML files. Hence, Hyper IDE will load up that 60 | additional plugin button, every time you open an HTML file for editing. To create a similar information bubble 61 | window for CSS files, you can do so with the following code. 62 | 63 | ```hyperlambda-snippet 64 | /* 65 | * Creates our bubble window CSS plugin. 66 | */ 67 | create-event:hyper-ide.plugins.css.is-css-file 68 | return 69 | button 70 | innerValue:@"" 71 | title:Shows an information window 72 | onclick 73 | 74 | /* 75 | * Displays an information "bubble" window. 76 | */ 77 | micro.windows.info:This is a CSS file! 78 | ``` 79 | 80 | If you want to create a plugin which is only available when a folder is selected in your file explorer, you 81 | can change the above `.plugins.` to `.folder-plugin.`. If you want to create a plugin which is only available 82 | when some specific folder is activated, you'll need to use the **[hyper-ide.file-explorer.get-active-item]** 83 | lambda event to determine which folder has been activated, before returning your plugin to caller. The 84 | **[hyper-ide.folder-plugins.create-module]** plugin illustrates this, since it's only available when the _"/modules/"_ 85 | folder is activated. 86 | 87 | Notice, even though most plugins in Hyper IDE are simple buttons, creating any type of plugin, being for instance 88 | a textbox, or a select widget, is easily accomplished, as long as whatever you return from your plugin Active Event, 89 | can somehow be stuffed inside of a Micro _"strip"_ widget. 90 | 91 | If you want to create a global plugin for Hyper IDE, which is always always available, regardless of which file or 92 | folder object is active in your file explorer, you can do so with the following naming 93 | convention `hyper-ide.global-plugin.YOUR-PLUGIN-NAME`. 94 | 95 | ### Hyper IDE as a plugin 96 | 97 | You can also consume Hyper IDE in your own application, as an extension widget. This extension widget's Active Event 98 | name is **[hyper-ide.widgets.ide]**. This allows you to in its entirely load up Hyper IDE as an extension widget 99 | in your own applications. Whether or not this makes sense or not, is arguably questionable. However, it may have 100 | uses for you, when debugging your applications - So I've chosen to allow for it. Notice, if you consume Hyper IDE 101 | as an extension widget, you're responsible yourself to load up its CSS file. This can be done with the following 102 | code. 103 | 104 | ```hyperlambda-snippet 105 | /* 106 | * Loads Hyper IDE's CSS file, for then to instantiate the Hyper IDE 107 | * extension widget inside a modal widget. 108 | */ 109 | p5.web.include-css-file:@IDE/media/main.css 110 | create-widgets 111 | micro.widgets.modal 112 | class:micro-widgets-modal large 113 | widgets 114 | 115 | /* 116 | * The Hyper IDE extension widget. 117 | */ 118 | hyper-ide.widgets.ide 119 | ``` 120 | 121 | By explicitly choosing to not load Hyper IDE's CSS file, this allows you to override the CSS classes used for the 122 | editor, to customise its appearance, by creating your own CSS file(s), and change its content. Notice, you can 123 | only instantiate Hyper IDE once on your page. Hence, make sure you check to see if it's already open, before you 124 | create your extension widget. Evaluating the above code while Hyper IDE is already open, will raise an exception. 125 | 126 | ### Template project types 127 | 128 | If you select the _"/modules/"_ folder, you'll see a _"create new module"_ plugin. By default, there are only a 129 | handful of different project types here, such as _"hello-world"_, _"datagrid"_ and _"angular-todo"_. However, 130 | these are simple template file, which you can extend yourself, with your own module types. To create your own 131 | template module types, create a new file encapsulating your template in your _"/modules/hyper-ide/helpers/app-template/"_ 132 | folder. Such template projects can also require additional settings from the user. This can be seen in 133 | [this file](hyper-ide?path=/modules/hyper-ide/helpers/app-templates/datagrid.hl) for instance, which has a 134 | **[.settings]** segment, which is expected to be a lambda object, containing additional widgets, the user 135 | needs to interact with, as he creates a new module. 136 | 137 | As the user creates a new module, your new module template file, will be evaluated with a **[name]** argument, 138 | which is the name of the template he chose to create. In addition, all additional **[.settings]** widget's values 139 | will be passed in, allowing you to retrieve these additional settings, as the user supplied them during creation. 140 | Below is a screenshot of how the process of creating such a new template module might appear to the end user. 141 | 142 | https://phosphorusfive.files.wordpress.com/2018/03/new-module-screenshot.png 143 | 144 | Such template projects might provide a valuable addon to avoid having to repeat repetetive tasks which 145 | are for some reasons necessary to create boiler plate code for, every time you create a new module. 146 | 147 | **Notice**, if you add such template new module extensions, you should take care of not loosing your files 148 | as you upgrade Hyper IDE and/or Phosphorus Five. 149 | 150 | ### Adding your own shell snippets 151 | 152 | You can also extend Hyper IDE with custom shell snippets, which allows you to evaluate some piece of bash 153 | code, from within the context of a folder. This is done by adding your shell bash file 154 | inside [this folder](hyper-ide?path=/modules/hyper-ide/helpers/shell-snippets/). These are the shell snippets 155 | the user can select from as he clicks the _"Open terminal window"_ plugin button for a folder. 156 | 157 | Such snippets can be shell commands that checks in your code to a Term Service server for instance, or starts 158 | a build process. All such shell snippets will be executed from within the context of the currently selected 159 | folder from your file explorer. Below is a screenshot of which snippets are available out of the box. 160 | 161 | https://phosphorusfive.files.wordpress.com/2018/03/shell-snippets-screenshot.png 162 | 163 | **Notice**, if you add such shell snippets extensions, you should take care of not loosing your files 164 | as you upgrade Hyper IDE and/or Phosphorus Five. 165 | 166 | **Notice** - Instead of adding your own template shell snippets, you can also directly execute a _".sh"_ file. 167 | This allows you to create for instance compiler scripts, and similar types of scripts, as an integral part 168 | of your projects, for then to evaluate them directly by opening up the file, and evaluating it due to 169 | the _"execute shell snippet file"_ plugin, that's distributed directly out of the box with Hyper IDE. You can 170 | also easily create your own plugin, which doesn't have to be a part of Hyper IDE, but which creates a plugin 171 | Active Event to evaluate _".bat"_ files, if you're on a windows system. 172 | 173 | ### Extending the general toolbars 174 | 175 | Even though you'd probably most of the times want to create specific file types of extension toolbar buttons, 176 | you can also modify the default toolbar buttons, by adding your button/widget into the correct folder 177 | inside of [this folder](/hyper-ide?path=/modules/hyper-ide/helpers/toolbars/). Here you can see all the different 178 | toolbar sections, encapsulated inside of their correct folders, allowing you to globally extend your toolbar 179 | as you see fit. 180 | 181 | **Notice**, if you add such toolbar extensions, you should take care of not loosing your files 182 | as you upgrade Hyper IDE and/or Phosphorus Five. 183 | 184 | -------------------------------------------------------------------------------- /startup/plugins/hyper-ide.folder-plugins.create-module.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Creates the __[hyper-ide.folder-plugin.create-module]__ Active Event. 3 | */ 4 | 5 | /* 6 | * Creates our _"create new module plugin"_ button. This button is only visible 7 | * if the currently selected object in your file explorer is the _"/modules/"_ folder. 8 | * 9 | * When this button is clicked, it will guide the user through a wizard, allowing 10 | * him to create a new module, from a list of _"template modules"_, which you 11 | * can find in the _"/modules/hyper-ide/helpers/app-templates/"_ folder. 12 | */ 13 | create-event:hyper-ide.folder-plugin.create-module 14 | 15 | /* 16 | * Verifying we're in our "/modules/" folder, and if not, returning early. 17 | * 18 | * This is to prevent this plugin to be visible in any other folders than our "/modules/" folder. 19 | */ 20 | hyper-ide.file-explorer.get-active-item 21 | if:x:/@hyper-ide.file-explorer.get-active-item?value 22 | !=:/modules/ 23 | return 24 | 25 | /* 26 | * Returning plugin button to caller. 27 | */ 28 | return 29 | button 30 | innerValue:@"" 31 | title:Create new module 32 | events 33 | 34 | /* 35 | * "API" event for allowing other parts of the system to initiate 36 | * "app creation process". 37 | * 38 | * Requires [app-type]. 39 | */ 40 | hyper-ide._plugins.create-app 41 | 42 | /* 43 | * Sanity checking arguments. 44 | */ 45 | micro.lambda.contract.min:x:/.. 46 | app-type:string 47 | 48 | /* 49 | * Simply raising [onclick] for button, for then to parametrise select 50 | * drop down list, with whatever [app-type] was specified. 51 | */ 52 | p5.web.widgets.ajax-events.raise:x:/../*/_event?value 53 | onclick 54 | p5.web.widgets.find-like:hyper-ide-new-module-template-type 55 | value:/{0}.hl 56 | :x:/../*/app-type?value 57 | get-widget-property:x:/-/*/*?value 58 | value 59 | set-widget-property:hyper-ide-new-module-template-type 60 | value:x:/@get-widget-property/*/*?value 61 | 62 | onclick 63 | 64 | /* 65 | * Showing a modal window, asking user to supply a name for his project. 66 | */ 67 | create-widgets 68 | micro.widgets.modal:hyper-ide-new-module-modal 69 | widgets 70 | h3 71 | innerValue:Create new module 72 | p 73 | innerValue:@"Provide a name for your module, such as foo-bar, which also will become its URL. 74 | Then choose a template type for your app." 75 | micro.widgets.wizard-form 76 | text 77 | info:Name 78 | .data-field:name 79 | onkeydown:@"if (event.keyCode == 13) {p5.$('hyper-ide-create-module-button').raise('onclick');return false;}" 80 | oninit 81 | 82 | /* 83 | * Setting initial focus to "name" textbox. 84 | */ 85 | micro.page.set-focus:x:/../*/_event?value 86 | 87 | select:hyper-ide-new-module-template-type 88 | info:Type 89 | .data-field:type 90 | onchange 91 | 92 | /* 93 | * Re-databinding settings for module type. 94 | */ 95 | hyper-ide.new-module.template-type-changed 96 | 97 | oninit 98 | 99 | /* 100 | * Creating one option element for each app-template that exists in installation. 101 | */ 102 | list-files:@IDE/helpers/app-templates/ 103 | filter:.hl 104 | for-each:x:/@list-files/*?name 105 | split:x:/@_dp?value 106 | =:/ 107 | =:. 108 | if:x:/@split/0/-2?name 109 | =:hello-world 110 | add:x:/..for-each/*/create-widget 111 | src:selected 112 | create-widget 113 | parent:x:/../*/_event?value 114 | element:option 115 | value:x:/@_dp?value 116 | innerValue:x:/@split/0/-2?name 117 | 118 | /* 119 | * Invoking our "databind template type" event initially. 120 | */ 121 | hyper-ide.new-module.template-type-changed 122 | 123 | events 124 | 125 | /* 126 | * Invoked when the template type is changed. 127 | * 128 | * Rebinds the template options widget. 129 | */ 130 | hyper-ide.new-module.template-type-changed 131 | 132 | /* 133 | * Retrieving the select list's selected value, and databinding 134 | * the "template type settings" accordingly. 135 | * 136 | * But first, clearing any previously created additional settings, for 137 | * previously selected template types. 138 | */ 139 | clear-widget:hyper-ide-new-module-template-settings 140 | get-widget-property:hyper-ide-new-module-template-type 141 | value 142 | load-file:x:/@get-widget-property/*/*?value 143 | if:x:/@load-file/*/*/.settings 144 | 145 | /* 146 | * Selected template type contains additional settings. 147 | */ 148 | add:x:/./*/create-widget/*/widgets 149 | src:x:/@load-file/*/*/.settings/* 150 | create-widget 151 | parent:hyper-ide-new-module-template-settings 152 | widgets 153 | 154 | container:hyper-ide-new-module-template-settings 155 | 156 | div 157 | class:right 158 | widgets 159 | div 160 | class:strip 161 | widgets 162 | button:hyper-ide-create-module-button 163 | innerValue:Create 164 | onclick 165 | 166 | /* 167 | * Creating a new default "empty module", with all the relevant base files, 168 | * necessary to tie things up. 169 | * 170 | * But first verifying the name of the module is something we can accept. 171 | */ 172 | micro.form.serialize:hyper-ide-new-module-modal 173 | match:x:/@micro.form.serialize/*/name?value 174 | src:regex:/^[-a-z_0-9]{3,}$/ 175 | if:x:/@match/*?count 176 | =:int:0 177 | 178 | /* 179 | * Not a valid module name, informing user, and returning early. 180 | */ 181 | micro.windows.info:Only use a-z, 0-9, _ or - characters, and use at least 3 characters. 182 | class:micro-windows-info warning 183 | return 184 | 185 | /* 186 | * Checking if a module with the same exists from before. 187 | */ 188 | if 189 | fetch:x:/0/0?value 190 | folder-exists:/modules/{0}/ 191 | :x:/@micro.form.serialize/*/name?value 192 | 193 | /* 194 | * Not a valid module name, informing user, and returning early. 195 | */ 196 | micro.windows.info:That module exists from before 197 | class:micro-windows-info warning 198 | return 199 | 200 | 201 | /* 202 | * Invoking file responsible for creating user's selected module type, 203 | * which depends upon which application template type user has selected. 204 | */ 205 | add:x:/+ 206 | src:x:/@micro.form.serialize/*(!/type) 207 | micro.evaluate.file:x:/@micro.form.serialize/*/type?value 208 | 209 | 210 | /* 211 | * Evaluating startup file, if it exists. 212 | */ 213 | if 214 | fetch:x:/0/0?value 215 | file-exists:/modules/{0}/install.hl 216 | :x:/@micro.form.serialize/*/name?value 217 | micro.evaluate.file:/modules/{0}/install.hl 218 | :x:/@micro.form.serialize/*/name?value 219 | if 220 | fetch:x:/0/0?value 221 | file-exists:/modules/{0}/startup.hl 222 | :x:/@micro.form.serialize/*/name?value 223 | micro.evaluate.file:/modules/{0}/startup.hl 224 | :x:/@micro.form.serialize/*/name?value 225 | 226 | 227 | /* 228 | * Deleting modal window, refreshing treeview, and informing user. 229 | */ 230 | delete-widget:hyper-ide-new-module-modal 231 | micro.windows.info:Your module was successfully created 232 | class:micro-windows-info success 233 | micro.widgets.tree.refresh-items:hyper-ide-folder-tree-browser 234 | items 235 | /modules/ 236 | 237 | /* 238 | * Immediately start editing our "launch.hl" file, which we'll need to 239 | * to by first selecting module's folder (to expand it), and then selecting 240 | * module's "launch.hl" file. 241 | */ 242 | add:x:/+/*/items 243 | src:/modules/{0}/ 244 | :x:/@micro.form.serialize/*/name?value 245 | micro.widgets.tree.toggle-items:hyper-ide-folder-tree-browser 246 | force-expand:true 247 | items 248 | add:x:/+/*/items 249 | src:/modules/{0}/launch.hl 250 | :x:/@micro.form.serialize/*/name?value 251 | micro.widgets.tree.select-items:hyper-ide-folder-tree-browser 252 | items 253 | 254 | button 255 | innerValue:Close 256 | onclick 257 | 258 | /* 259 | * Simply deletes modal widget. 260 | */ 261 | delete-widget:hyper-ide-new-module-modal 262 | -------------------------------------------------------------------------------- /helpers/create-skin.hl: -------------------------------------------------------------------------------- 1 | /* 2 | * Guides the user through the process of creating a new Micro skin CSS file. 3 | * 4 | * Uses a _"wizard"_ modal widget to help user through the process of creting 5 | * a new _"skin"_ CSS file for Micro. It does this by extracting all CSS variables 6 | * in the main _"micro.css"_ file between the comments _"/* VARIABLES_BEGIN *\/"_ 7 | * and _"/* VARIABLES_END *\/"_", and allows the user to fill in these values himself. 8 | */ 9 | load-file:@MICRO/media/micro.css 10 | 11 | 12 | 13 | 14 | 15 | /* 16 | * Finding all CSS variables that are available to us. 17 | */ 18 | split:x:/@load-file/*?value 19 | =:":root" 20 | split:x:/@split/2?name 21 | =:{ 22 | =:} 23 | split:x:/@split/1?name 24 | =:*/ 25 | split:x:/@split/1?name 26 | =:"\r\n" 27 | .vars 28 | for-each:x:/@split/*?name 29 | trim:x:/@_dp?value 30 | chars:"\t -;" 31 | split:x:/@trim?value 32 | =:":" 33 | trim:x:/@split/1?name 34 | chars:"; \t\r\n" 35 | add:x:/@.vars 36 | src:"{0}:{1}" 37 | :x:/@split/0?name 38 | :x:/@trim?value 39 | set:x:/@.vars/*/= 40 | 41 | 42 | 43 | 44 | /* 45 | * Applying all CSS variables into our tab widget. 46 | */ 47 | .no:int:1 48 | while:x:/@.vars/* 49 | eval-x:x:/+/*/*/*/name 50 | add:x:/../*/create-widgets/*/*/*/micro.widgets.tab 51 | src 52 | view 53 | name:Settings {0} 54 | :x:/@.no?value 55 | widgets 56 | apply:x:/../*/create-widgets/*/*/widgets/*/micro.widgets.tab/0/-/*/widgets 57 | src:x:/@.vars/*/[0,7] 58 | template 59 | div 60 | class:strip fill 61 | widgets 62 | label 63 | class:description-9 64 | {innerValue}:x:?name 65 | input 66 | type:text 67 | {value}:x:?value 68 | {.data-field}:x:?name 69 | set:x:/@.no?value 70 | +:x:/@.no?value 71 | _:1 72 | set:x:/@.vars/*/[0,7] 73 | 74 | 75 | 76 | 77 | 78 | /* 79 | * Adding the "preview" view. 80 | */ 81 | add:x:/../*/create-widgets/**/micro.widgets.tab 82 | src 83 | view 84 | name:Preview 85 | widgets 86 | div 87 | oninit 88 | 89 | /* 90 | * Injecting a style tag overriding the default skin 91 | * with whatever settings user supplied. 92 | * 93 | * First creating our skin's CSS. 94 | */ 95 | micro.form.serialize:hyper-ide-create-skin-wizard-modal 96 | .css:@"" 106 | :x:/@.css?value 107 | create-widgets 108 | text:x:/@.css?value 109 | parent:x:/../*/_event?value 110 | 111 | 112 | widgets 113 | 114 | /* 115 | * Then illustrating samples of most of our widgets, to 116 | * simply show off how the skin will look like. 117 | */ 118 | div:hyper-ide-preview-widget 119 | class:hyper-ide-preview-skin background air-left air-right air-bottom air-inner 120 | widgets 121 | h2 122 | innerValue:Header H2 123 | p 124 | innerValue:@"Some paragraph with inline code and 125 | a hyperlink and a strong and emphasized string." 126 | pre 127 | innerValue:@"Some pre formatted 128 | piece of text" 129 | div 130 | class:strip fill 131 | widgets 132 | label 133 | innerValue:Label 134 | input 135 | type:text 136 | placeholder:Some piece of input ... 137 | label 138 | widgets 139 | span 140 | innerValue:Check 141 | input 142 | type:checkbox 143 | div 144 | class:strip fill 145 | widgets 146 | label 147 | innerValue:Disabled 148 | input 149 | type:text 150 | disabled 151 | value:Some piece of input 152 | label 153 | widgets 154 | span 155 | innerValue:Check 156 | input 157 | disabled 158 | checked 159 | type:checkbox 160 | label 161 | widgets 162 | span 163 | innerValue:Radio button 1 164 | input 165 | type:radio 166 | name:hyper-ide-preview-rdo 167 | label 168 | widgets 169 | span 170 | innerValue:Radio button 2 171 | input 172 | type:radio 173 | name:hyper-ide-preview-rdo 174 | label 175 | widgets 176 | span 177 | innerValue:Disabled radio button 178 | input 179 | type:radio 180 | disabled 181 | name:hyper-ide-preview-rdo 182 | div 183 | class:shaded rounded air-inner bg 184 | innerValue:

Shaded and rounded div with bg

185 | div 186 | class:air-inner success 187 | innerValue:

Success div

188 | div 189 | class:warning air-inner 190 | innerValue:

Warning div

191 | button 192 | class:air-right 193 | innerValue:Some button 194 | button 195 | class:toggled air-right 196 | innerValue:Toggled button 197 | button 198 | disabled 199 | innerValue:Disabled button 200 | 201 | 202 | 203 | 204 | 205 | /* 206 | * Creating a modal widget, with one textbox for each variable. 207 | */ 208 | create-widgets 209 | micro.widgets.modal:hyper-ide-create-skin-wizard-modal 210 | class:micro-widgets-modal large 211 | widgets 212 | h3 213 | innerValue:Skin wizard 214 | micro.widgets.tab 215 | div 216 | class:strip right air-top 217 | widgets 218 | button 219 | innerValue:Generate 220 | onclick 221 | 222 | /* 223 | * Creating (another) modal widget to ask user for a name for his new skin. 224 | */ 225 | create-widgets 226 | micro.widgets.modal:hyper-ide-create-skin-wizard-modal-name 227 | widgets 228 | h3 229 | innerValue:Provide a name for your skin 230 | div 231 | class:fill strip 232 | widgets 233 | label 234 | innerValue:Name 235 | input:hyper-ide-new-skin-name 236 | type:text 237 | placeholder:Name for your skin ... 238 | onkeydown:@"if (event.keyCode == 13) {p5.$('hyper-ide-save-new-skin').raise('onclick');return false;} else if (event.keyCode == 27) {p5.$('hyper-ide-save-new-skin-cancel').raise('onclick');return false;}" 239 | oninit 240 | 241 | /* 242 | * Setting initial focus to textbox. 243 | */ 244 | micro.page.set-focus:x:/../*/_event?value 245 | 246 | div 247 | class:right strip 248 | widgets 249 | button:hyper-ide-save-new-skin 250 | innerValue:Save 251 | onclick 252 | 253 | /* 254 | * Serializing form and saving to a skin file. 255 | * 256 | * Notice, to avoid serializing preview widgets, we delete them first. 257 | * 258 | */ 259 | delete-widget:hyper-ide-preview-widget 260 | micro.form.serialize:hyper-ide-create-skin-wizard-modal 261 | 262 | /* 263 | * Building CSS. 264 | */ 265 | .css:@"/* CSS variables */ 266 | :root {" 267 | for-each:x:/@micro.form.serialize/* 268 | set:x:/@.css?value 269 | src:"{0}--{1}:{2};" 270 | :x:/@.css?value 271 | :x:/@_dp/#?name 272 | :x:/@_dp/#?value 273 | set:x:/@.css?value 274 | src:"{0}}}" 275 | :x:/@.css?value 276 | 277 | /* 278 | * Retrieving and sanity checking filename. 279 | */ 280 | get-widget-property:hyper-ide-new-skin-name 281 | value 282 | match:x:/@get-widget-property/*/*?value 283 | src:regex:/^[-_a-z0-9]+$/i 284 | if:x:/@match/*?count 285 | =:int:0 286 | or:x:/@match/0?name 287 | =: 288 | 289 | /* 290 | * Not a legal name for a file. 291 | */ 292 | micro.windows.info:Not a legal name for your skin 293 | class:micro-windows-info warning 294 | return 295 | 296 | /* 297 | * Saving skin file. 298 | */ 299 | save-file:@MICRO/media/skins/{0}.css 300 | :x:/@get-widget-property/*/*?value 301 | src:x:/@.css?value 302 | 303 | /* 304 | * Deleting both modal widgets. 305 | */ 306 | delete-widget:hyper-ide-create-skin-wizard-modal-name 307 | delete-widget:hyper-ide-create-skin-wizard-modal 308 | 309 | /* 310 | * Refreshing tree view's active folder, which should be the skin folder. 311 | */ 312 | hyper-ide.file-explorer.refresh-active-folder 313 | 314 | /* 315 | * Opening up our CSS file for editing. 316 | */ 317 | hyper-ide.file-explorer.select-path:/modules/micro/media/skins/{0}.css 318 | :x:/@get-widget-property/*/*?value 319 | 320 | button:hyper-ide-save-new-skin-cancel 321 | innerValue:Cancel 322 | onclick 323 | 324 | /* 325 | * Simply deleting modal widget. 326 | */ 327 | delete-widget:hyper-ide-create-skin-wizard-modal-name 328 | 329 | button 330 | innerValue:Cancel 331 | onclick 332 | 333 | /* 334 | * Simply deleting modal widget. 335 | */ 336 | delete-widget:hyper-ide-create-skin-wizard-modal 337 | --------------------------------------------------------------------------------