Code Monkey home page Code Monkey logo

syntaxerl's Introduction

Build Status

SyntaxErl

SyntaxErl is a syntax checker tool for Erlang. The syntax checker currently supports erlang source files (.erl), erlang header files (.hrl), erlang configs (.config, .rel, .script, .app, .app.src), escript files (.erl, .escript, .es), leex files (.xrl), and yecc files (.yrl). Its main purpose is to be used by tools like Emacs's Flymake and Vim's Syntastic or ALE.

SyntaxErl uses rebar, rebar3 or erlang.mk configs under the hood to determine deps and libs paths. Some common compile options are hardcoded, while others project specific are read from the config files. For the syntax checker to work correctly, make sure that your project is compilable and all the deps are at their places.

Building

Information on building and installing Erlang/OTP can be found here (more info).

Dependencies

To build SyntaxErl you will need a working installation of Erlang, git, and GNU make.

Building SyntaxErl

$ git clone git://github.com/ten0s/syntaxerl.git
$ cd syntaxerl
$ make

After performing the steps above in the current working directory you now have a script called `syntaxerl'. Place this script anywhere in your path.

Usage

Command line

$ syntaxerl
Syntax checker for Erlang (0.16.0)
Usage: syntaxerl [-d | --debug] <FILENAME>
       syntaxerl <-h | --help>
  -d, --debug    Enable debug output
  -h, --help     Show this message

Emacs

Flymake

;;;----------------------------------------
;;; erlang-mode
;;;----------------------------------------

(setq erlang-root-dir "/opt/r16b03-1")
(setq load-path (cons (car (file-expand-wildcards (concat erlang-root-dir "/lib/tools-*/emacs"))) load-path))
(setq erlang-electric-commands nil)
(require 'erlang-start)

(add-hook 'erlang-mode-hook
  '(lambda()
     (imenu-add-to-menubar "Imenu")))

; define auto erlang mode for these files/extensions.
(add-to-list 'auto-mode-alist '(".*\\.app\\'"     . erlang-mode))
(add-to-list 'auto-mode-alist '(".*app\\.src\\'"  . erlang-mode))
(add-to-list 'auto-mode-alist '(".*\\.config\\'"  . erlang-mode))
(add-to-list 'auto-mode-alist '(".*\\.rel\\'"     . erlang-mode))
(add-to-list 'auto-mode-alist '(".*\\.script\\'"  . erlang-mode))
(add-to-list 'auto-mode-alist '(".*\\.escript\\'" . erlang-mode))
(add-to-list 'auto-mode-alist '(".*\\.es\\'"      . erlang-mode))
(add-to-list 'auto-mode-alist '(".*\\.xrl\\'"     . erlang-mode))
(add-to-list 'auto-mode-alist '(".*\\.yrl\\'"     . erlang-mode))

; add include directory to default compile path.
(defvar erlang-compile-extra-opts
  '(bin_opt_info debug_info (i . "../include") (i . "../deps") (i . "../../") (i . "../../../deps")))

; define where put beam files.
(setq erlang-compile-outdir "../ebin")

;;;----------------------------------------
;;; flymake
;;;----------------------------------------

(require 'flymake)
(require 'flymake-cursor) ; http://www.emacswiki.org/emacs/FlymakeCursor
(setq flymake-log-level 3)

(defun flymake-compile-script-path (path)
  (let* ((temp-file (flymake-init-create-temp-buffer-copy
                     'flymake-create-temp-inplace))
         (local-file (file-relative-name
                      temp-file
                      (file-name-directory buffer-file-name))))
    (list path (list local-file))))

(defun flymake-syntaxerl ()
  (flymake-compile-script-path "~/bin/syntaxerl"))

(add-hook 'erlang-mode-hook
  '(lambda()
     (add-to-list 'flymake-allowed-file-name-masks '("\\.erl\\'"     flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.hrl\\'"     flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.xrl\\'"     flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.yrl\\'"     flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.app\\'"     flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.app.src\\'" flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.config\\'"  flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.rel\\'"     flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.script\\'"  flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.escript\\'" flymake-syntaxerl))
     (add-to-list 'flymake-allowed-file-name-masks '("\\.es\\'"      flymake-syntaxerl))

     ;; should be the last.
     (flymake-mode 1)
))

; see /usr/local/lib/erlang/lib/tools-<Ver>/emacs/erlang-flymake.erl
(defun erlang-flymake-only-on-save ()
  "Trigger flymake only when the buffer is saved (disables syntax
check on newline and when there are no changes)."
  (interactive)
  ;; There doesn't seem to be a way of disabling this; set to the
  ;; largest int available as a workaround (most-positive-fixnum
  ;; equates to 8.5 years on my machine, so it ought to be enough ;-) )
  (setq flymake-no-changes-timeout most-positive-fixnum)
  (setq flymake-start-syntax-check-on-newline nil))

(erlang-flymake-only-on-save)

Erlang-flymake

Your help is welcome.

Vim

Syntastic

Setup everything as described here. Then add

let g:syntastic_erlang_checkers=['syntaxerl']

to your vimrc.

Thanks locojay for that.

ALE

Install ALE plugin for vim 8+ or neovim.

To disable erlc linter please add the following lines to your vimrc:

let g:ale_linters = {
\   'erlang': ['syntaxerl'],
\}

syntaxerl's People

Contributors

dmitrivereshchagin avatar dumbbell avatar sideshowcoder avatar stwind avatar ten0s avatar urbanserj avatar

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

syntaxerl's Issues

OTP 18 support

Hi ๐Ÿ˜ธ

To be safe when pulling in OTP18 for Homebrew we need to know that your syntax checker tool supports OTP18 or at least doesn't break using it. What's the current status on this?

Thanks โค๏ธ

Erros with -include_lib detection

Hi guys,

I tried to use the syntaxerl at https://github.com/2600hz/kazoo, a relatively complex project, and noticed that all -include_libs are getting errors.

For example, at applications/callflows/src/callflow.hrl file, I got the following error in a vim+syntastic+sytaxerl enviroment:
" can't find include lib "whistle/include/wh_types.hrl" [erlang/syntaxerl]

I saw the same problem with vimerl, which also uses rebar.

Make a release

I'd like to put this into Homebrew, but they prefer to have a released version to work against (rather that head of master). Would you mind tagging one?

Here's a skeletal Homebrew formula that works right now (but doesn't meet submission guidelines):

class Syntaxerl < Formula
  homepage ""
  url "https://github.com/ten0s/syntaxerl.git"
  version "1.0.0"
  sha256 ""

  depends_on "erlang" => :build

  def install
    system "make"
    system "mkdir", "-p", "#{prefix}/bin"
    system "cp", "syntaxerl", "#{prefix}/bin/syntaxerl"
  end

  test do
    # simple test that we can self-check
    system "syntaxerl", "src/syntaxerl.erl"
  end
end

Crash when running

I get the following crash:

$ syntaxerl src/meck.erl
escript: exception error: no function clause matching 
                 syntaxerl:get_handler("src/meck.erl",undefined) (src/syntaxerl.erl, line 94)
  in function  syntaxerl:check_syntax/2 (src/syntaxerl.erl, line 40)
  in call from escript:run/2 (escript.erl, line 727)
  in call from escript:start/1 (escript.erl, line 277)
  in call from init:start_it/1 
  in call from init:start_em/1 

syntaxerl can't build absolute paths with certain rebar configuration

I think syntaxerl bugs out when multiple rebar.config files are visible

[wmealing@work-laptop] $ find | grep rebar | grep -v deps
./sensors/sms/rebar.config
./sensors/rebar.config
./rebar.config
./apps/adj_frontend/rebar.config
./apps/adj_backend/rebar.config
./apps/rebar.config

[wmealing@work-laptop ]$ ~/bin/syntaxerl sensors/sms/src/sms_worker.erl
escript: exception error: no function clause matching
filename:join("/home/wmealing/Source/adjutant-erlang",112) (filename.erl, line 406)
in function lists:map/2 (lists.erl, line 1173)
in call from syntaxerl_utils:rebar_deps_opts/1 (src/syntaxerl_utils.erl, line 106)
in call from syntaxerl_utils:rebar_deps_opts/1 (src/syntaxerl_utils.erl, line 102)
in call from syntaxerl_utils:deps_opts/3 (src/syntaxerl_utils.erl, line 50)
in call from syntaxerl_utils:incls_deps_opts/1 (src/syntaxerl_utils.erl, line 41)
in call from syntaxerl_erl:check_syntax/2 (src/syntaxerl_erl.erl, line 10)
in call from syntaxerl:check_syntax/2 (src/syntaxerl.erl, line 42)

If i move the rebar.config's out of the way, it works correctly.

[wmealing@work-laptop ]$ mv sensors/rebar.config.old ^C
[wmealing@work-laptop ]$ mv rebar.config rebar.config.old
[wmealing@work-laptop ]$ ~/bin/syntaxerl sensors/irc/src/irc_worker.erl

More details or a simplified test case can be provided if you require.

Relative include paths aren't correctly resolved

I have the following source layout:

./rebar.config
./deps/
./deps/amqp_client/include/amqp_client.hrl
./apps/foo/rebar.config
./apps/foo/src/foo_bar.erl

./apps/foo/rebar.config has {erl_opts, [{i, "../../deps/amqp_client/include"}]}. Note that the path given is relative to rebar.config. rebar compile handles this correctly when run from the top-level folder.

When running syntaxerl from ./apps/foo/src (I have vim configured to follow the directory of the open file, so I'm replicating that), like this:

.../apps/foo/src$ syntaxerl foo_bar.erl

... it seems to resolve the include path relative to the current directory, rather than the location of the rebar.config file.

This means that it reports that the .hrl file cannot be found; but it can, according to rebar.

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.