diff --git a/README.org b/README.org index a52c156..8794b52 100644 --- a/README.org +++ b/README.org @@ -30,8 +30,9 @@ Regardless of where you installed solidity mode from, you need to require the pa #+END_SRC (append that line to your =~/.emacs= file) -** Provide path to solc binary -The ~solc~ binary is assumed to be located at ~/usr/bin/solc~. Wherever that is not the case you would have to manually +** Interface with linters +*** Provide path to solc binary +The ~solc~ binary is assumed to be part of the PATH. Wherever that is not the case you would have to manually set the location of the binary like below: #+BEGIN_SRC emacs-lisp (setq solidity-solc-path "/home/lefteris/ew/cpp-ethereum/build/solc/solc") @@ -39,11 +40,55 @@ set the location of the binary like below: Note: This better be set before requiring solidity mode. +*** Provide path to solium binary +The ~solium~ binary is assumed to be part of the user's ~PATH~. If this is not the case +then set its location like below: +#+BEGIN_SRC emacs-lisp +(setq solidity-solium-path "/home/lefteris/.npm-global/bin/solium") +#+END_SRC + + ** [Optional] Flycheck interface Solidity mode can also interface with [[https://github.com/flycheck/flycheck][flycheck]] if you have it. Make sure to download and install the flycheck package. Then configure it to either work on all modes or enable it only for solidity mode. +Flycheck can interface either with solc or with [[http://solium.readthedocs.io/en/latest/][solium]]. Choose the appropriate +linter to use by providing the following in your emacs init: + +#+BEGIN_SRC emacs-lisp +(setq solidity-flycheck-active-checker "solium") +#+END_SRC + +If you want to use ~"solc"~ replace ~"solium"~ with it. + +Keep in mind that you need to provide the path to either solc or solium unless +emacs can already find it in your environment's ~PATH~. Even if you can call it +from the command line it does not mean that EMACS can see it as emacs may be started +by systemd at which point ~PATH~ is not fully populated. + +*** Configuring solc checker + +You can configure flycheck's solc invocation with the following arguments + +**** std contracts +By default this is false. If you want to include the standard contracts just add the following to your emacs init file + +#+BEGIN_SRC emacs-lisp +(setq flycheck-solidity-solc-addstd-contracts t) +#+END_SRC + +*** Configuring solium checker +You can configure flycheck's solium incocation with the following arguments + +**** solium RC file +By default solium looks at the current directory of the file you are editing in order to find ~.soliumrc.json~. Having this +file is required. But you can point to an external configuration file by putting the following anywhere in your emacs init file. + +#+BEGIN_SRC emacs-lisp +(setq flycheck-solidity-solium-soliumrcfile "/home/path/to/common/.soliumrc.json") +#+END_SRC + * Features + Syntax highlighting + Indentation diff --git a/solidity-mode.el b/solidity-mode.el index 8c9d111..79e6db6 100644 --- a/solidity-mode.el +++ b/solidity-mode.el @@ -4,7 +4,7 @@ ;; Author: Lefteris Karapetsas ;; Keywords: languages -;; Version: 0.1.3 +;; Version: 0.1.4 ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -43,12 +43,24 @@ "Callback hook to execute whenever a solidity file is loaded." :group 'solidity) -(defcustom solidity-solc-path "/usr/bin/solc" +(defcustom solidity-solc-path "solc" "Path to the solc binary." :group 'solidity :type 'string :package-version '(solidity . "0.1.1")) +(defcustom solidity-solium-path "solium" + "Path to the solium binary." + :group 'solidity + :type 'string + :package-version '(solidity . "0.1.4")) + +(defcustom solidity-flycheck-active-checker "solc" + "Choice of active checker. Either solc or solium." + :group 'solidity + :type 'string + :package-version '(solidity . "0.1.4")) + (defvar solidity-mode-map (let ((map (make-keymap))) (define-key map "\C-j" 'newline-and-indent) @@ -446,8 +458,9 @@ Highlight the 1st result." (when (eval-when-compile (require 'flycheck nil 'noerror)) ;; Avoid reference to free variable warnings (defvar flycheck-solidity-checker-executable) + (defvar flycheck-solium-checker-executable) - (flycheck-def-option-var flycheck-solidity-addstd-contracts nil solidity-checker + (flycheck-def-option-var flycheck-solidity-solc-addstd-contracts nil solidity-checker "Whether to add standard solidity contracts. When non-nil, enable add also standard solidity contracts via @@ -456,6 +469,17 @@ When non-nil, enable add also standard solidity contracts via :safe #'booleanp :package-version '(solidity-mode . "0.1.3")) + (flycheck-def-option-var flycheck-solidity-solium-soliumrcfile nil solium-check + "The path to use for soliumrc.json + +The value of this variable is either a string denoting a path to the soliumrc.json +or nil, to use the current directory. When non-nil, +we pass the directory to solium via the `--config' option." + :type '(choice (const :tag "No custom soliumrc" nil) + (string :tag "Custom soliumrc file location")) + :safe #'stringp + :package-version '(solidity-mode . "0.1.4")) + ;; add dummy source-inplace definition to avoid errors (defvar source-inplace t) ;; add a solidity mode callback to set the executable of solc for flycheck @@ -463,7 +487,7 @@ When non-nil, enable add also standard solidity contracts via (flycheck-define-checker solidity-checker "A Solidity syntax checker using the solc compiler" :command ("solc" - (option-flag "--add-std" flycheck-solidity-addstd-contracts) + (option-flag "--add-std" flycheck-solidity-solc-addstd-contracts) source-inplace) :error-patterns ((error line-start (file-name) ":" line ":" column ":" " Error: " (message)) @@ -471,11 +495,44 @@ When non-nil, enable add also standard solidity contracts via (warning line-start (file-name) ":" line ":" column ":" " Warning: " (message))) :modes solidity-mode :predicate (lambda () (eq major-mode 'solidity-mode))) - (add-to-list 'flycheck-checkers 'solidity-checker) - (add-hook 'solidity-mode-hook - (lambda () - (let ((solidity-command (concat solidity-solc-path))) - (setq flycheck-solidity-checker-executable solidity-command))))) + + ;; define solium flycheck syntax checker + (flycheck-define-checker solium-checker + "A Solidity linter using solium" + :command ("solium" + (option "--config=" flycheck-solidity-solium-soliumrcfile concat) + "-f" + source-inplace) + :error-patterns + ((error line-start (zero-or-more " ") line ":" column (zero-or-more " ") "error" (message)) + (error line-start (zero-or-more not-newline) "[Fatal error]" (message)) + (warning line-start (zero-or-more " ") line ":" column (zero-or-more " ") "warning" (message))) + :error-filter + ;; Add fake line numbers if they are missing in the lint output + (lambda (errors) + (dolist (err errors) + (unless (flycheck-error-line err) + (setf (flycheck-error-line err) 1))) + errors) + :modes solidity-mode + :predicate (lambda () (eq major-mode 'solidity-mode))) + + (when (string= solidity-flycheck-active-checker "solc") + (if (file-executable-p solidity-solc-path) + (progn + (add-to-list 'flycheck-checkers 'solidity-checker) + (add-hook 'solidity-mode-hook + (lambda () + (let ((solidity-command (concat solidity-solc-path))) + (setq flycheck-solidity-checker-executable solidity-command))))) + (error (format "Solidity Mode Configuration error. Requested solc flycheck integration but can't find solc at: %s" solidity-solc-path)))) + + (when (string= solidity-flycheck-active-checker "solium") + (if (file-executable-p solidity-solium-path) + (progn + (add-to-list 'flycheck-checkers 'solium-checker) + (setq flycheck-solium-checker-executable solidity-solium-path)) + (error (format "Solidity Mode Configuration error. Requested solium flycheck integration but can't find solium at: %s" solidity-solium-path))))) (provide 'solidity-mode) ;;; solidity-mode.el ends here