Giter Site home page Giter Site logo

crystal-lang-tools / emacs-crystal-mode Goto Github PK

View Code? Open in Web Editor NEW
47.0 47.0 19.0 267 KB

A minimal crystal mode for emacs, based on ruby-mode.

Home Page: https://melpa.org/#/crystal-mode

License: GNU General Public License v3.0

Emacs Lisp 99.92% Makefile 0.08%
crystal emacs

emacs-crystal-mode's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emacs-crystal-mode's Issues

Jumping to definition in project

So, given two files, for example:

lib/x.cr

class X
end
require "./x/y"

lib/x/y.cr

class Y < X
end

It seems I can't jump to the definition of X I get undefined constant X.

I'm not sure how that could be resolved, how do i tell it what my top level entry file is?

Include snippets

It would be nice to have this include yasnippets for commonly used patterns like

module ModuleName
end

class ClassName
end

etc

crystal-mode and tree-sitter

emacs 29.1 will be getting native tree-sitter support and a number of major modes are currently being converted to utilize exactly that.

It would be awesome to have both tree-sitter support for crystal and a crystal-ts-mode to make use of it.

I don't realistically think I will have time to do it, but I would love to get it going....

Indenting for #[]? fails

Indented by crystal mode:

a = Array.new(String)
a << "b"
if a[0] == "b"
  puts "hi"
elsif a.[0]? == "b"
             puts "hi"
      elsif a[0]? == "b"
                  puts hi
end

Indenting with crystal tool format works.

Emacs gettings stuck

Hi, my emacs is getting stuck whenever I run crystal-beginning-of-block and crystal-end-of-block.

Indentaion of two dimensional array fails when type hint is given

Indentation of two dimensional arrays works fine if not type hint is given for the internal arrays. But if you try to indent two dimensional arrays with type hints it all goes wrong. It especially renders a code with hard-coded large two dimensional arrays unreadable the behavior is as shown below.

[[1,2,3,4],
 [5,5,6,7]]


[[1, 2, 3] of UInt8,
              [4, 5, 6] of UInt8]

doesn't parse {% end %} properly

i've got a macro def similar to this:

class Form
  def self.whatever
    {% for var in @type.instance.instance_vars %}
	  # do things here
    {% end %}
  end
end

but crystal-mode parses the {% end %} tag as just a normal end keyword, leading to it thinking the final end (for the class) is extra and a syntax error

forward-sexp position error.

Plese check following code:

def self.get_user_by_auth_token(auth_token)
  decoded_open_id = decoded["open_id"]?

  if decoded_auth_token_salt.nil?
    return nil
  end

  user
end

When the cursor is upon the def, after pressing C-M-F, What we expected is to jump to the last line after end.

But, the actual behavior is: (cursor is I)

def self.get_user_by_auth_token(auth_token)
  decoded_open_id = decoded["open_id"]?

  if decoded_auth_token_salt.nil?
    return nil
  endI

  user
end

the jumped position is after the end of if.

Indenting fails for []?

