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

Use rouge for highlighting instead of Pygments #141

Merged
merged 4 commits into from
Oct 6, 2015
Merged

Use rouge for highlighting instead of Pygments #141

merged 4 commits into from
Oct 6, 2015

Conversation

kylef
Copy link
Contributor

@kylef kylef commented May 8, 2015

This removes a dependency on a Python project, and greatly improves syntax highlighting along with fixing #138.

Before:

screen shot 2015-05-08 at 18 00 26

After:

screen shot 2015-05-08 at 18 00 11

This does add a required dependency which may not be desired, if that is the case I'm happy to amend this pull request to make rouge optional.

register_filetype 'dylan', ['.dyl', '.dylan']
register_filetype 'ruby', ['.ruby', '.rb']
if !lexer && File.extname(options[:filename]) == '.m'
# Objective-C is hard to guess when you use BDD style frameworks like Kiwi and Specta
Copy link
Collaborator

Choose a reason for hiding this comment

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

Line is too long. [93/80]

@kattrali
Copy link
Contributor

kattrali commented May 8, 2015

The output is definitely nicer

`echo '#{code}' | pygmentize -f 256 -l #{language} #{options if options}`
end
if !lexer && File.extname(filename) == '.m'
# Objective-C is hard to guess when you use BDD style frameworks like Kiwi and Specta
Copy link
Collaborator

Choose a reason for hiding this comment

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

Line is too long. [93/80]

begin
require 'rouge'
rescue LoadError
Rouge = nil
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use SCREAMING_SNAKE_CASE for constants.

@kylef
Copy link
Contributor Author

kylef commented Jun 24, 2015

I've updated this pull request to make rouge optional (it's still in the gem spec, so when installed via ruby gems it will be available).

:filename => File.basename(filename),
:source => snippet.contents,
}
lexer = Rouge::Lexer.guesses(options).first
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be better to just use :filename => filename and not let it guess from the contents?
I believe that'd be faster as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not as accurate since certain pieces of code might have false positives against other languages. Especially when using BDD style frameworks.

I don't think performance is much of a problem since this code path is only called when there is a failing test (and there shouldn't be many of these ;)). This is also how it worked before so it was acceptable beforehand.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm.. I was playing with filenames and sources a bit, and seems like it sometimes recognizes objc (.m extensions), and always works with swift.

screen shot 2015-06-25 at 3 53 34 pm
screen shot 2015-06-25 at 3 51 43 pm

Copy link
Contributor

Choose a reason for hiding this comment

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

@kylef I appreciate code removal (and am always for it), but not sure if we should maybe keep the manual filename mapping.
What do you think?

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 both should be here, and here's a few examples of why:

  • This code using the Quick/Nimble Swift framework isn't able to be detected as Swift, purely because it would also be valid syntax in other languages such as Ruby and Python. The file extension is required to improve the guessing.
    screen shot 2015-06-25 at 16 01 49
  • Filename isn't enough to match Objective-C, since .m is a file extension shared with other file types (matlab for one).

@supermarin
Copy link
Contributor

@kylef sorry, maybe my explanation was bad.

Wouldn't it be better to just use :filename => filename and not let it guess from the contents?

This means using the whole filename (e.g. file.swift) instead of File.basename(filename) that you're using ATM.

I am aware that guess* methods are not 100% accurate, that's why I proposed to keep the manual mapping and just tell Rouge which language is it.

@kylef
Copy link
Contributor Author

kylef commented Jun 25, 2015

Okay that makes sense, I'll try address this soon.

@supermarin
Copy link
Contributor

Thanks for your work! appreciate that!

@@ -26,6 +26,8 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]

spec.add_dependency 'rouge', '~> 1.8'

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry if we already discussed - should we try to implicitly rely on Rouge like we did on Pygments?
That way we're still zero dependencies and will colorize if someone has installed Rouge

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 is already conditional, the conditionally depends on rouge in code.

return snippet.contents unless Rouge

