Discussion:
[Nano-devel] Some linters and syntax
Mark Oteiza
2015-03-30 23:40:14 UTC
Permalink
Hi,

With the new release, I got curious about nano and its new features, and
decided to play with it.

Emacs has flycheck, vim has syntastic. It's neat that nano now has
linter support. Here are some linters I found which worked with nano
(in .nanorc form):

extendsyntax c linter gcc -fshow-column
extendsyntax python linter pyflakes
extendsyntax ruby linter ruby -w -c
extendsyntax sh linter dash -n
extendsyntax tex linter chktex -v0 -q -I

It would be pretty convenient if nano shipped with some linter
definitions.

I also tried my hand at syntax files, writing ones for Guile scheme and
Emacs lisp. I'm sure they could use improvement, for instance:

* For Emacs lisp I don't know how to highlight multiline strings
(docstrings)
* In both lisps, if we want to highlight the `foo` function, there is
nothing stopping a function like `foo-bar` having just `foo`
highlighted, which looks weird.

I attached these syntax files. If any of this is desirable, I'd be
happy to send patches.

Mark
Benno Schulenberg
2015-03-31 15:12:57 UTC
Permalink
Hi Mark,
Post by Mark Oteiza
With the new release, I got curious about nano and its new features, and
decided to play with it.
Nice. :)
Post by Mark Oteiza
extendsyntax c linter gcc -fshow-column
When I run that on nano's src/color.c, it says (among many other things):
[ src/color.c:82:2: error: ‘colortype’ has no member named ‘next’ ].
But it does. What's up with that? (You may not; I just wonder.)
Post by Mark Oteiza
extendsyntax python linter pyflakes
When I run that, without pyflakes even being installed:
[ Got 0 parsable lines from command: pyflakes ]
So we need a better message when a command does not exist.
Post by Mark Oteiza
extendsyntax ruby linter ruby -w -c
extendsyntax sh linter dash -n
extendsyntax tex linter chktex -v0 -q -I
It would be pretty convenient if nano shipped with some linter
definitions.
It would. Chris? Okay to add?
Post by Mark Oteiza
I also tried my hand at syntax files, writing ones for Guile scheme and
* For Emacs lisp I don't know how to highlight multiline strings
(docstrings)
After a quick google for elisp docstring, it seems such a string
starts with some whitespace at the start of the line followed
by a doublequote. And it ends with a double quote at the end
of a line, with nothing after it. So... does this work:

color yellow start="^[[:blank:]]+\"" end="\"$"

Or if you think a doc string should always end with a period:

color yellow start="^[[:blank:]]+\"" end="\.\"$"
Post by Mark Oteiza
* In both lisps, if we want to highlight the `foo` function, there is
nothing stopping a function like `foo-bar` having just `foo`
highlighted, which looks weird.
I don't follow. Where in your elisp file is there a regex that
colours function names?

Benno
--
http://www.fastmail.com - Or how I learned to stop worrying and
love email again
Chris Allegretta
2015-03-31 19:45:31 UTC
Permalink
Post by Benno Schulenberg
Post by Mark Oteiza
It would be pretty convenient if nano shipped with some linter
definitions.
It would. Chris? Okay to add?
Yep, I think it's a small enough change to add linters to nanorc
definitions in the stable series that we can do so. It's just using a
feature we already created in the unstable series. Thanks for
checking!
Mark Oteiza
2015-04-16 06:46:04 UTC
Permalink
Hi,

... and here is a patch for the default linter definitions, except the c
one since that one was poor.

Cheers

Index: doc/syntax/python.nanorc
===================================================================
--- doc/syntax/python.nanorc (revision 5198)
+++ doc/syntax/python.nanorc (working copy)
@@ -2,6 +2,7 @@

syntax "python" "\.py$"
header "^#!.*python[-0-9._]*"
+linter pyflakes

# Function definitions.
icolor brightblue "def [0-9A-Z_]+"
Index: doc/syntax/ruby.nanorc
===================================================================
--- doc/syntax/ruby.nanorc (revision 5198)
+++ doc/syntax/ruby.nanorc (working copy)
@@ -2,6 +2,7 @@

syntax "ruby" "\.rb$"
header "^#!.*ruby[-0-9._]*"
+linter ruby -w -c