( Can't reopen #12 )

unless ENV["TIPBOT_ENV"]? == "test"
                          puts "No Config File specified! Exiting!" if ARGV.size == 0

Formats correctly with tool...

crystal-smie--backward-token: Error running timer ‘show-paren-function’: (search-failed "{%")

Example input:

%{ if flag?(:foo) %}
  bar
%{ end %}

When I move the cursor to the "b" in bar or the two white spaces before it, it throws the following error:

Debugger entered--Lisp error: (search-failed "{%")
  re-search-backward("{%")
  ...
  crystal-smie--backward-token()
  smie--opener/closer-at-point()
  smie--matching-block-data(#f(compiled-function (&rest args) #<bytecode -0x1d15d4b1af694f36>))
  apply(smie--matching-block-data #f(compiled-function (&rest args) #<bytecode -0x1d15d4b1af694f36>) nil)
  #f(advice-wrapper :around #f(compiled-function (&rest args) #<bytecode -0x1d15d4b1af694f36>) smie--matching-block-data)()
  show-paren-function()
  apply(show-paren-function nil)
  timer-event-handler([t 0 0 125000 t show-paren-function nil idle 0 nil])

It also moves the cursor, which means you have to disable crystal-mode if you want to edit.

My current workaround is to modify the function crystal-smie--backward-token:

(defun crystal-smie--backward-token ()

Putting a ignore-errors around the body suppresses the error and cursor doesn't jump. I don't know if that is a good solution (to try it out I created a PR: #53).

Don't indent correct for chaining if add comment at end of line.

e.g. following code when indent with emacs builtin ruby-mode (without LSP enabled), it will indent like this:

# test.rb, it correct.
result = (42..47).to_a                          # (1) => [42, 43, 44, 45, 46, 47]
           .sort { |n, m| m <=> n }             # (2) => [47, 46, 45, 44, 43, 42]
           .reject { |n| n.odd? }               # (3) => [46, 44, 42]
           .map { |n| n * n }                   # (4) => [2116, 1936, 1764]
           .select { |n| n % 4 == 0 }           # (5) => [2116, 1936, 1764]
           .tap { |arr| puts "#{arr.inspect}" } # (6) => [2116, 1936, 1764]
           .sort!                               # (7) => [1764, 1936, 2116]
           .any? { |num| num > 2000 }           # (8) => true

but, if switch to crystal-mode, it indent like this:

# test1.cr,  indent not correct

result = (42..47).to_a                          # (1) => [42, 43, 44, 45, 46, 47]
  .sort { |n, m| m <=> n }             # (2) => [47, 46, 45, 44, 43, 42]
    .reject { |n| n.odd? }               # (3) => [46, 44, 42]
      .map { |n| n * n }                   # (4) => [2116, 1936, 1764]
        .select { |n| n % 4 == 0 }           # (5) => [2116, 1936, 1764]
          .tap { |arr| puts "#{arr.inspect}" } # (6) => [2116, 1936, 1764]
            .sort!                               # (7) => [1764, 1936, 2116]
              .any? { |num| num > 2000 }           # (8) => true

But, if remove the those comment from line ending, it indent correct again.

# test2.cr, indent correct.
result = (42..47).to_a
         .sort { |n, m| m <=> n }
         .reject { |n| n.odd? }
         .map { |n| n * n }
         .select { |n| n % 4 == 0 }
         .tap { |arr| puts "#{arr.inspect}" }
         .sort!
         .any? { |num| num > 2000 }

case-in doesn't indent properly

The in statement inside a case block doesnt indent properly

It should be flush with the case, like the when keyword, but instead indents by 4 or 2 spaces, depending on how many are present.

Using flycheck-crystal in practice

How do you generally use flycheck-crystal? I find that it's basically useless for lots of perfectly fine code because compiling the source file you're editing on its own can give errors about missing namespaces or namespaces that are incorrectly loaded as modules when they should be classes.

This is not an issue for real-world compilation as the compilation targets (such as bin/something or spec/something_test.cr) usually follow a pattern of calling a main module/class file (e.g. src/something.cr) which loads everything and does so in the correct order.

I thought about extending the call to flycheck-define-checker to also compile spec/spec_helper.cr if it exists, but that's not so clean since a lot of projects use it to set up mocks and other things.

Indenting fails

struct Test
  DB.mapping({
               test: String,
             })
end

The example above gets indented correctly with the tool format, not in emacs though.

Indentation error for abstruct class

abstract class Shape
  abstract def area
  abstract def perim
end

Will indent to:

abstract class Shape
  abstract def area
    abstract def perim
    end

Thank you.

Support abstract syntax

I need the support for the abstract syntax

Current indent behavior is

abstract class Bra
  abstract def hoge
    abstract def fuga
      abstract def hoga
      ...
end

Better requires completion

Right now when requiring a file it completes the full path to the file, including the .cr extension. Using completion-at-point-functions it should be possible to make this complete just the filename and not the extension.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.