Summarized using AI

How I Built My Code Editor in Ruby

Andy Maleh • July 06, 2022 • Montréal, Canada • Talk

In this presentation titled "How I Built My Code Editor in Ruby," Andy Maleh showcases Gladiator, a code editor he developed entirely in Ruby. Gladiator offers several features including syntax highlighting for over 30 programming languages, split-pane editing, a file explorer, command shortcuts, and multi-project support. Maleh explains his motivations for creating the editor, highlighting Ruby's advantages such as its object-oriented nature, dynamic typing, and high expressiveness.

Key points discussed in the talk include:

- Architecture and Patterns: Maleh describes using architectural patterns such as Model-View-Controller (MVC) and Model-View-Presenter (MVP) to structure the editor efficiently. He emphasizes the importance of component decomposition and how these patterns facilitate clean separation of functionalities within the application.

- Development Process: The initial development was a personal challenge for Maleh, as he limited himself to using only the built-in text editing tools available in the terminal. He started with simple features and incrementally developed Gladiator over three years, improving it through real-use feedback.

- Feature Overview: During the demo, he showcases various functionalities including

- Syntax highlighting

- File tree navigation

- Tab support

- Undo/redo functionality

- Code execution

- External file system monitoring

He employs the Glimmer DSL for SWT to implement these features in Ruby, providing a clear interface for GUI design and functionality.

- Reflections and Future Work: Maleh discusses challenges such as syntax highlighting, which he accomplished through the Rouge library, and outlines potential future enhancements like implementing file content search and better multi-platform support. He encourages attendees to open issues or contribute to the project to solidify and expand its capabilities.

Overall, the presentation aims to equip attendees with a foundational understanding of building a code editor in Ruby, emphasizing incremental development and leveraging modern programming paradigms to enhance productivity and maintainability.

How I Built My Code Editor in Ruby
Andy Maleh • July 06, 2022 • Montréal, Canada • Talk

Gladiator is a code editor that was built completely in Ruby. It supports syntax highlighting for over 30 programming languages, split pane, file name lookup, a variety of keyboard shortcuts, undo/redo, find and replace, line jumping, monitoring external file system changes, ignoring uneditable files, expanding to fill the screen, running Ruby code, remembering the last open files, and multi-project support. In fact, I have been using Gladiator for all my code editing needs since May of 2020.

In this talk, I will present Gladiator's features, and then dig into the implementation of every feature in Ruby, covering things like the Model-View-Controller and Model-View-Presenter architectural patterns, how to build custom widgets, how to implement file editing commands, and how to support undo/redo.

Attendees should walk out of this talk with rudimentary knowledge of how to build a code editor in Ruby.

Related links:

Gladiator: https://github.com/AndyObtiva/glimmer-cs-gladiator
Glimmer DSL for SWT: https://github.com/AndyObtiva/glimmer-dsl-swt
Glimmer Process: https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md

Montreal.rb Meetup July 2022