# Reserved words.
color yellow "\<(BEGIN|END|alias|and|begin|break|case|class|def|defined\?|do|else|elsif|end|ensure|false|for|if|in|module)\>"
Index: doc/syntax/sh.nanorc
===================================================================
--- doc/syntax/sh.nanorc (revision 5198)
+++ doc/syntax/sh.nanorc (working copy)
@@ -2,6 +2,7 @@
syntax "sh" "\.sh$"
header "^#!.*((ba|da|k|pdk)?sh[-0-9_]*|openrc-run|runscript)"
magic "(POSIX|Bourne.*) shell script text"
+linter dash -n

icolor brightgreen "^[0-9A-Z_]+\(\)"
color green "\<(break|case|continue|do|done|elif|else|esac|exit|fi|for|function|if|in|read|return|select|shift|then|time|until|while)\>"
Index: doc/syntax/tex.nanorc
===================================================================
--- doc/syntax/tex.nanorc (revision 5198)
+++ doc/syntax/tex.nanorc (working copy)
@@ -1,6 +1,7 @@
## Here is a short example for TeX files.

syntax "tex" "\.tex$"
+linter chktex -v0 -q -I

icolor green "\\.|\\[A-Z]*"
color magenta "[{}]"
Mike Frysinger
2015-04-18 20:01:23 UTC
Permalink
Post by Mark Oteiza
--- doc/syntax/python.nanorc (revision 5198)
+++ doc/syntax/python.nanorc (working copy)
+linter pyflakes
i use pylint myself, but not sure if this is getting into bikeshedding. looks
like pylint is more up-to-date and comprehensive ?
Post by Mark Oteiza
--- doc/syntax/sh.nanorc (revision 5198)
+++ doc/syntax/sh.nanorc (working copy)
+linter dash -n
why not `sh -n` ?
-mike
Mark Oteiza
2015-04-18 22:13:07 UTC
Permalink
Post by Mike Frysinger
Post by Mark Oteiza
--- doc/syntax/python.nanorc (revision 5198)
+++ doc/syntax/python.nanorc (working copy)
+linter pyflakes
i use pylint myself, but not sure if this is getting into bikeshedding. looks
like pylint is more up-to-date and comprehensive ?
Me neither (re: bikeshedding) as I have never used pylint myself.
However, now I realize I actually use flake8, which is just a wrapper
around pyflakes, pep8, and other linters… oops.
Post by Mike Frysinger
Post by Mark Oteiza
--- doc/syntax/sh.nanorc (revision 5198)
+++ doc/syntax/sh.nanorc (working copy)
+linter dash -n
why not `sh -n` ?
At least here on Arch Linux, where sh is linked to bash, nano does not
recognize the output. I tried some other shells and guessed that dash
would be a good choice. I know at least debian uses dash as its sh:

https://wiki.debian.org/Shell
Mike Frysinger
2015-04-19 05:37:02 UTC
Permalink
Post by Mark Oteiza
Post by Mike Frysinger
Post by Mark Oteiza
--- doc/syntax/sh.nanorc (revision 5198)
+++ doc/syntax/sh.nanorc (working copy)
+linter dash -n
why not `sh -n` ?
At least here on Arch Linux, where sh is linked to bash, nano does not
recognize the output. I tried some other shells and guessed that dash
you can't really assume any shell exists. but i don't know what problem you're
referring to wrt Arch/bash/sh. seems to work fine for me:
# touch test.sh
# bash -n test.sh
# dash -n test.sh
# ln -sf dash /bin/sh
# sh -n test.sh
# ln -sf bash /bin/sh
# sh -n test.sh

