Regarding adding additional default font-lock faces

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Regarding adding additional default font-lock faces

Jostein Kjønigsen
Hey everyone.

When considering expanding on things which gets fontified in  typescript-mode (a third-party major-mode), we noticed that some fairly common use-cases don't have any appropriate font-lock-face variable to use, meaning major-mode developers will have to make their own, one new defface for each mode.

Examples of such use-cases and faces would be:

  • function/method-call (that is invocation, not declaration)
  • attributes/annotations for functions, classes, not to mention function-parameters

I'm sure there are more, but those are at least some  examples.

Not having a default font-face for this forces third-party packages which rely on standard font-lock-faces for most values, to introduce inconsistency by then suddenly creating some custom deffaces, which are namespaced to their own package.

Add this up to several packages, and it can get messy. No theme will certainly support this properly.

What does the emacs-community feel about expanding on the set of default font-lock faces to include values for these? And how do we decided which faces we should add?

--
Kind Regards
Jostein Kjønigsen


Reply | Threaded
Open this post in threaded view
|

Re: Regarding adding additional default font-lock faces

Stefan Monnier
>  * function/method-call (that is invocation, not declaration)

The standard face to use for these is the nil face.

>  * attributes/annotations for functions, classes,

I don't know what this refers to.  Which languages have those?

>    not to mention function-parameters

These also use the nil "standard face".

> What does the emacs-community feel about expanding on the set of default
> font-lock faces to include values for these? And how do we decided which
> faces we should add?

I'm not a big "angry fruit salad" fan, so I don't have a strong opinion
on these: I think it's OK if most of the code uses the default face, and
if people introduce new faces for "variable reference", "function call",
"number", "method call", "field access", "indirect function call",
"inlinable function call", ... I'll just tweak those faces to look like
the default face.


        Stefan


Reply | Threaded
Open this post in threaded view
|

Re: Regarding adding additional default font-lock faces

Jostein Kjønigsen
Hey Stefan.

Thanks for your reply.

I'm not a big "angry fruit salad" fan, so I don't have a strong opinion
on these

Absolutely fair. People do have preferences and they do differ.

I think it's OK if most of the code uses the default face, and
if people introduce new faces for "variable reference", "function call",
"number", "method call", "field access", "indirect function call",
"inlinable function call", ... I'll just tweak those faces to look like
the default face.

A corner-stone of Emacs is that the user should be able to adapt almost any aspect of it to his own needs and desires. Like you do here.

But wouldn't this be easier and better if there was one standard face for this for you to customize? As opposed to each major-mode creating their own face which you then have to customize "away"?

* function/method-call (that is invocation, not declaration)

The standard face to use for these is the nil face.

Which is fine. But can't we have a defface for this whose default value is nil?

That way major-modes have one standard variable to use, and users have one standard variable to customize.  I think that's a whole lot easier for everyone.

Not to mention this puts the user in control of their own experience, like Emacs should.

* attributes/annotations for functions, classes,

I don't know what this refers to.  Which languages have those?

  not to mention function-parameters

These also use the nil "standard face".


To be clear I meant annotations/attributes applied to function-parameters, not function parameters itself.

In C# it can look like this:

    [DataContract]
    public class QueryInfo
    {
        [DataMember(Order = 0)]
        public int ContactId { get; set; }

        [DataMember(Order = 1)]
        public int PersonId { get; set; }

        [DataMember(Order = 2)]
        public int ProjectId { get; set; }

        [DataMember(Order = 3)]
        public int SaleId { get; set; }
    }

Here the attributes [DataContract] is applied to the class itself and and [DataMember] is applied to its member-fields.