I put a hard-dependency in the gemspec since I would assume if you are using RubyGems to install xcpretty (a package manager) you would want it to manage your packages and dependencies.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

@kylef if there's a hard dependency, then there's no need for the conditional :)
The good thing is that it has no dependencies, and that's something we valued a lot in xcpretty itself so far.

On the other hand - I think we should be moving towards homebrew because xcpretty should be treated like a command line tool rather than a gem.
I understand we can bundle that up together with rouge tho, just thinking out loud.

@kattrali what are your thoughts on this particular one?

Copy link
Contributor

Choose a reason for hiding this comment

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

@kylef sorry just saw your comment ^^

So far rubygems are the only method one can install xcpretty with, afaik :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for the confusion guys, multitasking :)
Let me try once again - if I fail let's just 🚢 🇮🇹 .

Currently we use RubyGems, which is bad.
We should be using Homebrew and treat xcpretty like a CLI tool rather than a library.

No dependencies is great because install time is fast, and rubygems are super slow with dependencies->dependencies->dependencies.

Not having that line in .gemspec gives you the possibility of just installing xcpretty and manually installing rouge.
If we put that line into .gemspec, you'll have Rouge installed on each Travis job.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we put that line into .gemspec, you'll have Rouge installed on each Travis job.

You wouldn't, both Circle CI and Travis CI pre-install xcpretty in their OS X images.

I've removed it from the gem spec in 336e394 since you feel strongly about it not being there. But this means that RubyGems will not lock the version of Rouge and any breaking changes could cause xcpretty to break for users either now or in the distant future.

If the user has Rouge < 1.8 it may not work, or >= 2.0.


We should be using Homebrew and treat xcpretty like a CLI tool rather than a library.

Isn't that an even bigger dependency? One that requires you to be an administrator of your computer. Many users may not be able install xcpretty if they are in corporate or education environments where they do not have administrator privileges.

This conversation is off-topic and doesn't belong on this PR...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Due to 336e394, I don't think this is a good idea and I think we should close this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I think we're on the same page this time.

Currently we use RubyGems, which is bad.
We should be using Homebrew and treat xcpretty like a CLI tool rather than a library.

Considering there are plenty of other tools already in the average cocoa developer's toolbox which are installed via rubygems (and its on every OS X system already), this still seems negotiable. There are no barriers to installation; rubygems handles libraries with a binary components just fine, just as homebrew, pip, or any other package manager does. Even then, if you bundle xcpretty without rouge via Homebrew, it still works, just doesn't have rouge.

No dependencies is great because install time is fast, and rubygems are super slow with dependencies->dependencies->dependencies.

No argument here, however in this case we are talking about one dependency which greatly enhances the usability and has no dependencies itself. There is the chance that otherwise the rouge gem installed on the system does not meet this requirement and breaks xcpretty as a result when we do implicit dependencies.

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 336e394, I don't think this is a good idea and I think we should close this PR.

I'm sorry if I caused a conversation, that wasn't the intention.
Thank you again for your work - it's a great thing and we should merge this PR.

@kattrali kattrali modified the milestone: 1.0.0 Oct 6, 2015
else
options = {
:filename => File.basename(filename),
:source => contents,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use the new Ruby 1.9 hash syntax.
Avoid comma after the last item of a hash.

kattrali added a commit that referenced this pull request Oct 6, 2015
Use rouge for highlighting instead of Pygments
@kattrali kattrali merged commit 9b047b7 into xcpretty:master Oct 6, 2015
@kylef kylef deleted the kylef/rouge branch October 6, 2015 20:43
@0xced
Copy link
Contributor

0xced commented Oct 8, 2015

While the default theme (ThankfulEyes) works fine on a dark background, it’s terrible on a light background.

syntax highlighting on light background

Is there a way to detect the terminal background color so that we could use an appropriate theme?

@supermarin
Copy link
Contributor

Pretty hard; maybe there's a color scheme that works better.
I think the main problem is that it uses hardcoded color codes instead of basic terminal codes.

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.

None yet

5 participants