# echo '(' > test.sh
# sh -n test.sh
test.sh: line 2: syntax error: unexpected end of file
# bash -n test.sh
test.sh: line 2: syntax error: unexpected end of file
# dash -n test.sh
test.sh: 2: test.sh: Syntax error: end of file unexpected
# ln -sf dash /bin/sh
# sh -n test.sh
test.sh: 2: test.sh: Syntax error: end of file unexpected
# ln -sf bash /bin/sh
# sh -n test.sh
test.sh: line 2: syntax error: unexpected end of file
-mike
Mark Oteiza
2015-04-19 06:18:09 UTC
Permalink
Post by Mike Frysinger
Post by Mark Oteiza
where sh is linked to bash, nano does not
recognize the output.
# touch test.sh
# ln -sf bash /bin/sh
# sh -n test.sh
# echo '(' > test.sh
# sh -n test.sh
test.sh: line 2: syntax error: unexpected end of file
# bash -n test.sh
test.sh: line 2: syntax error: unexpected end of file
# dash -n test.sh
test.sh: 2: test.sh: Syntax error: end of file unexpected
Notice the difference in output between dash and bash. nano does not
know how to parse the output from bash because of the word "line" that
bash prints with the line number.
Mike Frysinger
2015-04-19 07:02:25 UTC
Permalink
Post by Mark Oteiza
Post by Mike Frysinger
Post by Mark Oteiza
where sh is linked to bash, nano does not
recognize the output.
# touch test.sh
# ln -sf bash /bin/sh
# sh -n test.sh
# echo '(' > test.sh
# sh -n test.sh
test.sh: line 2: syntax error: unexpected end of file
# bash -n test.sh
test.sh: line 2: syntax error: unexpected end of file
# dash -n test.sh
test.sh: 2: test.sh: Syntax error: end of file unexpected
Notice the difference in output between dash and bash. nano does not
know how to parse the output from bash because of the word "line" that
bash prints with the line number.
then nano is broken and it needs to be fixed ?
-mike

Mark Oteiza
2015-03-31 20:21:33 UTC
Permalink
Post by Benno Schulenberg
Post by Mark Oteiza
extendsyntax c linter gcc -fshow-column
[ src/color.c:82:2: error: ‘colortype’ has no member named ‘next’ ].
But it does. What's up with that? (You may not; I just wonder.)
I get taken to src/nano.h:
[ src/nano.h:126:10: fatal error: 'glib.h' file not found ]

Odd. I only tested on small c snippets, so I suppose this linter
definition isn't very good.
Post by Benno Schulenberg
Post by Mark Oteiza
extendsyntax python linter pyflakes
[ Got 0 parsable lines from command: pyflakes ]
So we need a better message when a command does not exist.
Yes, that would be good
Post by Benno Schulenberg
Post by Mark Oteiza
* For Emacs lisp I don't know how to highlight multiline strings
(docstrings)
After a quick google for elisp docstring, it seems such a string
starts with some whitespace at the start of the line followed
by a doublequote. And it ends with a double quote at the end
color yellow start="^[[:blank:]]+\"" end="\"$"
Ahh, great! There can be things like

(defconst foo nil
"This is a docstring.")

so the following seems to work better (also trying to not end if it's an
escaped double quote).

color yellow start="^[[:blank:]]+\"" end="[^\]\""
Post by Benno Schulenberg
Post by Mark Oteiza
* In both lisps, if we want to highlight the `foo` function, there is
nothing stopping a function like `foo-bar` having just `foo`
highlighted, which looks weird.
I don't follow. Where in your elisp file is there a regex that
colours function names?
Oh, all the regexen at the top: let, if, when, defun, etc. Take `map` for
example. In elisp there is also cl-map, so something like

(cl-map 'vector #'append list1 list2)

will have "map" highlighted when it shouldn't.
Benno Schulenberg
2015-04-01 15:37:12 UTC
Permalink
Post by Mark Oteiza
Take `map` for
example. In elisp there is also cl-map, so something like
(cl-map 'vector #'append list1 list2)
will have "map" highlighted when it shouldn't.
It's a pity one can't redefine the word-character class
to include the hyphen. :|

I've been trying things from here:
http://www.regular-expressions.info/lookaround.html

But putting color yellow "(?<!-)map" in a syntax file
gives this error:

Bad regex "(?<!-)map": Invalid preceding regular expression

Benno
--
http://www.fastmail.com - mmm... Fastmail...
Mark Oteiza
2015-04-16 06:39:07 UTC
Permalink
Hi,

Here are patches for the two lisp syntax files.