Another C# example where attributes are applied to function-parameters is typically invocation of platform native-functions:

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr CreateFileA(
     [MarshalAs(UnmanagedType.LPStr)] string filename,
     [MarshalAs(UnmanagedType.U4)] FileAccess access,
     [MarshalAs(UnmanagedType.U4)] FileShare share,
     IntPtr securityAttributes,
     [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
     [MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
     IntPtr templateFile);

In Typescript annotations/attributes looks like this:

@Component()
class Foo {
    //
}

Basically, attributes/annotations is a fairly well known and implemented concept throughout various programming languages. Java supports it. PHP supports it. And I'm sure a dozen other languages.

Given that it's a common concept, it therefore seems odd to me that Emacs should be ignorant of it.

I can see how some people prefer not to have "angry fruit saled", and that's fair.

But I think in the spirit of putting the user in controls, Emacs should provide some standard faces (whose default value may be nil) in place for those who do want additional highlighting. This would also empower theme-makers to provide richer themes, for those who want it.

I can't really see any obvious down-sides to adding some new faces for people to use and customize.

--
Regards
Jostein Kjønigsen



On Wed, Aug 1, 2018, at 11:53 PM, Stefan Monnier wrote:
* function/method-call (that is invocation, not declaration)

The standard face to use for these is the nil face.

* attributes/annotations for functions, classes,

I don't know what this refers to.  Which languages have those?

  not to mention function-parameters

These also use the nil "standard face".

What does the emacs-community feel about expanding on the set of default
font-lock faces to include values for these? And how do we decided which
faces we should add?

I'm not a big "angry fruit salad" fan, so I don't have a strong opinion
on these: I think it's OK if most of the code uses the default face, and
if people introduce new faces for "variable reference", "function call",
"number", "method call", "field access", "indirect function call",
"inlinable function call", ... I'll just tweak those faces to look like
the default face.


        Stefan



Reply | Threaded
Open this post in threaded view
|

Re: Regarding adding additional default font-lock faces

Stefan Monnier
> Which is fine. But can't we have a defface for this whose default
> value is nil?
> That way major-modes have one standard variable to use, and users have
> one standard variable to customize.  I think that's a whole lot easier
> for everyone.
> Not to mention this puts the user in control of their own experience,
> like Emacs should.

Of course.

I think the current design is strongly influenced by efficiency
considerations rather than by someone deciding that those constructs
shouldn't have their specific highlighting.

>>> * attributes/annotations for functions, classes,
>> I don't know what this refers to.  Which languages have those?
> To be clear I meant annotations/attributes *applied to* function-
> parameters, not function parameters itself.
> In C# it can look like this:
>
>>     [DataContract]
>>     public class QueryInfo
>>     {
>>         [DataMember(Order = 0)]
>>         public int ContactId { get; set; }
>>
>>         [DataMember(Order = 1)]
>>         public int PersonId { get; set; }
>>
>>         [DataMember(Order = 2)]
>>         public int ProjectId { get; set; }
>>
>>         [DataMember(Order = 3)]
>>         public int SaleId { get; set; }
>>     }

Ah, right, thanks.  I never use languages where this is used, but now
that I see it, I do remember having heard of it.


        Stefan

Reply | Threaded
Open this post in threaded view
|

Re: Regarding adding additional default font-lock faces

Nathan Moreau
Hello,

> Ah, right, thanks.  I never use languages where this is used, but now
> that I see it, I do remember having heard of it.
>
>

Another examples:
- Recent versions of ocaml has something similar:
http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s%3Aattributes

- c++ as well : https://en.cppreference.com/w/cpp/language/attributes

- One can maybe argue that python decorators could be fontified as
function attributes?



Nathan

On 2 August 2018 at 13:53, Stefan Monnier <[hidden email]> wrote:

>> Which is fine. But can't we have a defface for this whose default
>> value is nil?
>> That way major-modes have one standard variable to use, and users have
>> one standard variable to customize.  I think that's a whole lot easier
>> for everyone.
>> Not to mention this puts the user in control of their own experience,
>> like Emacs should.
>
> Of course.
>
> I think the current design is strongly influenced by efficiency
> considerations rather than by someone deciding that those constructs
> shouldn't have their specific highlighting.
>
>>>> * attributes/annotations for functions, classes,
>>> I don't know what this refers to.  Which languages have those?
>> To be clear I meant annotations/attributes *applied to* function-
>> parameters, not function parameters itself.
>> In C# it can look like this:
>>
>>>     [DataContract]
>>>     public class QueryInfo
>>>     {
>>>         [DataMember(Order = 0)]
>>>         public int ContactId { get; set; }
>>>
>>>         [DataMember(Order = 1)]
>>>         public int PersonId { get; set; }
>>>
>>>         [DataMember(Order = 2)]
>>>         public int ProjectId { get; set; }
>>>
>>>         [DataMember(Order = 3)]
>>>         public int SaleId { get; set; }
>>>     }
>
> Ah, right, thanks.  I never use languages where this is used, but now
> that I see it, I do remember having heard of it.
>
>
>         Stefan
>

Reply | Threaded
Open this post in threaded view
|

Re: Regarding adding additional default font-lock faces

Jostein Kjønigsen
In reply to this post by Stefan Monnier
On Thu, Aug 2, 2018, at 1:53 PM, Stefan Monnier wrote:
Which is fine. But can't we have a defface for this whose default
value is nil?
Of course.

OK. Sounds good.

In which case... Where do I start?

Do I just start hacking at lisp/font-lock.el and send in patches, or should we discuss which faces would be useful to add first?

Personally I see at least a need for:

  • font-lock-function-call-face
  • font-lock-decorator-face ("decorator" is another commonly used for the "attribute" concept and less likely to be confused with for instance HTML/XML attributes)

Are there any other nice-to-have default faces anyone can think of?

Besides the actual LISP-code itself... What's the process for documenting such changes? What other "house-keeping" needs to go with such a code-change?

Let me know, and I'll try to get it done.

--
Regards
Jostein Kjønigsen




Reply | Threaded
Open this post in threaded view
|

Re: Regarding adding additional default font-lock faces

Stefan Monnier
> Do I just start hacking at lisp/font-lock.el and send in patches, or
> should we discuss which faces would be useful to add first?

Each face will need to be justified, but you can send a sample patch
along with that justification.

>  * font-lock-function-call-face
>  * font-lock-decorator-face ("decorator" is another commonly used for
>    the "attribute" concept and less likely to be confused with for
>    instance HTML/XML attributes)
> Are there any other nice-to-have default faces anyone can think of?

If you can't think of others right now, then I recommend you stick to
those two for now.

Issues that come to mind:
- For me a "function call" is made of both a function and some number
  of arguments.  So it would be good to clarify to which part
  font-lock-function-call-face is meant to apply (the "function" part,
  I assume).  Also, clarify how it would be used in the case of method
  calls (I guess, just highlight the method name).
- Maybe the more difficult technical part will be to come up with a good
  default definition for those faces: just like for the other
  font-lock-*-faces, it should cover light and dark backgrounds, and it
  should maintain a good contrast.

Finally, to justify their introduction, it would be useful to be able to
point to existing Elisp packages which define/use their own faces for
those uses.

> Besides the actual LISP-code itself... What's the process for
> documenting such changes? What other "house-keeping" needs to go with
> such a code-change?

The addition needs to be mentioned in etc/NEWS and

    grep font-lock-keyword-face **/*.texi

will show you where they're documented (i.e. doc/lispref/modes.texi)


        Stefan