Skip to content

Pull Request Reviews : Integrating Code Editor with Syntax Highlighting

Samad Yar Khan edited this page Sep 7, 2022 · 1 revision

Pull Request Reviews : Integrating Code Editor with Syntax Highlighting

One of the features which was essential to the Github Rocket.Chat App was to have the ability to review code changes from a pull request and merge the PR right from RocketChat. We were able to fetch the code changes of a PR inside modals but they lacked style, syntax highlighting and indentation, it was plane text and on different line.

To tackle the issue we have tried three approaches :

1) Parse the diffs

  • The first method was to parse the diffs file provided by the github pulls API into a string.
  • The github diffs have ++ and -- to show additions and deletions. It was suggested that we could add different colors to the ++ and -- lines but that was not possible due to the limitation of the apps engine. So we will be moving forward with an emoji to show case additions and deletions.
  • Second issue was indentation. RC apps engine was able to parse \n as new lines but could not parse \t. The simple approach was to have a parser which add " " (~ 4 spaces) in place of tabs and we let RC do the work for new lines.

Blocker : The SectionBlock will simply truncate all the white spaces before the text in each line and we loose all the indentation. Hence we tried to solve the issue using a MultiLineInputBlock element.

2) Code Editor Integration

  • The second approach was to integrate a javascript like ACE inside apps engine.
  • The limitation of the apps engine UI is that we cannot add a new component as we please, the components are used from the UI kit and they are borrowed from fuselage.
  • ACE needs to run scripts on the client side but that is not possible with the current apps engine limitations.
  • So, we will need to add an editor component, which uses the modules provided by ace, into fuselage and then link that with the apps engine UI kit and use it in our app. (This is a work in progress , any help will be appreciated :) )

3) Adding New Input Elements to Fuselage UIKit

  • While displaying the PR code changes inside the SectionBlock element, the indentation of the code is not preserved. The MultilineInput elemnt preserves the indentation and can also be used a editor. It will not have proper highlighting but the indented code can be reviewed with relative ease.
  • The only problem is that the MultilineInput element has a small size. We aim at adding new MultilineMediumInput and MultilineLargeInput elements to fuselage.
  • This would enable Rocket.Chat App developers to have a larger input element in their apps. This would make it easier for users to go through large chunks of code at once instead of scrolling again and again.
  • The discussion for this approach can be tracked over here.
  • This would require changes in the fuselage , fuselage-ui-kit and UIKit packages.
  • The pull request for this feature can be tracked over here.
  • Once the PR is merged, we will need an additional PR in the Apps Engine to change the parameters passed to InputBlock element and our new elements will be accessible just by adding additional parameters to Input block.

Extending Code Editor Integration to fuselage and Apps-Engine

Adding a re-usable element component to Apps-Engine, requires us to add the component in fuselage and ui-kit packages in the fuselage, fuselage-ui-kit package in Rocket.Chat and the Apps Engine ui-kit.

google-summer-of-code

1) fuselage

  • Rocket.Chat uses React Components from the fuselage package to build the user interface.
  • Adding any new component to the ui-kit, requires us to add the component to fuselage.
  • We decided to go with CodeMirror to build the fuselage Code Editor Component but the component could not be built inside Rocket.Chat because of the internal module used by CodeMirror. The fuselage branch with CodeMirror can be found over here.
  • Finally, Ace was used to make the Code Editor component inside fuselage.
  • The fuselage package with the Ace Code Editor can be found over here.
storybook-code-editor

Code Editor in StoryBook

2) ui-kit (fuselage)

  • For any Apps Engine UIKit element, we must add the element/block definition in fuselage/ui-kit.
  • ui-kit contains definitions of blocks/elements along which are to be used by apps-engine developer, this also contains the parameters to be passed by the AppsEngine developer at the time of creation of an element or block which renders the fuselage component.
  • fusaelage-ui-kit uses the ui-kit definitions to render the elements as per the payload.
  • The ui-kit changes to add add the Code Editor Element to the kit can be found over here.
  • It made more sense to consider Code Editor as an extension of the the current PlainTextInputElement of the ui-kit. So, whenever the code prop of an InputElement block is set to true, we can render the CodeEditor as the input block element when needed and take code input from users aswell. The branch for this changes can be found over here.

3) fuselage-ui-kit

  • fuselage-ui-kit is a fuselage package, but Rocket.Chat is going through structural changes to build a mono-repo structure and the fuselage-ui-kit can be found inside the packages inside Rocket.Chat.
  • ui-kit elements can be tested inside modals and banners using storybook.
  • All ui-kit elements are added in the fuselage-ui-kit in order for them to be rendered inside Rocket.Chat on receiving a payload from the Rocket.Chat.Apps-Engine.
  • fuselage-ui-kit relies on ui-kit determine the components props/parameters and on fuselage to import and render the component on different surfaces such as banners or modals.
  • The fuselage-ui-kit branch with the CodeEditorInputElement can be found over here. Here we have introduced the code parameter or prop to the PlainTextInputElement which helps us render a the CodeEditor whenever a payload, with code set to true, is received from the Apps-Engine.
  • Other Implementation with the independent code editor block in fuselage-ui-kit can be found over here.
  • The Code Editor Component in storybook inside the fuselage-ui-kit can be found below.
code editor

Code Editor Input in Banner

code editor

Code Editor Input in Modal

4) Rocket.Chat.Apps-engine (ui-kit)

  • After adding the ui element/block to fuselage, ui-kit and fuselage-ui-kit, in order to make the block element re-usable by Rocket.Chat App developers, we must make changes to Rocket.Chat.App-engine/ui-kit.
  • To add new block/element, we must add typescript interfaces which define the ui-element properties similar to the ones in fuselage/ui-kit.
  • We need to create the methods such as CodeEditorBlock to the BlockBuilder class, which is used to develop ui-blocks for any Rocket.Chat App.
  • BlockBuilder sends a payload to the Rocket.Chat server and the ui-block is rendered using fuselage-ui-kit. Rocket.Chat.Apps-engine branch consisting of a new CodeEditor element can be found over here.
  • Sometimes its not needed to add new elements but we need to modify existing elements to add new functionality to available elements. Rocket.Chat.Apps-engine branch which extends the InputElement to use CodeEditor for a Code Input can be found over here.