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

# is symbol instead of being a prefix #394

Closed
vspinu opened this issue Jul 14, 2016 · 10 comments
Closed

# is symbol instead of being a prefix #394

vspinu opened this issue Jul 14, 2016 · 10 comments

Comments

@vspinu
Copy link
Contributor

vspinu commented Jul 14, 2016

# is heavily used as prefix in clojure. Treating it as symbol causes problems with navigation that assumes prefix behavior for such symbols (Fuco1/smartparens#621).

The line of concern is this one introduced in f6b01fc. From the inline doc and commit message it's not clear why # should be different from other prefix symbols @'~.

@Malabarba
Copy link
Member

We need to check the proper meaning of these things in order to do them right thing. What's the difference between a prefix character and a symbol character with the prefix flag?

Could someone find this section on the elisp manual?

@bbatsov
Copy link
Member

bbatsov commented Jul 23, 2016

I'm guessing we're talking about this section - https://www.gnu.org/software/emacs/manual/html_node/elisp/Syntax-Class-Table.html

@vspinu
Copy link
Contributor Author

vspinu commented Jul 23, 2016

To quote:

Characters used for syntactic operators that are considered as part of an expression if they appear next to one.

That definition is not very helpful in our case as it doesn't say if those characters are also part of the symbols or not. In elisp prefix characters are never part of the symbol ('aaa and #aaa are not symbols in elisp).

In clojure # cannot be part of the symbol either as you cannot do (def aaa#bbb 1). Thus, the behavior of (symbol-at-point) on aaa#bbb is currently incorrect. @pjstadig, do you still remember why you made that change?

A more complicated case is that of ?. This is a legal symbol character in clojure but it's also used in conditional prefix notation:

#?(:clj     Double/NaN
   :cljs    js/NaN
   :default nil)

So even if this issues is fixed smartparents wont be working correctly for conditional prefixes (Fuco1/smartparens#621) but at least it will be working for all others.

It's worth pointing out that elisp has similar problem with @ character which is part of macro splicing prefix but is also a valid symbol character. Fortunately, in clojure @ cannot be part of the symbol, and thus prefix is a correct class for it. Same thing should happen for #.

@pjstadig
Copy link
Contributor

The change I made very well could have been incorrect. I believe the reason I made it was because forward slurping and navigating were working an a way that I found weird with something like #(foo bar) A slurp would first take the '#' alone, then the expression. Same for navigation.

If it should be changed, then I have no objection.

@bbatsov
Copy link
Member

bbatsov commented Jul 23, 2016

@vspinu Feel free to make the necessary change.

@vspinu
Copy link
Contributor Author

vspinu commented Jul 23, 2016

Actually there is a special p syntax flag specially designed for such cases as @ in elisp and ? in clojure.

‘p’ identifies an additional “prefix character” for Lisp syntax. These characters are treated as whitespace when they appear between expressions. When they appear within an expression, they are handled according to their usual syntax classes.

vspinu added a commit to vspinu/clojure-mode that referenced this issue Jul 23, 2016
  ? must be treated as a symbol inside symbols but as a prefix within
  conditional prefixes like #? and #?@.
@Fuco1
Copy link

Fuco1 commented Oct 23, 2016

I have no idea what this is supposed to mean

These characters are treated as whitespace when they appear between expressions.

In either case, I should probably add some logic to smartparens to work with this (presumably new) flag. That would simplify the regexp hack we use now for the prefixes which aren't syntactically marked.

slipset pushed a commit to slipset/clojure-mode that referenced this issue Nov 1, 2017
slipset pushed a commit to slipset/clojure-mode that referenced this issue Nov 1, 2017
  ? must be treated as a symbol inside symbols but as a prefix within
  conditional prefixes like #? and #?@.
@Fuco1
Copy link

Fuco1 commented Nov 11, 2017

I've just added support for the p syntax flag to smartparens. @vspinu You've contributed a regexp-based solution some time ago which recognizes the prefix: "\\(?:[@'#~,_?^]+\)"`. When I remove this there are some failing tests which means the syntax classes probably aren't set up 100% correctly in clojure mode still.

Would you be interested in writing a patch for clojure mode so we can remove the kludge code from smartparens? It seems you've already solved some of the cases.

@vspinu
Copy link
Contributor Author

vspinu commented Nov 11, 2017

I've just added support for the p syntax flag to smartparens.

Does this mean that if all characters in a sequence are marked as prefix, smartparens should work as expected? That is, skip all those when needed?

Would you be interested in writing a patch for clojure mode

Sure. I will have a look.

@Fuco1
Copy link

Fuco1 commented Nov 12, 2017

@vspinu My understanding is that they should be treated as a prefix only if they start the symbol. So any mix of characters in class ' or with the p flag at the beginning of a symbol/sexp/string is now recognized as a prefix.

If they are in the middle of a symbol, they should be part of that symbol (I'm now not entirely sure I did implement this part correctly :D I will check).

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

No branches or pull requests

5 participants