emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Guidelines for the "symbol" syntax class


From: Dmitry Gutov
Subject: Guidelines for the "symbol" syntax class
Date: Sun, 3 Jan 2016 07:09:39 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Thunderbird/43.0

Hi all and Stefan,

I intend to make some changes to the syntax of `:' in ruby-mode, and I'm wondering how far should that change go. I can remove it from the syntax table, but still apply it via syntax-propertize-function in other cases, see below.

Do we have any solid guidelines for that?

Context: my two main uses of the notion of symbol are 1) "all symbols in all buffer" completion candidates, 2) filtering the results of xref-find-references by checking that the match begins and ends at a symbol boundary. Currently, both of these features don't work well in ruby-mode.

First, "M::C" is interpreted as one symbol. If I just search for references to "C", this won't match. And vice versa, this qualified name usually corresponds to the definition like this:

module M
  class C
  end
end

so if I search for references to "M::C", this won't match either. So `:' should simply become "punctuation". Then the simplest approach will leave to false positives, but no false negatives.

There is another way `:' is used in Ruby: Ruby Symbols (I'm going to mention those only using a capital S, to distinguish). Which is like weird syntax for interned strings, but they're often used to refer to method names: for introspection, or when defining a method dynamically, or to dispatch a call dynamically. Examples:

class C
  def foo
  end
end

C.instance_method(:foo) # => #<UnboundMethod: C#foo>

class C
  define_method(:foo) do
    3
  end
end

C.new.send(:foo) # => 3

Consequently, if somewhere in my Ruby program there's a method foo_bar, it might be beneficial to be able to complete a Symbol :fo to :foo_bar as well, or for xref-find-references, when looking for references to this method, include the usages of Symbol :foo_bar.

Or take this example:

class C
  # attr_reader is a macro, kinda.
  # Define a method C#foo that simply returns the value
  # of the instance variable with the same name:
  attr_reader :foo

  def initialize(foo)
    # Assign that instance variable.
    @foo = foo
  end

  def do_something
    # Call the previously defined method (parens are optional)
    # and then call a method on the returned value:
    foo.do_something_amazing
  end
end

After writing the attr_reader call, it would be handy if I could use the name of the symbol in completion when writing the name of the argument, and the name of the variable (so there's also a question of whether @ should have the "symbol" syntax; it currently doesn't). And then later, when calling the method.

Another argument in favor of not having `:' be symbol constituents in Symbol literals is that we have two ways to write Hash (associative array) literal with Symbol keys:

{:key => value} and {key: value},

where the latter is syntactic sugar for the former. If `:' is not a symbol constituents, we won't have two superficially "different" symbols in the buffer, and the "find references" search will easily find both.

Or, should I stop trying to make the simplest general approaches work in ruby-mode, and write a dedicated xref backend for Ruby? One that would use etags and Grep, but use a bit smarter filtering.

What should company-dabbrev-code do? Should it use dabbrev-abbrev-char-regexp, which ruby-mode will then set?

Should both company-dabbrev-code and ruby-mode make use of dabbrev-abbrev-skip-leading-regexp? Note that it still won't help to avoid making {:key and {key: look like different symbols.

And if I do all that, what *will* be the purpose of making `:' remain symbol constituents inside Symbol literals?

Thanks all,
especially to those who've read all this ;-)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]