00:00:00.179 okay so uh the title of the talk tonight is how I built my code editoring Ruby
00:00:06.600 so um let's go get started with this question right away how did I build my code
00:00:13.920 editor in Ruby so yes I used Ruby as a programming language using Jr Ruby
00:00:22.500 I applied object oriented design with abstractions like file and
00:00:27.840 directory I applied architectural patterns like MVC and MVP
00:00:34.260 I applied design patterns like command pattern composite adapter and observer
00:00:41.340 I use domain specific languages like the glimmer GUI DSL
00:00:47.879 I decomposed software modules meaning components or custom widgets when
00:00:54.120 building GUI I reused ruby gems Ruby libraries like
00:00:59.760 glimmer DSL swt file Watcher and clipboard and That's all folks I give you the
00:01:07.200 answer I'll go home now just kidding that was just a preview of
00:01:13.020 The Talk hang on for more okay so about myself I have a Bachelor
00:01:19.920 of Science and computer science from McGill University in Montreal uh uh and master of science in software
00:01:25.920 engineering from DePaul University Chicago like Mateo mentioned I've spoken at a
00:01:32.880 number of conferences uh I've recently won the fukuokai Ruby 2022 special award uh by mats the
00:01:40.860 creator of Ruby and uh I work as a senior full stack
00:01:46.439 developer at lexap so uh why build that code editor in Ruby
00:01:53.100 so let's start with the why the first reason is Ruby is a great language
00:01:58.920 it's object oriented it's dynamically typed
00:02:06.299 it's inspired by lisp Small Talk Pearl Python and basic
00:02:11.640 so that means it's got I mean small talk is one of the first languages that
00:02:17.520 demonstrated uh very a very high level of object oriented programming so everybody has some of the best style of
00:02:24.660 object-oriented programming in the world so lisp demonstrated how to build embedded dsls like embedded languages
00:02:31.500 within list in order to become a lot more productive at building Ruby has the
00:02:38.420 Pearl has a lot of good uh terminal or command line support especially for
00:02:44.940 opening files and running commands and stuff like that so Ruby has that python
00:02:50.400 has nice syntax that Ruby inherits uh some of and basic also is known for
00:02:55.860 being very approachable by non-programmers so Ruby has that as well
00:03:01.280 Ruby as a result supports meta programming and embedded dsls like I
00:03:06.720 mentioned just like lisp so it's very expressive it's highly
00:03:12.180 expressive and it gives us very maintainable code so that means it's very productive like
00:03:18.239 rails rails is famous for being one of the most productive Frameworks for web development
00:03:23.580 in Old programming languages nowadays um a second reason is I'm a senior
00:03:30.060 software engineer I have about 19 years of software engineering experience I've
00:03:35.640 also I mean I've been programming since I was a kid even before I mean I have a 19 years of professional experience but
00:03:40.920 I've been programming since I was a child so I have over 34th picky almost I
00:03:46.500 mean not 40 but over 30 years of experience in programming so why would I not build my own code editor I'm
00:03:53.640 proficient in requirements engineering meaning how to take requirements and turn them into
00:03:59.000 analysis and design that results in software um professions and object oriented
00:04:05.280 programming proficient and Architectural patterns design patterns domain specific
00:04:10.560 languages writing highly maintainable code um automated testing so I mean I I one
00:04:19.680 day I woke up and I'm like why why why am I using somebody else's editor why not build my own editor and the other
00:04:26.040 thing that bothered me was why are all editors not written in Ruby Ruby is one
00:04:31.320 of the best programming languages in the world editors code editors should be within Ruby too
00:04:37.380 so that's how Gladiator was born it was an open source project that was
00:04:43.320 born out of the idea of exploring Ruby in order to build my own code editor so let's start by doing a demo of Gladiator
00:04:51.120 so I'm going to get out of the presentation mode and launch it this is the icon Gladiator
00:05:00.840 so it just gives me this button that says open project then I can select a project like Like Gladiator itself
00:05:11.699 there it is so um basically it it has a syntax
00:05:18.479 highlighting for over 30 programming languages um and what you're seeing here is Ruby
00:05:23.759 codes and this is the code of gladiator itself uh it's got find and replace support so
00:05:30.180 I mean I can use any keyword and look for occurrences of it like like that for
00:05:35.639 example and I can do replace I can do it make it case sensitive or not or not I can look up files so if I want to look
00:05:42.539 up a model I type model and it gives you know all the models and then like navigate to this model that directory
00:05:48.120 model um I can I have a tree a file tree
00:05:56.639 navigation on the left side over here it's a file tree explorer that lets me navigate all that
00:06:02.400 the elements of the project so it's got binary scripts for launching
00:06:07.680 the app it's got configuration icons images most of the logic for this
00:06:13.919 Library art is under lip and it's got views models
00:06:19.560 um a launcher script and the main entry points of the project
00:06:26.940 um what are some other features uh oh yeah one cool feature is I can open a like a scratch pad
00:06:32.639 and for example type in a script here and say let's just say
00:06:38.479 text hello world label
00:06:43.740 world and um
00:06:49.500 I can run it unfortunately Stick Run so what happens at demos and uh yeah so
00:06:58.680 I'm supposed to be able to run a ruby script I don't know why it's not running but I'll leave that for another time but
00:07:04.800 uh let me open another project so I can open multiple projects
00:07:13.819 and uh this is a ruby script let me try to run this one okay cool this one ran
00:07:18.840 so this is another app that it's just a demo app of how to use a syntax
00:07:23.880 highlighted text editor it's called hello code text and I just opened it
00:07:29.520 um and decoded the app is here the stat that I just opened
00:07:34.620 so let's get back to the main project close this
00:07:42.419 um yeah I mean I can right click a file here and delete it refresh the tree create a new directory
00:07:48.720 a new file I can do copy paste and then we have a menu on top
00:07:54.419 uh open scratch Pad open project uh standard edit menu with the undo redo
00:08:00.479 copy cup paste um oh yeah this is cool actually split pane so I can split
00:08:06.900 split the pain vertically or horizontally actually I can also use the
00:08:12.720 keyboard shortcut so I can do this this is good because then I can open tests for example like specs
00:08:20.460 so let's just open this back on this side that way I can put this back on one side
00:08:26.759 and there it is the file is on the file
00:08:33.120 model is on the left side in the file spec us on the right side so it helps me
00:08:38.159 be more productive um but there are many other shortcuts like
00:08:44.039 I can yeah I just showed you this I can minimize the coding area to basically
00:08:50.160 hide all of those extraneous panes so and then I can even focus on one of the
00:08:56.040 two sides so I just focused on the test side and I can also close it and come back to
00:09:01.620 this side and and come back to this or I can just open the file uh find and replace alone
00:09:08.820 and I can use the mouse to like do this or yeah so um it's very basic functionality
00:09:17.399 for what a code editor is um I think I pretty much covered everything
00:09:23.040 I mean you guys thought tabs so I have multiple tabs for opening multiple files uh when I'm navigating a file I get some
00:09:30.839 sort of analytics here about like I mean it's not exactly analytics more about what is the character position what is
00:09:37.019 the line number Etc uh I can jump to a line like without hundreds or
00:09:43.200 hey there so it's a lot it's very basic coding functionality I built this in the
00:09:49.140 year 2000 2020 story um I've been using this for about three
00:09:55.019 years now as the main editor for all of my all of my work open source or closed
00:10:00.899 Source um so it's good enough for all my personal needs
00:10:07.079 um and I'll talk more about how I got into that one
00:10:12.600 any questions before what library do you use to render the UI
00:10:19.620 I'll I'll get to that one I'll answer that in a bit any other questions is it
00:10:25.380 uh across OS if I'm on Linux uh yes this one's on Windows 2 and it runs on Linux
00:10:31.079 with some hiccups okay so it's designed primarily for Mac because that's where I use it the most
00:10:37.320 but I've been able to use it on Windows Analytics as well that's pretty cool that's because of whatever yes thanks
00:10:45.959 so um okay so what is the Gladiator software
00:10:51.180 architecture before we dig into the code and the design and all of that what is the general architecture uh so it's a
00:10:57.600 it's a GUI app it's by GUI our main graphical user interface so uh Graphics
00:11:03.300 or interface apps uh our pop usually in general use the MVC pattern
00:11:10.279 which came from Small Talk the Small Talk programming language uh because
00:11:15.839 it's uh it provides a very clean separation of responsibilities so usually uh in a GUI app you have a
00:11:22.440 screen that gives you a sort of the user interface with items on it
00:11:27.839 and then you interact with the screen using a control device devices like The Mouse and the keyboard
00:11:34.260 so that's the controller part of MVC so you have the view which gives you the uh
00:11:39.779 the screen you have the controller which lets you control the app with the keyboard and mouse
00:11:44.880 and then the model is basically the business model behind that app that you're building it's basically how do
00:11:51.060 you uh what are the concepts of the app uh so I mean in Gladiator obviously some
00:11:57.060 of the concepts that are very obvious are we have a text editor uh we have text editor tabs we have a file explorer
00:12:05.459 tree etc etc I'm going to get into that in a moment
00:12:10.519 I'm also applying something called the MVP pattern which is a variation on MVC
00:12:16.459 that makes the controller a presenter so the controller is not only about
00:12:21.600 controlling um making changes uh through the keyboard and mouse to the to the view into the
00:12:28.860 model of things that are recorded in the model but also it's about observing the model for changes and making them get
00:12:36.360 reflected in the view automatically and that's done using something called Data binding or bi-directional data binding
00:12:42.839 data binding lets you basically declaratively bind certain elements of the view into certain properties on the
00:12:50.760 models I'll show you quote examples of that
00:12:56.060 thirdly the app is decomposed into software and modules AKA components AKA
00:13:03.060 custom widgets so Gladiator itself is a component
00:13:08.339 meaning if I want I can embed the entirety of gladiator into another app and I can bring it up when needed just
00:13:14.339 to edit some code but also it's decomposed into smaller
00:13:19.380 components like text editor file explorer tree file lookup list
00:13:25.019 the file edit menu the Gladiator menu bar and the progress shell
00:13:32.600 one thing I want to note is these are the general architectural Concepts behind building
00:13:38.279 Gladiator but it's not in any way or shape or form completely perfectly and
00:13:44.399 cleanly adhering to them the Code you know doesn't it's not a completely clean
00:13:50.160 MVC but that is the general concept that I built Gladiator around
00:13:57.360 as far as the software development process what happened is I basically made this
00:14:02.880 challenge with myself of not using any Editor to build Gladiator except what
00:14:08.100 comes built in into the operating system and on the Mac or Linux in the terminal I have Vim so I only used Vim to build
00:14:16.560 Gladiator initially secondly I started very very small and built features incrementally and I
00:14:23.639 started with the smallest thing possible that would enable me to upgrade myself from them to something better so that's
00:14:31.079 what the third step is and then I started eating my own dog food and using Gladiator to build more Gladiator
00:14:36.660 features so initially I had nothing but the text editor I didn't even have tabs I had just the text editor and I might
00:14:44.339 have had the file three that's it eventually I added a file lookup list
00:14:49.440 and then I added tap support and then I added split pane etc etc uh and that's how I'm continuing
00:14:55.980 development on this project for for three years I mean I touch it once every few months I'm not working on it every
00:15:02.579 day or anything except in the beginning I might have worked on it every day for day or two in the beginning uh but now I
00:15:08.699 touch it every few months and whenever I need a new feature I upgrade Gladiator with a new feature
00:15:15.720 as far as the software development process I use something called the glimmer process which I came up with when I built another open source Library
00:15:22.199 called glimmer it's simply made up of seven guidelines to pick and choose as necessary it's not very dogmatic you can
00:15:30.540 rule out some guidelines if you want or not apply everything and you don't have to follow an order
00:15:36.740 it's just a summary of all my learnings from my software engineering work as
00:15:42.180 well as my masters in software engineering so I mean there's a requirements Gathering phase usually in any app meaning writing down a list of
00:15:49.079 tasks or features that you want it doesn't have to be complete complete but you need to have something to start
00:15:54.899 with uh and usually you do prioritize prioritization of this list uh you need
00:16:01.139 a sort of a general architecture and software design uh an initial release plan meaning what do you want to release
00:16:07.139 for version 0.0.1 and then what do I want to release for the MVP the very first uh
00:16:13.500 beta Alpha release and then the very first Beta release Etc so you need some sort of a release plan
00:16:19.980 you need small releases so no release took me more than I would say more than
00:16:25.139 two weeks per release and to be honest in general they were usually two days that may be produced
00:16:37.440 this case so I can tell myself what I don't like and what I like uh and automated tests uh I did not so I
00:16:44.459 did not write a lot of automated tests this project was more I'm using it every
00:16:49.500 day so that is the test I don't need an automated test but this is a good example of why here I I don't recommend
00:16:55.199 to be dogmatic about any of those guidelines but I do have a few automated tests there were a few parts that were a
00:17:00.720 bit buggy that I ended up resolving the bugs with by running tests for them any questions before I move on
00:17:09.179 yeah do you ever open it up to outside intestines I did yeah I have a few users
00:17:16.740 for the project and they've reported some bugs to me in the past mostly what to do with Windows because I don't use
00:17:22.380 it on Windows much maybe not just bugs but maybe I'll sold potential features or improvements
00:17:30.299 um well I'm hoping we'll have a lot more users after today yeah
00:17:38.280 and the refactoring of course uh that's a very important Point uh every like
00:17:44.760 often I find a feature in a very big blob of code but then a month or two later when I try to add more features on
00:17:51.360 top of that becomes very difficult so I end up refactoring and however I follow the school of like I only refactor as
00:17:58.080 much as needed to facilitate future work I don't try to immediately refactor it into the perfect structure so I refactor
00:18:06.120 is needed only but that's been always always important refactoring
00:18:12.179 um I mean I refactor almost every release so uh let's start digging into the
00:18:18.120 implementation of gladiator features so uh first let's get into the file tree navigation
00:18:26.820 so um I have the code over here
00:18:32.700 um the file tree navigation is basically this part on the top on the bottom left
00:18:39.960 um it's simply a tree structure of the directories of the project that I opened so in this case the project that I
00:18:46.080 opened shows up over here that formed an absolute path of it it's basically uh
00:18:51.840 you know whatever some absolute path code and then Slimmer uh glimmer Dash CS
00:18:57.299 Dutch Gladiator which is the name the official name of this project so
00:19:03.960 uh how did I build this part so this part has been decomposed into its own component eventually and right now it's
00:19:10.380 called the file explorer tree so we can just look at the code of file exploratory to know how that that is
00:19:15.539 implemented so I'm using uh glimmer as the user interface Library
00:19:20.840 glimmer DSL for swt lets you use the swt
00:19:27.120 library which is the same library that Eclipse IDE is built with so I'm using the same technology that was used to
00:19:33.419 build the Eclipse IDE in order to build this editor and that technology is
00:19:38.460 written in Java so in order to use Java Java libraries from Ruby you have to use
00:19:43.500 Jr Ruby instead of C Ruby so I'm using jruby as well um so that's how I've been able to
00:19:48.660 leverage swt and I've leveraged it using the glimmer DSL for it which gives you a
00:19:55.500 ruby way of dealing with swt as opposed to the javaway the Ruby way gives you a
00:20:01.320 DSL that maps to the structure of the of the graphical user interface and usually
00:20:06.900 whenever you build a component you need to extend if you're building a custom widget custom components you need
00:20:13.620 to include this glimmer column called an UI phone call and custom widget module or mixin
00:20:21.440 and after that you declare the body inside this body method not method it's
00:20:27.539 actually a body sort of structure so body lets you build
00:20:33.659 the graphical user interface as a hierarchical structure so think of this as the Ruby version of HTML HTML lets
00:20:41.039 you open a body and nest in it divs and then within the dips you can Nest paragraphs and within the paragraphs you
00:20:47.100 can Nest labels if you want and input text Fields Etc this is the same thing
00:20:52.559 done in Ruby using a DSO um so here the the rules of Ruby style
00:20:58.620 guides change a bit you try to think if it's declaratively not imperatively so
00:21:05.280 when you're writing imperative code in Ruby and anything you have a method that you're invoking when you pass it a Blog
00:21:11.880 usually say do end and because you're being imperative you're saying okay this is the method uh
00:21:18.000 print and then do and within the do maybe you want to do extra work before
00:21:24.120 printing some text and then end that's because you're writing imperative code here I'm writing declarative code and
00:21:30.600 I'm taking advantage of the fact that in Ruby I can write dsls and DSL is basically a language embedded within
00:21:37.020 Ruby that lets me write graphically or interface code so I have a body
00:21:42.539 uh within the body of this component the first thing that appears is a tree and this is the tree that you guys are
00:21:48.960 seeing over here and then within within the tree so whenever you open a uh so usually I mean
00:21:55.500 just to give you an example an HTML I would have done it like this I would have done uh body
00:22:02.340 and then within that I would have done there is no tree component in HTML but if there were
00:22:08.100 that's what it would have been and that's how I would have done it the same exact code in Ruby would do it like
00:22:14.280 this he would say this uh you open a block and you close it and then you say Tree open a block close it it's a lot
00:22:20.340 more it's a drier because I don't have to have a closing tag you just use a curly brace to close it
00:22:27.600 um and then within the tree you can declare properties of the tree so let's get back to the code
00:22:33.659 whoops Maybe do you have a way to zoom in just a little bit for the folks oh yeah yeah
00:22:40.020 let me zoom in yes okay
00:22:46.440 so I'm gonna kill those Okay so
00:22:52.460 thank you is that better yeah not that much cool okay so uh the body is a tree element
00:23:00.600 and then within the tree uh we have the Tree items we have a foreground color uh
00:23:05.880 we have some basically declarative stuff about how to support drag and drop from this tree
00:23:12.059 which I'll get into in a moment and then we have a menu so under the tree we have
00:23:17.159 a menu nested meaning the menu has open deletes refresh screening so this is basically if I'm gonna do unzoom for a
00:23:23.940 second and zoom back here this is what happens when I right click on one of those elements and um
00:23:30.179 uh you get this menu it's got open and delete refresh Etc so the code structure
00:23:36.059 mirrors the GUI structure meaning you know the menu belongs to the tree so
00:23:41.340 here you Nest the menu uh within sorry I must be at a different top I'm sorry
00:23:47.520 go back uh here this one yeah so here we have a tree and we asked
00:23:53.640 the menu within it and this is very similar to HTML HTML you basically have for example a form and within the form
00:24:01.740 you Nest an input field input field and the input field belongs to the form here's the same way it's basically I
00:24:08.340 have a menu that belongs to this tree and it'll pop up when I right click on the elements of the tree
00:24:13.820 so the Tree items is basically how I'm populating the tree and this one line is
00:24:20.039 populating the tree using data binding so all I'm doing is I'm basically binding the items of the tree to the
00:24:28.440 project directory object attribute sorry on cell
00:24:34.679 um and uh here I'm specifying that in order to grab children from that object
00:24:40.140 you need to invoke the children method and in order to grab the text the string
00:24:46.320 that will be displayed for every child like what is the file name for example uh
00:24:52.320 basically uh I'm invoking the name method so
00:24:58.380 um by using data binding um I've reduced the work of populating the
00:25:05.640 tree into a single line of Rubicon that's it which is unheard of in other languages and Java you have to write
00:25:10.919 patients and pages of code to build a GUI like that like I'm pretty sure that Eclipse IDE itself has pages to pages of
00:25:17.039 code to do stuff like that so because I used to do Java development of GUI in the past so so that's why I love Ruby I
00:25:24.059 mean in Ruby this is a single line of code it takes care of populating the Tweet declaratively why because if you
00:25:30.240 think about it uh what is a tree a tree is simply a hurricane
00:25:35.279 that begins with a root element and uh it ends with leaves at the bottom
00:25:42.299 so how do you data bind the tree the simplest way of thinking about it is I need a root element first of all second
00:25:49.200 of all I need to uh to know what what method should I invoke on this root element to get the children of the of
00:25:54.299 that element recursively and basically the method is
00:25:59.400 children I mean I ended up having a children method literally on that object
00:26:05.940 um and then on every child once I grabbed a child how am I going to display the text in the tree uh item for
00:26:13.080 it well I call the name method so that's all you have to do um using data binding declaratively
00:26:19.740 that's basically all this information that I just stated is here in one line of code
00:26:25.500 um and by the way tree elements are follow the composite pattern in
00:26:33.480 object-oriented programming meaning every element is a composite of more elements and every sub elements the
00:26:39.059 composite of even more sub elements um that's called the composite pattern and they all basically have to extend
00:26:45.960 the same class so all the items of the tree have the same story super class which is a composite sort of super class
00:26:53.580 uh and if I were to dig into the model so the root object is the project directory uh the model is a directory so
00:27:01.020 if we were to look at the model layer we have a glimmer Gladiator directory
00:27:08.460 and uh the directory has a number like
00:27:14.400 basically has a lot of attributes but one of them is children that's the attribute that I configured to be
00:27:19.980 loading the tree in the GUI um it has a selected child as well
00:27:25.020 because when when I open a file like this one that's the selected child wipe out so every composite has to know which
00:27:32.279 child is selected underneath um and there's a lot more information I'll get into it later but that's pretty
00:27:39.779 much the gist of what a tree is and how I how I was able to populate the tree uh
00:27:45.240 I basically made a directory here that uh will populate itself with an initial
00:27:50.700 path which is the root path of the project and then from that point on there is
00:27:55.799 logic on the model that will let you grab the children and behind the scenes it will call the Ruby facilities that
00:28:02.880 will show them to the command of line and figure out what files are under that directory as well as what other
00:28:08.820 subdirectories are under that directory um
00:28:14.820 so that's pretty much it I mean the menu items you got the gist of that too forever so
00:28:21.779 there's a menu it has menu items underneath uh within every menu item there are properties as well like what
00:28:27.899 is the text of the menu item uh and then there's a listener so this is uh this gets into the Observer pattern from MVC
00:28:34.919 uh usually um uh an MVC uh well let's get back to the
00:28:41.520 diagram of MVC it might be helpful to get into it right now actually let me just jump into it right
00:28:48.059 here okay usually The View
00:28:53.360 anything you see on the view is a visual representation of the model data so the
00:28:58.799 view is usually observing the model for changes and then it gets updated some model data that's how MVC type the
00:29:06.720 clean Small Talk At UC works the proper one and then the controller on the other hand is observing what the
00:29:13.919 user wants to do with the keyboard and mouse and when the keyboard and mouse are triggered
00:29:19.020 um uh it actually will end up uh calling the model to cause a change and then
00:29:24.659 since the view is observing that model for changes it'll it'll get updated indirectly after the user had made a
00:29:30.720 change with the controller so um
00:29:35.760 so here what I'm trying to say is basically you can configure listeners on menu items to tell to tell uh which are
00:29:43.140 basically playing the role of controller following the Observer pattern and this
00:29:48.899 listener the block of code that's underneath it will get triggered when I click on the menu item so I mean if I
00:29:55.140 click here and I say we're let's just say rename that's more obvious it let me rename the file for
00:30:01.860 example so that's because it responded to one of those controller uh actions that I have
00:30:09.779 configured over here um
00:30:19.440 I probably should you name it back though
00:30:24.840 okay um yeah so
00:30:32.520 so let's I'll get into a lot more detail later let's just jump into a few other components from uh Gladiator just to
00:30:40.740 uh yeah let's talk about something else if I look up my name so if I look up my name is this part
00:30:46.679 so how is it built again it's a component uh I have a file lookup list
00:30:51.840 component here it's got a body and again just like HTML except with a much lighter version of HTML and it's not
00:30:58.679 HTML because it's desktop development so it's more of a I call it the glimmer GUI
00:31:03.720 DSL it's a DSL for a GUI development it's called glimmer so I'm using the GUI
00:31:09.419 DSL here the glimmerically DSL and I have a list in this case
00:31:15.779 this is a list that will show me files that are looked up using a text control
00:31:21.059 so here are typed models so it basically did a search that showed me all file paths that have
00:31:28.980 the word model in them but I could have typed a view that would have given me everything that has view in its path and
00:31:35.460 and other Ides usually this feature is hidden you usually have to type a shortcut like command l or something and
00:31:41.640 it'll pop up I chose the design of keeping it shown all the time because I thought it might be more user friendly
00:31:47.700 I'm being my own usability expert on my phone now that might be just my own opinion maybe most people like disagree
00:31:53.880 with me but just an example of uh you know when you're building your own app uh you eat your own dog food and you
00:32:00.179 can build the app exactly exactly the project is open Souls yes so
00:32:05.760 I could forward you can make it absolutely so absolutely I agree with your opinion thank you
00:32:12.840 um so yeah so it's a list um it's got a selection that will be
00:32:18.240 um where we are so the list uh selection attribute uh will will basically data
00:32:26.460 bind whenever I select an item in the list it'll end up storing it on this filtered path attribute on this object
00:32:34.080 project directory um using data binding so in data binding
00:32:39.779 is usually bidirectional meaning when I first load the list uh whatever is
00:32:45.240 stored on that project directory will show up in the list but then if I make a
00:32:51.120 selection it'll it will store a value back on the model so that's why it's called bi-directional Data binding
00:32:58.500 um it's a bit Superfluous to say it because it's a bit it's intuitive usually you
00:33:04.019 want to make a change to the uh the codes and you also want to see changes
00:33:09.480 reflected back to you so you almost always you want to do something bi-directional um
00:33:15.779 and again it has a few properties selection foreground and then it's got listeners listeners always begin with
00:33:21.419 the on keyword so on Mouse up on on key pressed so on keep rest is basically if
00:33:27.659 with the keyboards I use the keyboard as a controller and I click enter it'll
00:33:33.539 open that file like right now I am on that file but let's just say I pick a different part of this one see it took
00:33:39.240 me there um so on Mouse up we'll we'll actually change
00:33:46.559 the selected file on the project directory
00:33:52.080 that is open over here so basically that one is if I click on a file so let's
00:33:57.179 just say I click progress show it'll it'll also open it's here so
00:34:03.080 basically this is happening indirectly using the MVC pattern that's what makes the code kind of clean the code is a
00:34:09.300 single line of code like this single line of code couldn't happen done all the work for
00:34:16.339 figuring out the path opening the five contents and opening up a new text editor and then
00:34:23.339 showing it in a new tab there's no way that line of code did all of that well that's true because that line of code
00:34:29.339 isn't doing all of that directly but it's doing it indirectly all I'm doing here is I'm updating an
00:34:36.000 attribute on a model and saying this is the new selected file however because I'm following NBC I have
00:34:43.679 codes elsewhere that says observe that attribute on this model and do all the
00:34:49.440 work that I just mentioned which is open the file contents open a new text editor load it up Etc but the code here is so
00:34:56.220 clean like if I'm maintaining this code it's a single line of code like I'm not thinking of all the other details at the
00:35:02.760 same time so that's pretty much that this is drag and drop drag and drop is a bit
00:35:09.359 complicated but it actually got simplified in recent in more recent versions of glimmer uh still this is not
00:35:15.240 that complicated it's basically saying that if I drag anything from here send this data for dragging basically set the
00:35:21.720 path of the file that's it set it as the event data and then when I drop the file
00:35:26.940 somewhere else there's a Code elsewhere that's saying if I drop so let's let's do drag and drop
00:35:32.640 so if I drag this text editor and drop it here it basically split the
00:35:37.800 screen and open a new editor here so there's another code elsewhere that is waiting for that drop to happen and it's
00:35:44.160 actually in Gladiator if I'm not mistaken or let me double check it might be in text editor
00:35:50.520 oh yeah these are synced using using bi-directional data binding so that's why they both scrolled at the same time
00:35:56.880 I built it that way some people might not like to build it you might want to separate the the
00:36:03.540 um the scrolling but I I I actually kept in sync synced for me it's good enough like
00:36:09.359 that um but if I were to dig into this uh the
00:36:15.119 text editor has there it is there's a drop Target declaration here that's saying if I drop something here
00:36:21.960 um grab that data that was the event data and then set it as the selected file on the project directory and again
00:36:29.339 there's then code elsewhere that is monitoring that selected chart path and as soon as it gets set it creates the
00:36:36.720 text editor and it opens it and if it's a drop event it'll automatically detect that it's a drop event because I'm
00:36:42.300 setting this attribute drag and drop true and it'll split the screen for me whereas if it was not a
00:36:48.000 drag and drop event for something else I would have not split the screen it would have just opened a new tab
00:36:53.160 so let's move on so text editor you already saw with the text editor a little bit
00:36:59.640 this is the text editor basically it's got a number line numbers part which is you see material on the left side
00:37:06.359 uh and it's a styled text widget meaning text that could be styled just like HTML
00:37:12.480 think of it as just like HTML but it's it's in a desktop context
00:37:17.700 um and uh I'm data binding a whole bunch of attributes here and the key one is
00:37:23.460 basically uh top pixel uh let me see
00:37:35.160 Waits I might be pointing at the wrong attribute um actually I can just search for it at
00:37:41.220 the time thanks for watching yep there it is uh oh okay okay I'm doing it in a
00:37:48.000 different place never mind load line numbers text content and then here I'm basically basically what you can do with
00:37:53.220 glimmer is reopen any component later if you want and add more stuff to it like more Properties or more elements within
00:37:59.400 it uh so just like Ruby's how Ruby supports open classes glimmer supports open GUI objects like GUI components it
00:38:06.599 can always be open and going components and change it so I'm changing it and basically synchronizing with
00:38:11.640 bi-directional data binding the topics so value to the topic cell attributes on
00:38:16.859 a model called the file model and that will synchronize so basically when I scroll up and down the top pixel is the
00:38:23.520 distance of the pixel that you're viewing on top here from the beginning of the document so for example here the
00:38:29.700 top pixel is oh yeah by the way we're showing it here so here the topic sold 402
00:38:36.000 um if I scroll down more it gets it grows even bigger now it's 1463. uh so that's how I end up thinking the
00:38:43.440 line numbers on the left side with the code on the right side so basically I have two text areas one and a little two
00:38:49.079 style text areas one that is representing the line numbers and one that's representing the code uh the code
00:38:55.200 is the text area it's called code text which is a more advanced version of style text style text lets you style a
00:39:02.099 text area any way you want context will automatically infer The Styling from the
00:39:07.619 language that you're using so that's why I specify to it the language um I specify here the language that I'm
00:39:14.579 using in this case it's Ruby it'll actually use the model to figure out what the language is so based on the
00:39:20.099 file extension if the file extension is dot CR that's the crystal programming language if it's dot uh RB it's the Ruby
00:39:27.780 programming language so for example if I were to open readme.md that's MD that's markdown so that's a different uh I see
00:39:35.339 like it also has uh coloring but it's different this one's more focusing on markdown syntax like building URLs for
00:39:42.480 example links um so again I'm just giving you a very high
00:39:48.599 level overview of this project um I'm not like this is uh I this is a very
00:39:55.320 Advanced I would say uh presentation and I'm Gonna Leave You with the high level
00:40:01.260 overview of how to build your own editor but not this but then you have to do your own homework afterwards and study
00:40:06.359 glimmer and also build your editor piece by piece in very small increments in
00:40:11.700 order to simplify the problem for yourself and successfully build your own editor so uh tabs what are tabs
00:40:18.720 uh basically tabs uh always fold under something called a tab folder
00:40:26.180 so you need a tab folder in order to have tabs in an application so here I have a tab
00:40:31.859 holder um and if I were to look at where it was assigned
00:40:38.460 oops there you go this is where it was
00:40:44.819 assigned and built I built it using this method and this method is basically
00:40:52.440 the nice thing about being in Ruby not HTML is an HTML if you want to break small parts of the page into their own
00:40:58.980 page you can't without using a technology like rails with ERD and partials on your own account you don't
00:41:05.760 have support for that uh actually the newer the newest HTML is beginning to add support for building
00:41:11.880 HTML components in JavaScript but still within HTML you can actually JavaScript
00:41:17.520 for it here the nice thing in rubies I can just build their method that has a useful name and then call that method
00:41:23.520 and within it um I can just build a tab folder and add listeners to it drag and drop support
00:41:31.020 Etc like because you can also drag a tab if you want to split the screen sometimes like
00:41:38.940 yep so I can drag and top
00:41:44.880 close now okay okay there you go so I can also split the screen by dragging the top
00:41:58.339 tabs always start with a tab folder and then I usually uh when you first open
00:42:04.800 the project it might have no tabs like zero tabs and then I add tabs to it by
00:42:10.920 reopening the content at the tab so that's why uh I end up relying on this dot content method that I showed you
00:42:17.400 that lets you reopen the content of the tab folder and then add top I tap items and then within the
00:42:24.180 top item I add the text editor widget so this text editor component that I showed
00:42:30.540 you earlier uh which has the class name text editor by convention in glimmer if you build
00:42:36.420 like a class name with this class name and it includes the custom widget mixing
00:42:42.900 that will automatically make a text underscore editor uh low level sorry
00:42:48.420 under under case methods available for you within the glimmer GUI DSL to invoke
00:42:55.079 that component and this is what this is how I can use here the text editor keyword so that means you can build an
00:43:02.099 unlimited number of Widgets or components for yourself for your GUI apps in order to build higher and higher
00:43:08.819 abstractions that simply find the way you think of your app in fact like I mentioned in the
00:43:15.180 beginning Gladiator itself is a keyword of those so that means I can include this entirety of gladiator in in another
00:43:22.380 glimmer app by using the keyword Gladiator only that's it does everything that we're seeing here just with one
00:43:28.140 keyword and that that comes from lisp by the way this is one of the great things of why Ruby uh inherits some features from this
00:43:35.460 like embedded dsls okay tabs find and replace
00:43:40.859 um I think it's simple enough I don't have to cover it keyboard shortcuts keyboard shortcuts are basically another
00:43:46.079 form of controller um on-text editor for example at the bottom I have a listener that
00:43:53.339 says uh uh on verified key verify key listener will execute wiper right when I
00:43:59.640 hit the key but before the key shows up on the screen so if I'm typing for example then I'm typing a character uh
00:44:07.440 right when I hit the character but before it shows up on the screen the verify unverify keyless mirror will fire
00:44:13.160 and here within this listener I just checked what that key is and then I execute a shortcut so it could be uh let
00:44:20.099 me show you some shortcuts so I can do this like indent in and then out that's Command right and left uh
00:44:28.140 the brackets I can do commands up and down I like that one a lot like it lets
00:44:33.180 me move a line up and down very quickly I mean I used to use this in Eclipse a lot the eclipse has that feature so I
00:44:39.420 kind of wanted to add it to my own editor um I can duplicate a line command d
00:44:45.240 uh so all of those are just here like see I check okay the user click command and click Z so that must be undo and
00:44:52.980 again like see if I do uh do this I can hit command Z and that would undo it
00:44:58.740 so that's undue so all the shortcuts are basically I check for every key
00:45:04.260 combination and whatever that key combination is I end up uh firing the command for it oh yeah that's
00:45:11.280 one thing I could cover now undo redo support is done using the command pattern that's the classical way of
00:45:16.980 implementing under redo usually um so that's why here I for every command
00:45:22.920 that executes like this this will fire a command that will say indent and indent
00:45:28.440 in uh how now I have a command class that will actually keep track of the
00:45:34.740 history of all the commands that fired and that's how I go on to redo eventually I can fire an undo command
00:45:40.140 it'll just go back to the history of all the commands that ran and it'll uh go back a command and basically undo the
00:45:47.460 text content value to its older version so I keep an old a version of the text
00:45:54.180 content content on every command change um one one more thing I had to do is um
00:46:02.520 usually commands are except you have for every command like indent or Al Dente would have a separate class
00:46:08.520 that would be the clean way of implementing command pattern uh the thing is when I started building the project I had a file uh class that was
00:46:16.380 representing all file operations on an open file and within it it has methods
00:46:23.160 for every operation so I have a method that says uh let me show you um
00:46:29.300 uh prefix new line remove line insert new line indent I just showed you and
00:46:35.819 then outdent Etc I have a method for every one of those operations I could have refactored this code and
00:46:42.720 moved every method into its own command but I was trying to save myself time and I used some of the crazy Ruby meta
00:46:48.599 programming features to get around that and Ruby every method is a considered um
00:46:54.660 uh a Lambda you can convert any method to a Lambda and then a Lambda is an object so that's already kind of a like
00:47:02.040 a command so then what I did is I used the adapter pattern and I made the command class adapt methods from the
00:47:08.160 file class into commands without making them clearance so that's one just one of
00:47:14.099 the cool things about ruby of course I'd like to in the future to refactor a file and break all of those into their own
00:47:21.059 classes that would be a lot cleaner because this is right now a giant file it's like what 700 lines of code so it
00:47:27.240 would be cleaner for me to do real command pattern but I'm just showing you Ruby is cool sometimes you can let you
00:47:32.819 cheat and get away without having to do that the pattern right away but in a future
00:47:38.640 refactor interval hopefully I'll handle that you guys saw split pain you saw menus
00:47:43.980 um you saw how to run Ruby I mean running Ruby code is the simplest feature all you have to do is uh read
00:47:49.319 the contents of the file and eval that's it in fact I bet I have an email here no
00:47:55.440 Maybe I'm Wrong maybe I did it how did I do it
00:48:04.380 maybe I did it a different way let me see do I have her one here it would have to be here okay there it is
00:48:10.680 run oh never mind I didn't do eBay see I I whites clean coat I don't use Eva I'm
00:48:16.380 just joking because Eva has a very bad reputation in Ruby I used loads instead of Eva which is the the next ugliest
00:48:22.440 thing but I'm just joking it's not that ugly in this case because if you have a file and
00:48:27.540 you want to run it as a ruby file like and I'm already inside Ruby you can just load it so that's what I do I just fold
00:48:34.859 it um and oh yeah if it's a scratch file it means it's a temporary file I will I
00:48:40.200 created in a temporary place and then I load it pretty much it
00:48:45.300 so yeah I think I pretty much covered everything here these are three esoteric
00:48:50.940 features towards the end that I'm going to cover basically watch the file directory yeah watch the external file
00:48:56.880 directory system for changes that means that if from outside of gladiator I end
00:49:02.339 up creating a file it will show up over here so let's hope it works right now
00:49:09.599 sometimes that doesn't work but there it is okay so if I were to touch
00:49:17.460 it's just a new file and then I think it showed up yeah there
00:49:23.339 it is new file so this is basically I have a I'm using a gem called a file Watcher
00:49:29.700 that will watch the file system for changes and as long as soon as they happen it will reflect them in the in
00:49:34.800 the in the Tweet the files Explorer retrievement Gladiator so that's what that is now I'm just using a gem for it
00:49:41.640 I bet it's the code is here file launcher I stop it when I close the file but I
00:49:49.020 you know dude it's it's just uh FW oh yeah and I have to do it in a separate thread because you don't want to pause
00:49:55.380 so given that I'm using Jr Ruby not C Ruby I have support for multiple threads
00:50:00.720 at the same time I can run threads in parallel which is not possible and c will be unless you use the new feature
00:50:06.240 which is called Raptors uh but fortunately in Jr Ruby I don't have to worry about that I mean I personally love threads because I used to be a Java
00:50:12.660 developer in the past and Java has threats and why not use them so this is a good example of using the myspina
00:50:19.200 separate thread to avoid pausing the IDE which is pretty much fluid and fast uh
00:50:24.660 but in the background they're basically demonitoring the file system for changes
00:50:30.059 um remember last open files you guys already saw that in action when I opened
00:50:35.339 Gladiator opened all the last open files that's just a matter of me uh uh
00:50:41.819 basically I have a load load config ignore path load config
00:50:50.280 that's a load config I store a yaml file somewhere that contains all the last of
00:50:55.980 all the tabs that are open um and when I close Gladiator and open it again it just looks at the names of
00:51:02.640 all the open files from that yaml file and it opens up all those tabs that's it
00:51:08.520 um database never exactly and finally ignoring irrelevant paths so if I have
00:51:15.839 uh uh like logs I don't want to open log logs are usually files that are like
00:51:22.440 have 20 more 20 000 lines of code or sorry lines of data or more like logs in
00:51:28.380 a web application uh so I have a bunch of directories that are ignored by Gladiator by default and they're all
00:51:35.160 over here uh yeah like basically dot get directory ignorant coverage
00:51:42.140 which gets data when you're running tests packages node modules nobody wants
00:51:48.359 no numbers temp vendor package disk test reports so these are
00:51:55.260 all directories that are basically ignored and you can add more files through them and basically whenever you create a project a
00:52:02.099 gladiator will generate a DOT Gladiator file that's hidden that maintains what
00:52:07.680 are all the open tabs this is so this is the animal filed and then I told you about I'm showing you the content of it
00:52:13.440 these are the open tabs uh this I even maintained what the top pixel was like
00:52:18.720 how scrolled you were in the file um how many split pains do you have did you
00:52:25.559 have uh what are the ignored paths Etc um so that's pretty much it
00:52:33.720 so I pretty much covered everything what are some future features that are missing right now if I'm Gladiator which
00:52:39.119 I haven't gotten into uh the first one for sure is file content search right now I use grab for now so
00:52:48.300 so yeah file content search uh there's a command on Linux or Mac called rep you
00:52:54.720 can use it to look up the contents of files I use that for now and it works pretty well for me for my you know
00:53:00.780 workflow but I'd love to in the future support doing file searches within Gladiator directly that would save me a
00:53:07.740 bit of time um themes right now there is internal support for themes
00:53:13.140 I'm sorry about misspelling here but uh that is not exposed so I can actually
00:53:19.260 aim it but I personally selected the theme that it has right now
00:53:24.359 um Mark Andre recently asked me if it supports dark themes I said no but I could quickly support it if needed so
00:53:31.079 I'd like to support that in the future extensions you can right now extend it it's open source you can just take the
00:53:36.839 source code and extend it that way but I'd like to make a more
00:53:42.599 by you know providing a pattern for people to follow in order to build extensions um and maybe others can contribute that
00:53:49.260 to the project they could just build into some medical requests and I I'd be happy to accept it and finally better
00:53:55.020 Windows and Linux support I mean I'll mostly use it on the Mac on the Mac I like it I think it's very good for my
00:54:00.240 needs but on Windows or Linux could use a bit of improvement uh and that's about it that takes us to
00:54:06.359 the Q a phase
00:54:17.099 move on to something else to announcements
00:54:22.700 how syntax highlighting works like um let me get into that yes yes I meant to
00:54:28.500 get into that so syntax highlighting is part of the
00:54:33.540 code text custom widget which used to be part of gladiator but then I thought it was so useful that I extracted it from
00:54:40.260 Gladiator and I moved it to glimmer so now any user of glimmer gets access to syntax highlighting for
00:54:46.380 for free for all the languages that I mentioned are supported uh and by the way the languages that are supported are
00:54:51.780 mentioned here in the readme they're uh these are these C C plus plus Crystal CSS jsx JSP Json JavaScript again we
00:55:01.319 pretty much all the things that you care about SAS CSS SQL Etc
00:55:07.140 um so this is the code text custom widget which is not part of glimmer
00:55:13.200 um the key part about uh the key logic regarding syntax highlighting is
00:55:20.520 is me not doing the syntax highlighting uh myself basically what I did is I used
00:55:25.619 a library called Rouge which is a ruby gem that has support for over 100 programming languages so I'm exposing
00:55:32.520 about over 30 languages that I care about in Gladiator but the library itself supports me a hundred languages
00:55:37.920 even more than what I'm exposing and Rouge does the support by I'll show you how it does it all you have to do is
00:55:46.980 there it is online get Style this is a listener that will get triggered on every line you see on the
00:55:53.940 screen in this widget before it gets rendered so this screen that I'm scrolling right now on every scroll or
00:56:01.079 change that method will get triggered and it'll basically go in and ask you to provide
00:56:06.839 it with style for every character that's showing up here so what I do is I use the Russian by calling I abstracted the
00:56:14.400 whole ruchamp thing using this method called syntax highlighting so let's dig into what syntax highlighting does
00:56:21.299 there it is it basically uses the Rouge Luxor and it lacks is the text meaning
00:56:28.140 it breaks it into tokens and for every token uh it'll give me so this is doing
00:56:33.420 all the work this is doing almost everything for for every token you see here like this for example this line
00:56:39.900 here is light blue this is dark blue this is uh red for the colons each one of those is a token uh
00:56:47.400 for every token it gives me a foreground color background color font style uh
00:56:52.680 everything I need to know in order to style it so that I return this data as part of this method I actually pass it
00:56:58.079 to sorry I pass it to a block here oh yeah I I basically iterate over each token
00:57:05.700 and for every token I grab the token index the token text the type the
00:57:10.859 foreground color background color bold italic Etc and I and I convert adapt all
00:57:16.920 this data that's kind of like the adapter pattern into what swt wants from me swt wants them in a style range
00:57:24.359 object and that represents a token so then I give the Salvage object everything it needs over here you know
00:57:30.240 what my foreground color background color size Etc um font font style as well and uh
00:57:37.680 I dump it into this thing and then I pass this thing into the event object that comes to me from here and when the
00:57:44.400 method when this block returns um The Styling happens using the swt style text widget
00:57:52.859 that's it so this is all abstracted into a code text component so you don't have
00:57:58.140 to worry about it just give it the language it just S2 for the language and if you want the theme as well so there
00:58:04.020 is support for theming uh and whether you want to see lines or not this is what I showed you in this example I can
00:58:10.020 see lines if I want or I can show highlights of code without mines oh no this one does have life but Without
00:58:15.359 Borders this one doesn't have lines each one is a different theme
00:58:20.640 so yeah that's it any other questions
00:58:29.280 yeah what was the most difficult thing or the thing you're most proud of in the project
00:58:34.680 nice
00:58:41.099 I would definitely say syntax highlighting was one of the most worrisome things that I thought
00:58:47.640 about at first that I was worried I wasn't going to be too difficult for me to Independent
00:58:54.000 um but like I said my only other editor was Bim and so tired of using them
00:58:59.940 so I I hunkered down and implemented syntax highlighting successfully and I was so happy when it worked the first
00:59:05.460 time being very sad
00:59:11.520 here's the deal man Vim is like is like having a Chevy okay a Chevy Malibu
00:59:16.920 uh I'm trying to build up Mercedes you may have a Chevy Malibu modified add a
00:59:22.559 whole bunch of cool features to it and extensions but it's still a Chevy Malibu it's time percent extended I understand
00:59:27.960 the same technology as the Eclipse which is used for NASA for NASA so it's that's like the Mercedes of building code
00:59:35.220 editors so that's what I'm trying to aim at not Bim I have a question though yeah sure if
00:59:41.099 it's about them oh yeah if you were to if you wanted to replicate web user experience I mean
00:59:47.520 like the ulti Combos and stuff like that how confident you think you could do that like with your DSL and stuff like
00:59:53.099 that um no you can Implement anything against yourself for sure man
01:00:00.720 cool uh the reason I say it can you can
01:00:06.540 Implement everything is because even if there was a wizard that didn't and swt that you dreamed of somehow like
01:00:12.839 say a film editor um you can build your own widget from
01:00:18.240 scratch if you want using custom graphic canvas graphics so there it does have support for canvas
01:00:24.359 Graphics meaning pixel by pixel if you want you can build your own widget but in general you probably want to avoid
01:00:30.660 that unless freely maintenance because that's for work but it's possible if needed do you feel confident that with
01:00:35.700 all the patterns you have right now you could like get something close to what Vim has pretty fast since like it seems
01:00:43.020 like the app sections are really good or do you think I I would basically try to
01:00:48.319 rewrite vim and Ruby no no I'm pretty sure you can do it
01:00:54.480 I wouldn't do it myself because I'm pretty sure you can do it
01:01:01.200 any other questions okay thank you everybody oh yeah one
01:01:06.420 more out how would you go about uh let's say I had an idea for a certain extension for them for Gladiator how
01:01:13.260 would you go about it if I wanted to go and create it because I understand that I could go forward but I don't think
01:01:18.780 it's really uh uh negative
01:01:24.119 very very efficient to add to add features you're using with with Force
01:01:29.460 for every everything I want I would want to add maybe uh if there was a DSL or
01:01:35.339 extensions it would be a little easier yeah I mean you could get started by
01:01:41.040 implementing support for software extensions I'm sure that work for that is useful
01:01:46.260 however I mean to talk about a bit about that I used to use in Java as something
01:01:51.900 called the eclipse Rich client platform which is the eclipse itself is built on top of a framework and I I've used it to
01:01:59.460 build desktop but sorry yeah desktop applications for business in a previous job and the way we used it was we built
01:02:05.280 extensions for for the eclipse sorry not that not the ID the platform itself the
01:02:11.099 eclipse platform um the rich client platform so um things that they made extensible for
01:02:17.640 example is when I open a tab right now I support say 100 languages programming
01:02:22.740 languages if somebody wants to add more support for something Beyond Rouge with the Russian provides which is to be
01:02:29.700 honest it almost covers everything but still if you want to invent your own language
01:02:35.160 support for it I guess we'd have to open that up so I'd have to modify the code text thing
01:02:43.559 widget to support passing a block that will do all the work that I just showed
01:02:49.859 you about the lecture how Lexus lexor Lexis the world the words the tokens and
01:02:55.619 then it gives you uh coloring for them so that's one thing uh another thing would be every part that you see here
01:03:02.579 like the file explorer the file lookup the navigation area is a component if we
01:03:08.220 can also support the idea of people building their own components as extensions that can show up anywhere on
01:03:14.339 the screen that's something that Eclipse used to use and supports with their framework that would be cool to support
01:03:21.000 with this in Ruby so yeah there are quite a few ideas on
01:03:26.280 how to extend this also you can extend the menus and you can extend um the
01:03:31.859 right click menus and you can extend preferences if needed
01:03:39.359 but if you ever think of building one of those features please submit a pull request over
01:03:49.980 cool uh well that concludes the Q a phase let's get into that announcements thank
01:03:56.460 you
Explore all talks recorded at Montreal.rb Meetup
+6