mirror of git://git.sv.gnu.org/nano.git
new feature: comment/uncomment current line or selected lines
This allows for commenting or uncommenting a line or a bunch of lines with a single keystroke (default binding: M-3). The characters used for commenting/uncommenting are specified by the active syntax file. Reviewed-by: Benno Schulenberg <bensberg@justemail.net> Signed-off-by: Mike Scalora <mike@scalora.org>
This commit is contained in:
parent
d3bd855c9d
commit
6a2032f5b0
16
configure.ac
16
configure.ac
|
@ -84,6 +84,22 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(comment,
|
||||
AS_HELP_STRING([--disable-comment], [Disable comment/uncomment functions]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_comment" = xyes; then
|
||||
AC_MSG_ERROR([--enable-comment cannot work with --enable-tiny])
|
||||
else
|
||||
# Disabling nanorc silently disables comment support.
|
||||
enable_comment=no
|
||||
fi
|
||||
fi
|
||||
if test "x$disable_comment" != xyes; then
|
||||
if test "x$enable_comment" != xno; then
|
||||
AC_DEFINE(ENABLE_COMMENT, 1, [Define this to disable the comment/uncomment functionality.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(extra,
|
||||
AS_HELP_STRING([--disable-extra], [Disable extra features, currently only easter eggs]))
|
||||
if test "x$enable_extra" = xno; then
|
||||
|
|
|
@ -302,6 +302,16 @@ syntax should be used for that file. This
|
|||
functionality only works when \fBlibmagic\fP is installed on the
|
||||
system and will be silently ignored otherwise.
|
||||
.TP
|
||||
.BI comment " string"
|
||||
Use the given string for commenting and uncommenting lines. A vertical bar or
|
||||
pipe character (|) designates bracket-style comments; for example, "/*|*/" for
|
||||
CSS files. The characters before the pipe are prepended to the line and the
|
||||
characters after the pipe are appended at the end of the line. If no pipe
|
||||
character is present, the entire string is prepended; for example, "#" for
|
||||
Python files. If empty double quotes are specified, the comment/uncomment
|
||||
function is disabled; for example, "" for JSON. Double quotes or backslashes
|
||||
may be escaped with a backslash; for example, ".\\"" for man page source.
|
||||
.TP
|
||||
.B color \fIfgcolor\fR,\fIbgcolor\fR """\fIregex\fR""" ...
|
||||
Display all pieces of text that match
|
||||
the extended regular expression \fIregex\fP with foreground color
|
||||
|
@ -336,7 +346,7 @@ to \fBicolor\fP.
|
|||
.BI extendsyntax " str directive " \fR[ "arg " \fR...]
|
||||
Extend the syntax previously defined as \fIstr\fP to include
|
||||
new information. This allows you to add a new \fBcolor\fP, \fBicolor\fP,
|
||||
\fBheader\fP, \fBmagic\fP, \fBlinter\fP, or \fBformatter\fP directive
|
||||
\fBheader\fP, \fBmagic\fP, \fBcomment\fP, \fBlinter\fP, or \fBformatter\fP directive
|
||||
to an already defined syntax -- useful when you want to
|
||||
slightly improve a syntax defined in one of the system-installed
|
||||
files (which are normally not writable)
|
||||
|
@ -455,6 +465,10 @@ Indents (shifts to the right) the currently marked text.
|
|||
.B unindent
|
||||
Unindents (shifts to the left) the currently marked text.
|
||||
.TP
|
||||
.B comment
|
||||
Comments or uncomments the current line or marked lines, using the comment
|
||||
style specified in the active syntax.
|
||||
.TP
|
||||
.B left
|
||||
Goes left one position (in the editor or browser).
|
||||
.TP
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "asm" "\.(S|s|asm)$"
|
||||
magic "[Aa]ssembl(y|er)"
|
||||
comment "//"
|
||||
|
||||
color red "\<[A-Z_]{2,}\>"
|
||||
color brightgreen "\.(data|subsection|text)"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for Autoconf.
|
||||
|
||||
syntax "autoconf" "\.(ac|m4)$"
|
||||
comment "#"
|
||||
|
||||
# Keywords:
|
||||
color yellow "\<(if|test|then|elif|else|fi|for|in|do|done)\>"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "awk" "\.awk$"
|
||||
magic "awk.*script text"
|
||||
comment "#"
|
||||
|
||||
# Records.
|
||||
icolor brightred "\$[0-9A-Z_!@#$*?-]+"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "c" "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
|
||||
magic "(ASCII|UTF-8 Unicode) C(\+\+)? program text"
|
||||
comment "//"
|
||||
|
||||
color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||
color green "\<(float|double|bool|char|int|short|long|sizeof|enum|void|auto|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Syntax highlighting for CMake files.
|
||||
|
||||
syntax "cmake" "(CMakeLists\.txt|\.cmake)$"
|
||||
comment "#"
|
||||
|
||||
icolor green "^[[:space:]]*[A-Z0-9_]+"
|
||||
icolor brightyellow "^[[:space:]]*(include|include_directories|include_external_msproject)\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for CSS files.
|
||||
|
||||
syntax "css" "\.css$"
|
||||
comment "/*|*/"
|
||||
|
||||
color brightred "."
|
||||
color brightyellow start="\{" end="\}"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for apt's sources.list.
|
||||
|
||||
syntax "sources.list" "sources\.list(~|\.old|\.save)?$" "sources\.list\.d/.*\.list(~|\.old|\.save)?$"
|
||||
comment "#"
|
||||
|
||||
# Coloring the deb lines, working from tail to head. First the
|
||||
# components -- well, everything, and thus also the components.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
## for files that do not match any other syntax.
|
||||
|
||||
syntax "default"
|
||||
comment "#"
|
||||
|
||||
# Spaces in front of tabs.
|
||||
color ,red " + +"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for Emacs Lisp.
|
||||
|
||||
syntax "elisp" "\.el$"
|
||||
comment ";"
|
||||
|
||||
# Basic functions/macros
|
||||
color brightcyan "\<(if|when|unless|cond|and|or|lambda|let|progn|while|dolist|dotimes)\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for Fortran 90/95.
|
||||
|
||||
syntax "fortran" "\.(f|f90|f95)$"
|
||||
comment "!"
|
||||
|
||||
color red "\<[0-9]+\>"
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for Gentoo ebuilds/eclasses.
|
||||
|
||||
syntax "ebuild" "\.e(build|class)$"
|
||||
comment "#"
|
||||
|
||||
## All the standard portage functions
|
||||
color brightgreen "(^|\<default_)src_(unpack|prepare|configure|compile|install|test)\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for Go.
|
||||
|
||||
syntax "go" "\.go$"
|
||||
comment "//"
|
||||
|
||||
# Set up a formatter since spelling is probably useless...
|
||||
formatter gofmt -w
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for groff.
|
||||
|
||||
syntax "groff" "\.m[ems]$" "\.rof" "\.tmac$" "^tmac."
|
||||
comment ".\""
|
||||
|
||||
# The argument of .ds or .nr
|
||||
color cyan "^\.(ds|nr) [^[:space:]]*"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
syntax "guile" "\.scm$"
|
||||
header "^#!.*guile"
|
||||
magic "guile"
|
||||
comment ";"
|
||||
|
||||
# Basic scheme functions
|
||||
color green "\<(do|if|lambda|let(rec)?|map|unless|when)\>"
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
syntax "html" "\.html?$"
|
||||
magic "HTML document text"
|
||||
comment "<!--|-->"
|
||||
|
||||
color cyan start="<" end=">"
|
||||
color red "&[^;[:space:]]*;"
|
||||
color green ""(\\.|[^"])*""
|
||||
|
||||
color yellow start="<!--" end="-->"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "java" "\.java$"
|
||||
magic "Java "
|
||||
comment "//"
|
||||
|
||||
color green "\<(boolean|byte|char|double|float|int|long|new|short|this|transient|void)\>"
|
||||
color red "\<(break|case|catch|continue|default|do|else|finally|for|if|return|switch|throw|try|while)\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for Javascript.
|
||||
|
||||
syntax "javascript" "\.js$"
|
||||
comment "//"
|
||||
|
||||
color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||
color green "\<(const|function|let|this|typeof|var|void)\>"
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
# License: GPLv3 or newer
|
||||
|
||||
syntax "json" "\.json$"
|
||||
# No comments are permitted in JSON.
|
||||
comment ""
|
||||
|
||||
# Numbers (used as value).
|
||||
color green ":[[:space:]]*\-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee]?[-+]?[0-9]+)?"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
## Version: 2011-05-05
|
||||
|
||||
syntax "lua" "\.lua$"
|
||||
comment "--"
|
||||
|
||||
color brightwhite "\[\[.*\]\]"
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for Makefiles.
|
||||
|
||||
syntax "makefile" "Makefile[^/]*$" "\.(make|mk)$"
|
||||
comment "#"
|
||||
|
||||
color red "[:=]"
|
||||
color magenta "\<(if|ifeq|else|endif)\>"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "man" "\.[1-9]x?$"
|
||||
magic "troff or preprocessor input text"
|
||||
comment ".\""
|
||||
|
||||
color green "\.(SH|SS|TH) .*$"
|
||||
color brightgreen "\.(SH|SS|TH) " "\.([HIT]P)"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "mgp" "\.mgp$"
|
||||
header "^%include.*"
|
||||
comment "#"
|
||||
|
||||
icolor green "^%[a-z].*$"
|
||||
color cyan "(^|[[:space:]])#.*$"
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
## Here is an example for nanorc files.
|
||||
|
||||
syntax "nanorc" "\.?nanorc$"
|
||||
comment "#"
|
||||
|
||||
# Possible errors and parameters
|
||||
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|linter|i?color|extendsyntax).*$"
|
||||
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|comment|magic|linter|i?color|extendsyntax).*$"
|
||||
|
||||
# Keywords
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|autoindent|backup|backwards|boldtext|casesensitive|const(antshow)?|cut|fill|historylog|justifytrim|locking|morespace|mouse|multibuffer|noconvert|nohelp|nonewlines|nowrap|pos(ition)?log|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|smarthome|smooth|softwrap|suspend|tabsize|tabstospaces|tempfile|unix|view|wordbounds)\>"
|
||||
|
@ -11,8 +12,8 @@ icolor yellow "^[[:space:]]*set[[:space:]]+(functioncolor|keycolor|statuscolor|t
|
|||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|functioncolor|keycolor|matchbrackets|operatingdir|punct|quotestr|speller|statuscolor|titlecolor|whitespace)[[:space:]]+"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^|M-)([[:alpha:]]|space|[]]|[0-9^_=+{}|;:'\",./<>\?-])|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+[[:alpha:]]+[[:space:]]+(all|main|search|replace(2|with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^|M-)([[:alpha:]]|space|[]]|[0-9^_=+{}|;:'\",./<>\?-])|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(2|with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|linter|formatter)[[:space:]]+.*$"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|linter|formatter|extendsyntax)\>"
|
||||
icolor brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|linter|formatter)[[:space:]]+.*$"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|extendsyntax)\>"
|
||||
|
||||
# Colors
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "nftables" "\.(nft|nftables)$"
|
||||
header "^#!.*(nft|nftables)"
|
||||
comment "#"
|
||||
|
||||
# Objects and operations
|
||||
color green "\<(chain|hook|policy|priority|ruleset|set|table|type|v?map)\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for C/C++/Obj-C.
|
||||
|
||||
syntax "m" "\.m$"
|
||||
comment "//"
|
||||
|
||||
# Stuffs,
|
||||
color brightwhite "\<[A-Z_][0-9A-Z_]+\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Syntax highlighting for OCaml.
|
||||
|
||||
syntax "ocaml" "\.mli?$"
|
||||
comment "(*|*)"
|
||||
|
||||
# Uid:
|
||||
color red "\<[A-Z][0-9a-z_]{2,}\>"
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
syntax "patch" "\.(patch|diff|debdiff)$"
|
||||
magic "diff output text"
|
||||
# There is no official support for comments in patch files.
|
||||
comment ""
|
||||
|
||||
# Added lines.
|
||||
color brightgreen "^\+.*"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
syntax "perl" "\.p[lm]$"
|
||||
header "^#!.*perl[-0-9._]*"
|
||||
magic "Perl script text"
|
||||
comment "#"
|
||||
|
||||
color red "\<(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\>" "\<(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\>" "\<(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\>" "\<(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\>" "\<(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>"
|
||||
color magenta "\<(continue|else|elsif|do|for|foreach|if|unless|until|while|eq|ne|lt|gt|le|ge|cmp|x|my|sub|use|package|can|isa)\>"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "php" "\.php[2345s~]?$"
|
||||
magic "PHP script text"
|
||||
comment "//"
|
||||
|
||||
# PHP markings.
|
||||
color brightgreen "(<\?(php)?|\?>)"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Colouring for PO files.
|
||||
|
||||
syntax "po" "\.pot?$"
|
||||
comment "#"
|
||||
|
||||
# Comments.
|
||||
color green "^#.*$"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "sql" "\.sql[2345s~]?$"
|
||||
magic "PostgreSQL script text"
|
||||
comment "-- "
|
||||
|
||||
# Functions.
|
||||
color white "\<[a-z_]*\("
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Here is an example for POV-Ray.
|
||||
|
||||
syntax "pov" "\.(pov|POV|povray|POVRAY)$"
|
||||
comment "//"
|
||||
|
||||
color brightcyan "^[[:space:]]*#[[:space:]]*(declare)"
|
||||
color brightyellow "\<(sphere|cylinder|translate|matrix|rotate|scale)\>"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
syntax "python" "\.py$"
|
||||
header "^#!.*python[-0-9._]*"
|
||||
linter pyflakes
|
||||
comment "#"
|
||||
|
||||
# Function definitions.
|
||||
icolor brightblue "def [0-9A-Z_]+"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
syntax "ruby" "\.rb$"
|
||||
header "^#!.*ruby[-0-9._]*"
|
||||
linter ruby -w -c
|
||||
comment "#"
|
||||
|
||||
# Reserved words.
|
||||
color yellow "\<(BEGIN|END|alias|and|begin|break|case|class|def|defined\?|do|else|elsif|end|ensure|false|for|if|in|module)\>"
|
||||
|
|
|
@ -4,6 +4,7 @@ syntax "sh" "\.sh$"
|
|||
header "^#!.*((ba|da|k|pdk)?sh[-0-9_]*|openrc-run|runscript)"
|
||||
magic "(POSIX|Bourne.*) shell script text"
|
||||
linter dash -n
|
||||
comment "#"
|
||||
|
||||
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)\>"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Syntax highlighting for RPM spec files.
|
||||
|
||||
syntax "spec" "\.(spec$|spec\.*)"
|
||||
comment "#"
|
||||
|
||||
# Main tags.
|
||||
color brightblue "((Icon|ExclusiveOs|ExcludeOs)[[:space:]]*:)"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Syntax highlighting for Tcl files.
|
||||
|
||||
syntax "tcl" "\.tcl$"
|
||||
comment "#"
|
||||
|
||||
# Standard Tcl [info commands]:
|
||||
color green "\<(after|append|array|auto_execok|auto_import|auto_load|auto_load_index|auto_qualify|binary|break|case|catch|cd|clock|close|concat|continue|encoding|eof|error|eval|exec|exit|expr|fblocked|fconfigure|fcopy|file|fileevent|flush|for|foreach|format|gets|glob|global|history|if|incr|info|interp|join|lappend|lindex|linsert|list|llength|load|lrange|lreplace|lsearch|lset|lsort|namespace|open|package|pid|puts|pwd|read|regexp|regsub|rename|return|scan|seek|set|socket|source|split|string|subst|switch|tclLog|tell|time|trace|unknown|unset|update|uplevel|upvar|variable|vwait|while)\>"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "tex" "\.tex$"
|
||||
linter chktex -v0 -q -I
|
||||
comment "%"
|
||||
|
||||
icolor green "\\.|\\[A-Z]*"
|
||||
color magenta "[{}]"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
syntax "texinfo" "\.texi$"
|
||||
header "^\\input texinfo"
|
||||
magic "Texinfo source text"
|
||||
comment "@c "
|
||||
|
||||
# Command arguments, trailing and enclosed.
|
||||
color cyan "^@[a-z]+[[:space:]]+.*$"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
syntax "xml" "\.([jrsx]html?|jnlp|mml|pom|rng|sgml?|svg|w[as]dl|wsdd|xjb|xml|xs(d|lt?)|xul)$"
|
||||
magic "(XML|SGML) (sub)?document text"
|
||||
comment "<!--|-->"
|
||||
|
||||
# The entire content of the tag:
|
||||
color green start="<" end=">"
|
||||
|
|
|
@ -886,6 +886,16 @@ to be edited, to determine whether this syntax should be used for that
|
|||
file. This functionality only works when libmagic is installed on the
|
||||
system and will be silently ignored otherwise.
|
||||
|
||||
@item comment "string"
|
||||
Use the given string for commenting and uncommenting lines. A vertical bar or
|
||||
pipe character (|) designates bracket-style comments; for example, "/*|*/" for
|
||||
CSS files. The characters before the pipe are prepended to the line and the
|
||||
characters after the pipe are appended at the end of the line. If no pipe
|
||||
character is present, the entire string is prepended; for example, "#" for
|
||||
Python files. If empty double quotes are specified, the comment/uncomment
|
||||
functions are disabled; for example, "" for JSON. Double quotes or backslashes
|
||||
may be escaped with a backslash; for example, ".\\"" for man page source.
|
||||
|
||||
@item color fgcolor,bgcolor "regex" @dots{}
|
||||
Display all pieces of text that match the
|
||||
extended regular expression "regex" with foreground color "fgcolor" and
|
||||
|
@ -918,7 +928,7 @@ to @code{icolor}.
|
|||
@item extendsyntax str directive [arg @dots{}]
|
||||
Extend the syntax previously defined as str to include new information.
|
||||
This allows you to add a new @code{color}, @code{icolor}, @code{header},
|
||||
@code{magic}, @code{linter}, or @code{formatter} directive to an already
|
||||
@code{magic}, @code{comment}, @code{linter}, or @code{formatter} directive to an already
|
||||
defined syntax --- useful when you want to slightly improve a syntax defined
|
||||
in one of the system-installed files (which are normally not writable).
|
||||
|
||||
|
@ -1043,6 +1053,10 @@ Indents (shifts to the right) the currently marked text.
|
|||
@item unindent
|
||||
Unindents (shifts to the left) the currently marked text.
|
||||
|
||||
@item comment
|
||||
Comments or uncomments the current line or marked lines, using the comment
|
||||
style specified in the active syntax.
|
||||
|
||||
@item left
|
||||
Goes left one position (in the editor or browser).
|
||||
|
||||
|
|
14
src/global.c
14
src/global.c
|
@ -554,6 +554,9 @@ void shortcut_init(void)
|
|||
N_("Copy the current line and store it in the cutbuffer");
|
||||
const char *nano_indent_msg = N_("Indent the current line");
|
||||
const char *nano_unindent_msg = N_("Unindent the current line");
|
||||
#ifdef ENABLE_COMMENT
|
||||
const char *nano_comment_msg = N_("Comment/uncomment the current line or marked lines");
|
||||
#endif
|
||||
const char *nano_undo_msg = N_("Undo the last operation");
|
||||
const char *nano_redo_msg = N_("Redo the last undone operation");
|
||||
#endif
|
||||
|
@ -937,6 +940,10 @@ void shortcut_init(void)
|
|||
add_to_funcs(do_suspend_void, MMAIN,
|
||||
N_("Suspend"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW);
|
||||
|
||||
#ifdef ENABLE_COMMENT
|
||||
add_to_funcs(do_comment, MMAIN,
|
||||
N_("Comment Lines"), IFSCHELP(nano_comment_msg), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_savefile, MMAIN,
|
||||
N_("Save"), IFSCHELP(nano_savefile_msg), BLANKAFTER, NOVIEW);
|
||||
|
@ -1103,6 +1110,9 @@ void shortcut_init(void)
|
|||
add_to_sclist(MMAIN, "M-{", do_unindent, 0);
|
||||
add_to_sclist(MMAIN, "M-U", do_undo, 0);
|
||||
add_to_sclist(MMAIN, "M-E", do_redo, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_COMMENT
|
||||
add_to_sclist(MMAIN, "M-3", do_comment, 0);
|
||||
#endif
|
||||
add_to_sclist(MMOST, "^B", do_left, 0);
|
||||
add_to_sclist(MMOST, "Left", do_left, 0);
|
||||
|
@ -1419,6 +1429,10 @@ sc *strtosc(const char *input)
|
|||
else if (!strcasecmp(input, "endpara"))
|
||||
s->scfunc = do_para_end_void;
|
||||
#endif
|
||||
#ifdef ENABLE_COMMENT
|
||||
else if (!strcasecmp(input, "comment"))
|
||||
s->scfunc = do_comment;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "indent"))
|
||||
s->scfunc = do_indent_void;
|
||||
|
|
|
@ -996,6 +996,9 @@ void version(void)
|
|||
#ifdef DISABLE_COLOR
|
||||
printf(" --disable-color");
|
||||
#endif
|
||||
#ifndef ENABLE_COMMENT
|
||||
printf(" --disable-comment");
|
||||
#endif
|
||||
#ifdef DISABLE_EXTRA
|
||||
printf(" --disable-extra");
|
||||
#endif
|
||||
|
|
15
src/nano.h
15
src/nano.h
|
@ -191,6 +191,9 @@ typedef enum {
|
|||
ADD, DEL, BACK, CUT, CUT_EOF, REPLACE,
|
||||
#ifndef DISABLE_WRAPPING
|
||||
SPLIT_BEGIN, SPLIT_END,
|
||||
#endif
|
||||
#ifndef DISABLE_COMMENT
|
||||
COMMENT, UNCOMMENT, PREFLIGHT,
|
||||
#endif
|
||||
JOIN, PASTE, INSERT, ENTER, OTHER
|
||||
} undo_type;
|
||||
|
@ -251,6 +254,8 @@ typedef struct syntaxtype {
|
|||
/* The command with which to lint this type of file. */
|
||||
char *formatter;
|
||||
/* The formatting command (for programming languages mainly). */
|
||||
char *comment;
|
||||
/* The line comment prefix (and postfix) for this type of file. */
|
||||
colortype *color;
|
||||
/* The colors and their regexes used in this syntax. */
|
||||
int nmultis;
|
||||
|
@ -322,6 +327,14 @@ typedef struct partition {
|
|||
} partition;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct undo_group {
|
||||
ssize_t top_line;
|
||||
/* First line of group. */
|
||||
ssize_t bottom_line;
|
||||
/* Last line of group. */
|
||||
struct undo_group *next;
|
||||
} undo_group;
|
||||
|
||||
typedef struct undo {
|
||||
ssize_t lineno;
|
||||
undo_type type;
|
||||
|
@ -336,6 +349,8 @@ typedef struct undo {
|
|||
/* The file size after the action. */
|
||||
int xflags;
|
||||
/* Some flag data we need. */
|
||||
undo_group *grouping;
|
||||
/* Undo info specific to groups of lines. */
|
||||
|
||||
/* Cut-specific stuff we need. */
|
||||
filestruct *cutbuffer;
|
||||
|
|
|
@ -653,6 +653,9 @@ void do_unindent(void);
|
|||
void do_undo(void);
|
||||
void do_redo(void);
|
||||
#endif
|
||||
#ifndef DISABLE_COMMENT
|
||||
void do_comment(void);
|
||||
#endif
|
||||
void do_enter(void);
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE cancel_command(int signal);
|
||||
|
@ -745,6 +748,11 @@ void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
|||
void discard_until(const undo *thisitem, openfilestruct *thefile);
|
||||
void add_undo(undo_type action);
|
||||
void update_undo(undo_type action);
|
||||
#ifndef DISABLE_COMMENT
|
||||
void add_comment_undo(undo_type action, const char *comment_seq, size_t undo_x);
|
||||
void update_comment_undo(ssize_t lineno);
|
||||
bool comment_line(undo_type action, filestruct *f, const char *comment_seq);
|
||||
#endif
|
||||
#endif
|
||||
size_t get_totsize(const filestruct *begin, const filestruct *end);
|
||||
filestruct *fsfromline(ssize_t lineno);
|
||||
|
|
25
src/rcfile.c
25
src/rcfile.c
|
@ -306,6 +306,7 @@ void parse_syntax(char *ptr)
|
|||
live_syntax->magics = NULL;
|
||||
live_syntax->linter = NULL;
|
||||
live_syntax->formatter = NULL;
|
||||
live_syntax->comment = NULL;
|
||||
live_syntax->color = NULL;
|
||||
lastcolor = NULL;
|
||||
live_syntax->nmultis = 0;
|
||||
|
@ -868,6 +869,24 @@ void pick_up_name(const char *kind, char *ptr, char **storage)
|
|||
/* Allow unsetting the command by using an empty string. */
|
||||
if (!strcmp(ptr, "\"\""))
|
||||
*storage = NULL;
|
||||
else if (*ptr == '"') {
|
||||
*storage = mallocstrcpy(NULL, ++ptr);
|
||||
char* q = *storage;
|
||||
char* p = *storage;
|
||||
/* Snip out the backslashes of escaped characters. */
|
||||
while (*p != '"') {
|
||||
if (*p == '\0') {
|
||||
rcfile_error(N_("Argument of '%s' lacks closing \""), kind);
|
||||
free(*storage);
|
||||
*storage = NULL;
|
||||
return;
|
||||
} else if (*p == '\\' && *(p + 1) != '\0') {
|
||||
p++;
|
||||
}
|
||||
*q++ = *p++;
|
||||
}
|
||||
*q = '\0';
|
||||
}
|
||||
else
|
||||
*storage = mallocstrcpy(NULL, ptr);
|
||||
}
|
||||
|
@ -982,6 +1001,12 @@ void parse_rcfile(FILE *rcstream
|
|||
grab_and_store("magic", ptr, &live_syntax->magics);
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
else if (strcasecmp(keyword, "comment") == 0)
|
||||
#ifdef ENABLE_COMMENT
|
||||
pick_up_name("comment", ptr, &live_syntax->comment);
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
else if (strcasecmp(keyword, "color") == 0)
|
||||
parse_colors(ptr, NANO_REG_EXTENDED);
|
||||
|
|
258
src/text.c
258
src/text.c
|
@ -425,7 +425,194 @@ void do_unindent(void)
|
|||
{
|
||||
do_indent(-tabsize);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifdef ENABLE_COMMENT
|
||||
/* Test whether the string is empty or consists of only blanks. */
|
||||
bool white_string(const char *s)
|
||||
{
|
||||
while (*s != '\0' && (is_blank_mbchar(s) || *s == '\r'))
|
||||
s += move_mbright(s, 0);
|
||||
|
||||
return !*s;
|
||||
}
|
||||
|
||||
/* Comment or uncomment the current line or the marked lines. */
|
||||
void do_comment()
|
||||
{
|
||||
const char *comment_seq = "#";
|
||||
undo_type action = UNCOMMENT;
|
||||
filestruct *top, *bot, *f;
|
||||
size_t top_x, bot_x, was_x;
|
||||
bool empty, all_empty = TRUE;
|
||||
|
||||
bool file_changed = FALSE;
|
||||
/* Whether any comment has been added or deleted. */
|
||||
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
|
||||
#ifndef DISABLE_COLOR
|
||||
if (openfile->syntax && openfile->syntax->comment)
|
||||
comment_seq = openfile->syntax->comment;
|
||||
|
||||
/* Does the syntax not allow comments? */
|
||||
if (strlen(comment_seq) == 0) {
|
||||
statusbar(_("Commenting is not supported for this file type"));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Determine which lines to work on. */
|
||||
if (openfile->mark_set)
|
||||
mark_order((const filestruct **) &top, &top_x,
|
||||
(const filestruct **) &bot, &bot_x, NULL);
|
||||
else {
|
||||
top = openfile->current;
|
||||
bot = top;
|
||||
}
|
||||
|
||||
/* Remember the cursor x position to be restored when undoing. */
|
||||
was_x = openfile->current_x;
|
||||
|
||||
/* Figure out whether to comment or uncomment the selected line or lines. */
|
||||
for (f = top; f != bot->next; f = f->next) {
|
||||
empty = white_string(f->data);
|
||||
|
||||
/* If this line is not blank and not commented, we comment all. */
|
||||
if (!empty && !comment_line(PREFLIGHT, f, comment_seq)) {
|
||||
action = COMMENT;
|
||||
break;
|
||||
}
|
||||
all_empty = all_empty && empty;
|
||||
}
|
||||
|
||||
/* If all selected lines are blank, we comment them. */
|
||||
action = all_empty ? COMMENT : action;
|
||||
|
||||
/* Process the selected line or lines. */
|
||||
for (f = top; f != bot->next; f = f->next) {
|
||||
if (comment_line(action, f, comment_seq)) {
|
||||
if (!file_changed) {
|
||||
/* Start building undo data on the first modified line. */
|
||||
add_comment_undo(action, comment_seq, was_x);
|
||||
file_changed = TRUE;
|
||||
}
|
||||
/* Add undo data for each modified line. */
|
||||
update_comment_undo(f->lineno);
|
||||
}
|
||||
}
|
||||
|
||||
if (file_changed) {
|
||||
set_modified();
|
||||
refresh_needed = TRUE;
|
||||
} else
|
||||
statusbar(_("Cannot comment past end of file"));
|
||||
}
|
||||
|
||||
/* Test whether the given line can be uncommented, or add or remove a comment,
|
||||
* depending on action. Return TRUE if the line is uncommentable, or when
|
||||
* anything was added or removed; FALSE otherwise. */
|
||||
bool comment_line(undo_type action, filestruct *f, const char *comment_seq)
|
||||
{
|
||||
size_t comment_seq_len = strlen(comment_seq);
|
||||
const char *post_seq = strchr(comment_seq, '|');
|
||||
/* The postfix, if this is a bracketing type comment sequence. */
|
||||
size_t pre_len = post_seq ? post_seq++ - comment_seq : comment_seq_len;
|
||||
/* Length of prefix. */
|
||||
size_t post_len = post_seq ? comment_seq_len - pre_len - 1 : 0;
|
||||
/* Length of postfix. */
|
||||
size_t line_len = strlen(f->data);
|
||||
|
||||
if (!ISSET(NO_NEWLINES) && f == openfile->filebot)
|
||||
return FALSE;
|
||||
|
||||
if (action == COMMENT) {
|
||||
/* Make room for the comment sequence(s), move the text right and
|
||||
* copy them in. */
|
||||
f->data = charealloc(f->data, line_len + pre_len + post_len + 1);
|
||||
charmove(&f->data[pre_len], f->data, line_len);
|
||||
charmove(f->data, comment_seq, pre_len);
|
||||
if (post_len)
|
||||
charmove(&f->data[pre_len + line_len], post_seq, post_len);
|
||||
f->data[pre_len + line_len + post_len] = '\0';
|
||||
|
||||
openfile->totsize += pre_len + post_len;
|
||||
|
||||
/* If needed, adjust the position of the mark and of the cursor. */
|
||||
if (openfile->mark_set && f == openfile->mark_begin)
|
||||
openfile->mark_begin_x += pre_len;
|
||||
if (f == openfile->current) {
|
||||
openfile->current_x += pre_len;
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If the line is commented, report it as uncommentable, or uncomment it. */
|
||||
if (strncmp(f->data, comment_seq, pre_len) == 0 && (post_len == 0 ||
|
||||
strcmp(&f->data[line_len - post_len], post_seq) == 0)) {
|
||||
|
||||
if (action == PREFLIGHT)
|
||||
return TRUE;
|
||||
|
||||
/* Erase the comment prefix by moving the non-comment part. */
|
||||
charmove(f->data, &f->data[pre_len], line_len - pre_len);
|
||||
/* Truncate the postfix if there was one. */
|
||||
f->data[line_len - pre_len - post_len] = '\0';
|
||||
|
||||
openfile->totsize -= pre_len + post_len;
|
||||
|
||||
/* If needed, adjust the position of the mark and then the cursor. */
|
||||
if (openfile->mark_set && f == openfile->mark_begin) {
|
||||
if (openfile->mark_begin_x < pre_len)
|
||||
openfile->mark_begin_x = 0;
|
||||
else
|
||||
openfile->mark_begin_x -= pre_len;
|
||||
}
|
||||
if (f == openfile->current) {
|
||||
if (openfile->current_x < pre_len)
|
||||
openfile->current_x = 0;
|
||||
else
|
||||
openfile->current_x -= pre_len;
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Perform an undo or redo for a comment or uncomment action. */
|
||||
void handle_comment_action(undo *u, bool undoing, bool add_comment)
|
||||
{
|
||||
undo_group *group = u->grouping;
|
||||
|
||||
/* When redoing, reposition the cursor and let the commenter adjust it. */
|
||||
if (!undoing)
|
||||
goto_line_posx(u->lineno, u->begin);
|
||||
|
||||
while (group) {
|
||||
filestruct *f = fsfromline(group->top_line);
|
||||
|
||||
while (f && f->lineno <= group->bottom_line) {
|
||||
comment_line(undoing ^ add_comment ?
|
||||
COMMENT : UNCOMMENT, f, u->strdata);
|
||||
f = f->next;
|
||||
}
|
||||
group = group->next;
|
||||
}
|
||||
|
||||
/* When undoing, reposition the cursor to the recorded location. */
|
||||
if (undoing)
|
||||
goto_line_posx(u->lineno, u->begin);
|
||||
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
#endif /* ENABLE_COMMENT */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
#define redo_paste undo_cut
|
||||
#define undo_paste redo_cut
|
||||
|
||||
|
@ -574,6 +761,16 @@ void do_undo(void)
|
|||
unlink_node(f->next);
|
||||
goto_line_posx(u->lineno, u->begin);
|
||||
break;
|
||||
#ifdef ENABLE_COMMENT
|
||||
case COMMENT:
|
||||
handle_comment_action(u, TRUE, TRUE);
|
||||
undidmsg = _("comment");
|
||||
break;
|
||||
case UNCOMMENT:
|
||||
handle_comment_action(u, TRUE, FALSE);
|
||||
undidmsg = _("uncomment");
|
||||
break;
|
||||
#endif
|
||||
case INSERT:
|
||||
undidmsg = _("text insert");
|
||||
filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
|
||||
|
@ -738,6 +935,16 @@ void do_redo(void)
|
|||
free_filestruct(u->cutbuffer);
|
||||
u->cutbuffer = NULL;
|
||||
break;
|
||||
#ifdef ENABLE_COMMENT
|
||||
case COMMENT:
|
||||
handle_comment_action(u, FALSE, TRUE);
|
||||
redidmsg = _("comment");
|
||||
break;
|
||||
case UNCOMMENT:
|
||||
handle_comment_action(u, FALSE, FALSE);
|
||||
redidmsg = _("uncomment");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
statusline(ALERT, _("Internal error: unknown type. "
|
||||
"Please save your work."));
|
||||
|
@ -909,11 +1116,20 @@ bool execute_command(const char *command)
|
|||
void discard_until(const undo *thisitem, openfilestruct *thefile)
|
||||
{
|
||||
undo *dropit = thefile->undotop;
|
||||
undo_group *group;
|
||||
|
||||
while (dropit != NULL && dropit != thisitem) {
|
||||
thefile->undotop = dropit->next;
|
||||
free(dropit->strdata);
|
||||
free_filestruct(dropit->cutbuffer);
|
||||
#ifdef ENABLE_COMMENT
|
||||
group = dropit->grouping;
|
||||
while (group != NULL) {
|
||||
undo_group *next = group->next;
|
||||
free(group);
|
||||
group = next;
|
||||
}
|
||||
#endif
|
||||
free(dropit);
|
||||
dropit = thefile->undotop;
|
||||
}
|
||||
|
@ -969,6 +1185,7 @@ void add_undo(undo_type action)
|
|||
u->mark_set = FALSE;
|
||||
u->wassize = openfile->totsize;
|
||||
u->xflags = 0;
|
||||
u->grouping = NULL;
|
||||
|
||||
switch (u->type) {
|
||||
/* We need to start copying data into the undo buffer
|
||||
|
@ -1036,6 +1253,11 @@ void add_undo(undo_type action)
|
|||
break;
|
||||
case ENTER:
|
||||
break;
|
||||
#ifdef ENABLE_COMMENT
|
||||
case COMMENT:
|
||||
case UNCOMMENT:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
statusline(ALERT, _("Internal error: unknown type. "
|
||||
"Please save your work."));
|
||||
|
@ -1049,6 +1271,42 @@ void add_undo(undo_type action)
|
|||
openfile->last_action = action;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COMMENT
|
||||
/* Add a comment undo item. This should be called once for each use
|
||||
* of the comment/uncomment feature that modifies the document. */
|
||||
void add_comment_undo(undo_type action, const char *comment_seq, size_t was_x)
|
||||
{
|
||||
add_undo(action);
|
||||
|
||||
/* Store the comment sequence used for the operation, because it could
|
||||
* change when the file name changes; we need to know what it was. */
|
||||
openfile->current_undo->strdata = mallocstrcpy(NULL, comment_seq);
|
||||
|
||||
/* Remember the position of the cursor before the change was made. */
|
||||
openfile->current_undo->begin = was_x;
|
||||
}
|
||||
|
||||
/* Update a comment undo item. This should be called once for each line
|
||||
* affected by the comment/uncomment feature. */
|
||||
void update_comment_undo(ssize_t lineno)
|
||||
{
|
||||
undo *u = openfile->current_undo;
|
||||
|
||||
/* If there already is a group and the current line is contiguous with it,
|
||||
* extend the group; otherwise, create a new group. */
|
||||
if (u->grouping && u->grouping->bottom_line + 1 == lineno)
|
||||
u->grouping->bottom_line++;
|
||||
else {
|
||||
undo_group *born = (undo_group *)nmalloc(sizeof(undo_group));
|
||||
|
||||
born->next = u->grouping;
|
||||
u->grouping = born;
|
||||
born->top_line = lineno;
|
||||
born->bottom_line = lineno;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_COMMENT */
|
||||
|
||||
/* Update an undo item, or determine whether a new one is really needed
|
||||
* and bounce the data to add_undo instead. The latter functionality
|
||||
* just feels gimmicky and may just be more hassle than it's worth,
|
||||
|
|
Loading…
Reference in New Issue