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

Rule proposal: string-content #327

Closed
fregante opened this issue Jun 22, 2019 · 13 comments · Fixed by #496
Closed

Rule proposal: string-content #327

fregante opened this issue Jun 22, 2019 · 13 comments · Fixed by #496
Labels
💵 Funded on Issuehunt This issue has been funded on Issuehunt help wanted new rule

Comments

@fregante
Copy link
Collaborator

fregante commented Jun 22, 2019

Issuehunt badges

Good 👍

const description = 'Add text to user’s comments'

Not good 👎

const description = 'Add text to user\'s comments'

Prior art: https://github.com/jmont/eslint-plugin-smart-quotes

I tried that one but it doesn't have a fixer and it has many false positives. Also strings could be CSS selectors so[alt=""] needs to stay as is.


Originally posted by @sindresorhus in refined-github/refined-github#2167:

'use strict';

const create = context => {
	return {
		Literal: node => {
          	const {value} = node;
     
			if (typeof value !== 'string') {
				return;
			}
          
        	const fixedValue = value.replace(/'/, '‘');

			if (fixedValue === value) {
				return;
			}

			context.report({
				node,
				message: 'Use other quote kind',
				fix: fixer => fixer.replaceTextRange([node.range[0] + 1, node.range[1] - 1], fixedValue)
			});
		}
	};
};

module.exports = {
	create,
	meta: {
		type: 'problem',
		fixable: 'code'
	}
};

https://astexplorer.net/#/gist/3a67df351a57608ae38a6b55102376d6/c8425e326ddce75bf7242295c8818134ef2d2e16


IssueHunt Summary

Backers (Total: $80.00)

Submitted pull Requests


Become a backer now!

Or submit a pull request to get the deposits!

Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

@MrHen
Copy link
Contributor

MrHen commented Jun 22, 2019

I'm not sure how a lint rule would detect when it is appropriate to use one over the other. If you have a string such as Sally said, "Bob said, 'I am hungry'." you cannot flag both single quotes for conversion. The strings themselves could be split up across multiple literals so you couldn't check the content of any particular literal to know which is appropriate.

That being said, there are similar potential rules with other shorthand strings:

  • " versus and (which is locale specific)
  • ... versus
  • -> versus (or a plethora of other arrows)

I think the ellipsis would be the easiest to detect because exactly three periods in a row is pretty indicative of an ellipsis. But I'm wary of trying to challenge the content in strings -- I think linting is more suited for checking code syntax and style than English syntax and style.


I suppose we could make this a generic string content scanner that took configured regex search / replace:

"unicorn/string-content": ["warn", {
  "patterns": [
    {
      "match": "'",
      "suggest": "",
      "fix": false
    },
    {
      "match": "..." ,
      "suggest": "",
      "fix": true
    }
  ]
}],

Or some such. But I'm fairly skeptical.

@fregante
Copy link
Collaborator Author

fregante commented Jun 22, 2019

My fear is that it might cause some false positives; that’s why it should probably be limited to single apostrophes, exclusively to avoid escaping them.

A generic “typography” rule would be difficult to manage since there are many cases in which punctuation is not part of user-visible text (e.g. selectors, queries)

The replacer would be great too, as a generic rule

@fregante
Copy link
Collaborator Author

fregante commented Jun 22, 2019

To test the applicability of this rule in your projects, try looking for situations where \' needs to stay like that:

grep "\\\'" -R . \
	--exclude-dir node_modules \
	--exclude-dir .git \
	--include "*.js" \
	--include "*.ts" \
	--include "*.tsx" \
	--exclude '*.min.*'

@sindresorhus
Copy link
Owner

I like the idea of a generic string-content rule. Let's go with that.

I think match could be even more flexible by accepting: string | RegExp | Array<string | RegExp> (?)

@sindresorhus
Copy link
Owner

sindresorhus commented Jun 23, 2019

I would use the rule for important things:

"unicorn/string-content": ["error", {
  "patterns": [
    {
      "match": "unicorn",
      "suggest": "🦄",
      "fix": true
    }
  ]
}]

@sindresorhus sindresorhus changed the title Rule proposal: Prefer typographic apostrophe in strings: \' Rule proposal: string-content Sep 5, 2019
@sindresorhus sindresorhus changed the title Rule proposal: string-content Rule proposal: string-content Sep 5, 2019
@issuehunt-oss
Copy link

issuehunt-oss bot commented Sep 6, 2019

@issuehunt has funded $80.00 to this issue.


@issuehunt-oss issuehunt-oss bot added the 💵 Funded on Issuehunt This issue has been funded on Issuehunt label Sep 6, 2019
@otofu-square
Copy link

I'd like to work on this issue 👀

@fregante
Copy link
Collaborator Author

It's all yours :)

@sindresorhus
Copy link
Owner

sindresorhus commented Sep 11, 2019

Just make sure you read this thoroughly and have an understanding of AST and ESLint rules :) And add a lot of tests. It's better with too many than too few.

@fisker
Copy link
Collaborator

fisker commented Jan 6, 2020

@sindresorhus I have a problem on report message, if we treat match as RegExp

{
	match: 'https?:\\\/\\\/www\\\\.github\\\\.com',
    suggest: 'github.com'
}

How do we report?

  1. Message: Prefer `github.com`.
  2. Add pattern.message, and default to Prefer `github.com`.
  3. Report the pattern, Message Prefer `github.com` over `/https\?:\/\/www\\.github\\.com/gu`.
  4. Don't support RegExp

Another problem, this rule original idea to fix ' to , so default to

[
	{
	  match: '\\'',
	  suggest: '‘',
	}
]

patterns should override or append? or more option?

@sindresorhus
Copy link
Owner

How do we report?

I would go with both 2 and 3. Default to 3, but allow overriding the message.

patterns should override or append? or more option?

We could make the key be the match:

{
	'\\'': {
		suggest: '‘'
	}
}

And allow setting it to false. Then the user could either override or disable with:

{
	'\\'': false
}

@sindresorhus
Copy link
Owner

Rewarding this issue is blocked by a dumb IssueHunt bug: https://spectrum.chat/issuehunt/general/error-when-accessing-an-issue-page~edd3be59-9228-472f-ae32-ce888e56bc1c?m=MTU4MzcyNjY3MjIxOQ==

@isghe
Copy link

isghe commented Mar 13, 2020

It's a dangerous rule xojs/xo#439 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💵 Funded on Issuehunt This issue has been funded on Issuehunt help wanted new rule
Projects
None yet
6 participants