Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add emacs #1297

Merged
merged 68 commits into from
Apr 5, 2018
Merged

add emacs #1297

merged 68 commits into from
Apr 5, 2018

Conversation

JuanCaicedo
Copy link
Contributor

This adds the plugin developed by akirak/prism-emacs-lisp for the emacs lisp language. The extension is emacs.

I would like to support also lisp and elisp since both of those names are used, but I'm not sure what would be the best way to do that.

Let me know if there's anything missing to be able to add this 😀

@JuanCaicedo
Copy link
Contributor Author

I'll try to post an example soon of this working

@JuanCaicedo
Copy link
Contributor Author

JuanCaicedo commented Feb 16, 2018

You can see some of the highlighting at https://prism-emacs-ogfsnjvwlg.now.sh/post

Copy link
Contributor

@Golmote Golmote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thanks for contributing.

Apart from my inline comments, there are other things that need to be adressed before inclusion in Prism:

  • You need to add the language in the components.js file.
  • You should add an example file, following the format of the existing ones.
  • You should ideally add tests. You can find more information on the Test suite and look at the many existing examples.

@@ -0,0 +1,179 @@
Prism.languages.emacs = (function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • emacs is an editor before being a language. I think it would be less confusing to name the component emacs-lisp.
  • Since this is a dialect of Lisp, it would have been interesting to have generic support for Lisp first, and then maybe add specific dialects support if the generic component can't handle them.


// Symbol name. See https://www.gnu.org/software/emacs/manual/html_node/elisp/Symbol-Type.html
// & and : are excluded as they are usually used for special purposes
const symbol = '[-+*/_~!@$%^=<>{}\\w]+';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Prism is written is ES5. ES6 is not compatible with IE11 so this component would need to be transpiled or rewrittent in ES5. Here, this just means the const should be replaced with var.
  • The _ should not be needed here as it's already included in \w.

// Functions to construct regular expressions
// simple form
// e.g. (interactive ... or (interactive)
const simple_form = name => new RegExp(`(\\()${name}(?=[\\s\\)])`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Same thing for fat arrows and template strings. Please use ES5.
  • There is no need to espace the closing parenthesis in the character class at the end.

// e.g. (interactive ... or (interactive)
const simple_form = name => new RegExp(`(\\()${name}(?=[\\s\\)])`);
// booleans and numbers
const primitive = pattern => new RegExp(`([\\s\\(\\[])${pattern}(?=[\\s\\)])`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to espace the opening and closing parentheses in the character classes here.

},
'comment': /;.*/,
'string': {
pattern: /"(?:[^"\\]*|\\.)*"/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about line feeds? Are multiline strings supported in Emacs Lisp? If not, the character class should probably also exclude \r and \n.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think multiline feeds are supported, I say that because this is a valid function definition

(defun multiply-by-seven (number)
       "Multiply NUMBER by seven,
second line"
       (* 7 number))

pattern: primitive("[-+]?\\d+(?:\\.\\d*)?"),
lookbehind: true
}
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the array contains only one pattern, it could be be removed.