Index: Makefile.am
===================================================================
--- doc/syntax/Makefile.am (revision 5198)
+++ doc/syntax/Makefile.am (working copy)
@@ -10,6 +10,7 @@
gentoo.nanorc \
go.nanorc \
groff.nanorc \
+ guile.nanorc \
html.nanorc \
java.nanorc \
javascript.nanorc \
Index: guile.nanorc
===================================================================
--- doc/syntax/guile.nanorc (revision 0)
+++ doc/syntax/guile.nanorc (working copy)
@@ -0,0 +1,23 @@
+## Here is an example for Guile scheme.
+
+syntax "guile" "\.scm$"
+header "^#!.*guile"
+magic "guile"
+
+color green "\<(let|if|when|unless|lambda|map)\>"
+color brightcyan "\<(define|define-syntax|define-macro)\>"
+color brightcyan "\<(define-module|define-public)\>"
+# Quoted symbols
+color brightyellow "'\<(\w|-)+\>"
+# Chars
+color brightmagenta "#\\."
+color brightmagenta "#\\\w+\>"
+# Booleans
+color brightred "(#t|#f)\>"
+# Keywords
+color blue "#?:(\w|[?-])+"
+# Strings
+color yellow start="^[[:blank:]]+\"" end="[^\]\""
+color yellow ""(\\.|[^"])*""
+# Comments
+color cyan "(^|[[:space:]]);.*$"
Mark Oteiza
2015-04-18 03:36:28 UTC
Permalink
Comments and just a couple more functions added

Index: Makefile.am
===================================================================
--- Makefile.am (revision 5198)
+++ Makefile.am (working copy)
@@ -10,6 +10,7 @@
gentoo.nanorc \
go.nanorc \
groff.nanorc \
+ guile.nanorc \
html.nanorc \
java.nanorc \
javascript.nanorc \
Index: guile.nanorc
===================================================================
--- guile.nanorc (revision 0)
+++ guile.nanorc (working copy)
@@ -0,0 +1,25 @@
+## Here is an example for Guile scheme.
+
+syntax "guile" "\.scm$"
+header "^#!.*guile"
+magic "guile"
+
+# Basic scheme functions
+color green "\<(let|letrec|if|when|unless|lambda|map|do)\>"
+# Defining things
+color brightcyan "\<(define|define-syntax|define-macro)\>"
+color brightcyan "\<(define-module|define-public)\>"
+# Quoted symbols
+color brightyellow "'\<(\w|-)+\>"
+# Chars
+color brightmagenta "#\\."
+color brightmagenta "#\\\w+\>"
+# Booleans
+color brightred "(#t|#f)\>"
+# Keywords
+color blue "#?:(\w|[?-])+"
+# Strings
+color yellow start="^[[:blank:]]+\"" end="[^\]\""
+color yellow ""(\\.|[^"])*""
+# Comments
+color cyan "(^|[[:space:]]);.*$"
Benno Schulenberg
2015-04-18 13:07:59 UTC
Permalink
Post by Mark Oteiza
--- guile.nanorc (revision 0)
+++ guile.nanorc (working copy)
Both patches applied to SVN, r5204 (a bit tweaked, though).

And the linter definitions too, r5203.

Thanks.

Benno
--
http://www.fastmail.com - Accessible with your email software
or over the web
Mark Oteiza
2015-04-18 15:15:25 UTC
Permalink
Post by Benno Schulenberg
Post by Mark Oteiza
--- guile.nanorc (revision 0)
+++ guile.nanorc (working copy)
Both patches applied to SVN, r5204 (a bit tweaked, though).
And the linter definitions too, r5203.
Thanks.
Thanks!
Mark Oteiza
2015-04-16 06:40:21 UTC
Permalink
Index: Makefile.am
===================================================================
--- doc/syntax/Makefile.am (revision 5198)
+++ doc/syntax/Makefile.am (working copy)
@@ -6,6 +6,7 @@
css.nanorc \
debian.nanorc \
default.nanorc \
+ elisp.nanorc \
fortran.nanorc \
gentoo.nanorc \
go.nanorc \
Index: elisp.nanorc
===================================================================
--- doc/syntax/elisp.nanorc (revision 0)
+++ doc/syntax/elisp.nanorc (working copy)
@@ -0,0 +1,21 @@
+## Here is an example for Emacs lisp.
+
+syntax "elisp" "\.el$"
+
+color green "\<(let|if|when|unless|lambda|map)\>"
+color brightcyan "\<(defun|defmacro)\>"
+color brightcyan "\<(defvar|defconst)\>"
+color brightcyan "\<(defgroup|defcustom|defface)\>"
+color brightcyan "\<(setq|setq-default|setq-local)\>"
+color brightcyan "\<(require|provide)\>"
+# Quoted symbols
+color brightyellow "#?'\<(\w|-)+\>"
+# Booleans
+color brightred "\<(t|nil)\>"
+# Keywords
+color blue ":(\w|[?-])+"
+# Strings
+color yellow start="^[[:blank:]]+\"" end="[^\]\""
+color yellow ""(\\.|[^"])*""
+# Comments
+color cyan "(^|[[:space:]]);.*$"
Benno Schulenberg
2015-04-16 07:41:01 UTC
Permalink
Hi Mark,

(Ah, nice. I was just about to ping you. :) )
Post by Mark Oteiza
+color green "\<(let|if|when|unless|lambda|map)\>"
Below you have comments, like "Booleans" and "Keywords".
Any way to describe the above things? The same question
for the next bunch.
Post by Mark Oteiza
+color brightcyan "\<(defun|defmacro)\>"
+color brightcyan "\<(defvar|defconst)\>"
+color brightcyan "\<(defgroup|defcustom|defface)\>"
Any reason why these are not in a single string?

Benno
--
http://www.fastmail.com - Choose from over 50 domains or use your own
Mark Oteiza
2015-04-16 16:43:03 UTC
Permalink
Post by Benno Schulenberg
Post by Mark Oteiza
+color green "\<(let|if|when|unless|lambda|map)\>"
Below you have comments, like "Booleans" and "Keywords".
Any way to describe the above things? The same question
for the next bunch.
Post by Mark Oteiza
+color brightcyan "\<(defun|defmacro)\>"
+color brightcyan "\<(defvar|defconst)\>"
+color brightcyan "\<(defgroup|defcustom|defface)\>"
Both are builtin functions/macros, and now that I think about it, I'm
not sure why I colored them differently for elisp.
Post by Benno Schulenberg
Any reason why these are not in a single string?
Grouped into categories, as things could be added to them. I tried
keeping it minimal to avoid going overboard to try covering all of
elisp. I could add some more things though, along with adding
explanatory comments.
Mark Oteiza
2015-04-18 03:35:38 UTC
Permalink
Added comments and some more elisp functions/macros

Index: Makefile.am
===================================================================
--- Makefile.am (revision 5198)
+++ Makefile.am (working copy)
@@ -6,6 +6,7 @@
css.nanorc \
debian.nanorc \
default.nanorc \
+ elisp.nanorc \
fortran.nanorc \
gentoo.nanorc \
go.nanorc \
Index: elisp.nanorc
===================================================================
--- elisp.nanorc (revision 0)
+++ elisp.nanorc (working copy)
@@ -0,0 +1,31 @@
+## Here is an example for Emacs lisp.
+
+syntax "elisp" "\.el$"
+
+# Basic functions/macros
+color brightcyan "\<(let|if|when|unless|and|or|lambda|dolist|dotimes|while|cond|progn)\>"
+color brightcyan "\<save-(excursion|window-excursion|restriction)\>"
+color brightcyan "\<eval-(and|when)-compile\>"
+# Defining functions
+color brightcyan "\<def(un|macro|alias|subst|generic)\>"
+color brightcyan "\<cl-def(un|macro|subst|generic|struct|type)\>"
+color brightcyan "\<define-(derived|minor|generic)-mode\>"
+# Defining variables
+color brightcyan "\<def(var|const|class|var-local|varalias)\>"
+# Customization functions
+color brightcyan "\<def(group|custom|face|theme)\>"
+# Setting values
+color brightcyan "\<(setq|setq-default|setq-local|setf|push|pop|declare|declare-function)\>"
+# Feature functions
+color brightcyan "\<(require|provide)\>"
+# Quoted symbols
+color brightyellow "#?'\<(\w|-)+\>"
+# Booleans
+color brightred "\<(t|nil)\>"
+# Keywords
+color blue ":(\w|[?-])+"
+# Strings
+color yellow start="^[[:blank:]]+\"" end="[^\]\""
+color yellow ""(\\.|[^"])*""
+# Comments
+color cyan "(^|[[:space:]]);.*$"
Continue reading on narkive:
Loading...