pattern: new RegExp(par + 'def(?:var|const|custom|group)\\s+' + symbol),
lookbehind: true,
inside: {
'keyword': /def[a-z]+/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder what the highlighting would be here with a code piece like (defvar defabc? Maybe a ^ anchor should be added at the beginning of this regexp.

pattern: new RegExp(par + `(?:cl-)?(?:defun\\*?|defmacro)\\s+${symbol}\\s+\\([\\s\\S]*\\)`),
lookbehind: true,
inside: {
'keyword': /(?:cl-)?def\S+/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A ^ anchor might be needed here too.

pattern: new RegExp(par + `lambda\\s+\\((?:&?${symbol}\\s*)*\\)`),
lookbehind: true,
inside: {
'keyword': /lambda/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A ^ anchor might be needed here too.

@JuanCaicedo
Copy link
Contributor Author

@Golmote Thanks for the feedback! I'm having some trouble understanding the tests. I'll upload here with some comments on what I'm having trouble with.

I think the renamings I made will cause the previous comments to appear outdated. I'm adding this here as a reminder that they still need to be addressed

components.js Outdated
@@ -197,6 +197,10 @@ var components = {
"title": "Eiffel",
"owner": "Conaclos"
},
"elisp": {
"title": "Elisp",
"owner": "JuanCaicedo"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I should be the owner, since I didn't develop this. Totally willing to defer to @akirak if they would like to take it over 😀

Copy link

@akirak akirak Feb 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for creating this pull request.

I don't mind your being owner of the module, but this plugin is experimental, and there are some corner cases where it doesn't render well, like in this example. It's doing complex things, and I don't know how to fix this bug.

If you still don't mind using the plugin, you or whoever can be its owner. As you've put an effort in adapting the plugin, I think you deserve the credit. I will mention this merge in the README of my repo, but I won't be responsible for maintaining the plugin.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akirak has a point, here. In Prism, we do expect the component's "owner" to do some kind of maintenance if issues regarding this component arise.
So you should probably keep it with your ownership, @JuanCaicedo.


[
["string", ["\"\""]],
["string", "\"foo\\\r\nbar\""]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This leads to a failure which I don't understand

Token Stream:
[["string",["\"\""]],"\r\n\"foo\\\r\nbar\""]
-----------------------------------------
Expected Token Stream:
[["string",["\"\""]],["string","\"foo\\\r\nbar\""]]
-----------------------------------------

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My impression is that the second case is not recognized as a string. I'm not sure if it's a problem I'm how I'm writing the test cases or in the implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm inclined to assume the implementation is right and my testing is wrong. If so, maybe the problem is that listing strings like this isn't valid lisp. Maybe the test tokens could me changed to

(
""
"foo
bar"
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, your string pattern in the component allows only unescaped line feeds. #1297 (comment)

@akirak
Copy link

akirak commented Feb 17, 2018

Also note, you may have to add some classes to your theme (CSS) to fully take advantage of it. I have tried it with Dracula theme included in the repo, which is a dedicated effort for the language, but I haven't tested it with any other themes for Prism.

@akirak
Copy link

akirak commented Feb 18, 2018

@Golmote I'm the original author of the plugin, and I'm sorry for this tedious work. That code was not meant to be merged into the code base of PrismJS. It should be transpiled using babel, but apparently its resulting code will not be suitable for maintenance by human. Therefore I didn't send a merge request to you.

I am currently working on another project, and I'm not sure if I will adapt this stuff to the proper plugin format. Thank you for your comments.

@akirak
Copy link

akirak commented Feb 18, 2018

The name emacs relates to a limitation of a blog engine I am using. My blog source contains code blocks in emacs-lisp language, but my blog engine somehow splits the name by hyphen, and the resulting class name becomes emacs. The plugin was named emacs so that it can highlight Emacs Lisp code in my blog, and I didn't consider supporting other Lisp dialects. Perhaps it should have been first named emacs-lisp, but I would still have to add an alias emacs for use in my blog.

@Golmote
Copy link
Contributor

Golmote commented Feb 18, 2018

@akirak No worries. I noticed that some patterns are not handled by the official themes. It's not the first component doing so though, and it's ok if some parts are tagged but not styled. I'll just check the appearance once the PR is ready to be merged and maybe we'll make some adjustments. We might also want to add a comment with a link to your original repo, to credit your original work and in case some users are interested in using the Dracula theme you made.

The transpilation to ES5 should not be that tedious in this case: you're really just using tiny bits of syntactic sugar. Transforming const to var, fat arrows to regular functions, and template strings to good old string concatenation should be pretty straightforward.

I understand the naming limitation you had. Maybe we can still add emacs as an alias, since it seems to be the main scripting language used by this editor.

Thanks for showing up on the PR anyway! I hope @JuanCaicedo can take it to a mergeable state. :)

@JuanCaicedo
Copy link
Contributor Author

@Golmote sorry for the delay, I'm working through these changes now 😀

@@ -0,0 +1 @@
function loadLanguages(e){e||(e=Object.keys(components.languages).filter(function(e){return"meta"!==e})),Array.isArray(e)||(e=[e]),e.forEach(function(e){components.languages[e]&&components.languages[e].require&&loadLanguages(components.languages[e].require),require("./prism-"+e)})}var components=require("../components.js");module.exports=loadLanguages;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was generated when I ran gulp. Not sure if it should be included. If not, I can revert the commit that added it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I never realized a minified version was generated for it.
I don't think it's needed, though. I'll have to update the gulpfile to exclude it. In the meantime, you can remove it from this PR, indeed.

Sorry about this, and thanks for pointing it out!

Prism.languages.lisp = language;
Prism.languages.elisp = language;
Prism.languages.emacs = language;
Prism.languages['emacs-lisp'] = language;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this alias is allowed. I added it to allow more flexibility, but I can remove it you'd rather not have it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok, we can keep it.

@JuanCaicedo
Copy link
Contributor Author

@Golmote I fixed the merge conflicts and addressed the majority of the code comments (sorry for the accidental style changes 😬)

I'm working on trying to combine the regexes you mentioned. I'm finding it difficult though, so if it's okay to merge this without doing that, let me know 😀

Copy link
Contributor

@Golmote Golmote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuanCaicedo Don't worry it's ok if you don't manage to merge the regexps. Maybe I'll try later, once the PR is merged.

Thanks for updating the PR, we're almost there! Please take a look at my comments.

@@ -0,0 +1 @@
function loadLanguages(e){e||(e=Object.keys(components.languages).filter(function(e){return"meta"!==e})),Array.isArray(e)||(e=[e]),e.forEach(function(e){components.languages[e]&&components.languages[e].require&&loadLanguages(components.languages[e].require),require("./prism-"+e)})}var components=require("../components.js");module.exports=loadLanguages;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I never realized a minified version was generated for it.
I don't think it's needed, though. I'll have to update the gulpfile to exclude it. In the meantime, you can remove it from this PR, indeed.

Sorry about this, and thanks for pointing it out!

Prism.languages.lisp = language;
Prism.languages.elisp = language;
Prism.languages.emacs = language;
Prism.languages['emacs-lisp'] = language;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok, we can keep it.

<li>"language-emacs"</li>
<li>"language-emacs-lisp"</li>
</ul>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to a recent update, you can remove everything above this comment, in this file. The example header will be generated automatically.

components.json Outdated
@@ -373,6 +373,11 @@
"title": "Liquid",
"owner": "cinhtau"
},
"lisp": {
"title": "lisp",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you capitalize the name here? "Lisp"

Note that you'll need to run gulp after this change, to update the Show Language plugin files.

bar"
"\"foo\""
"foo\tbar"
"foo\tbar"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a duplicate here. I don't think there's a need to test it twice.

themes/prism.css Outdated
@@ -104,7 +104,7 @@ pre[class*="language-"] {
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
color: #a67f59;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should not be here. This file was changed 10 days ago in 8aea939. #9a6e3a is the correct value.

@JuanCaicedo
Copy link
Contributor Author

@Golmote I've updated based on your last comments 😀

@Golmote Golmote merged commit 46468f8 into PrismJS:gh-pages Apr 5, 2018
@Golmote
Copy link
Contributor

Golmote commented Apr 5, 2018

@JuanCaicedo Yay! 🎉

@JuanCaicedo JuanCaicedo deleted the add-emacs branch April 6, 2018 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants