1
1

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>
Этот коммит содержится в:
Mike Scalora 2016-05-25 22:13:50 +02:00 коммит произвёл Benno Schulenberg
родитель d3bd855c9d
Коммит 6a2032f5b0
49 изменённых файлов: 416 добавлений и 5 удалений

Просмотреть файл

@ -84,6 +84,22 @@ else
fi fi
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, AC_ARG_ENABLE(extra,
AS_HELP_STRING([--disable-extra], [Disable extra features, currently only easter eggs])) AS_HELP_STRING([--disable-extra], [Disable extra features, currently only easter eggs]))
if test "x$enable_extra" = xno; then 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 functionality only works when \fBlibmagic\fP is installed on the
system and will be silently ignored otherwise. system and will be silently ignored otherwise.
.TP .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""" ... .B color \fIfgcolor\fR,\fIbgcolor\fR """\fIregex\fR""" ...
Display all pieces of text that match Display all pieces of text that match
the extended regular expression \fIregex\fP with foreground color the extended regular expression \fIregex\fP with foreground color
@ -336,7 +346,7 @@ to \fBicolor\fP.
.BI extendsyntax " str directive " \fR[ "arg " \fR...] .BI extendsyntax " str directive " \fR[ "arg " \fR...]
Extend the syntax previously defined as \fIstr\fP to include Extend the syntax previously defined as \fIstr\fP to include
new information. This allows you to add a new \fBcolor\fP, \fBicolor\fP, 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 to an already defined syntax -- useful when you want to
slightly improve a syntax defined in one of the system-installed slightly improve a syntax defined in one of the system-installed
files (which are normally not writable) files (which are normally not writable)
@ -455,6 +465,10 @@ Indents (shifts to the right) the currently marked text.
.B unindent .B unindent
Unindents (shifts to the left) the currently marked text. Unindents (shifts to the left) the currently marked text.
.TP .TP
.B comment
Comments or uncomments the current line or marked lines, using the comment
style specified in the active syntax.
.TP
.B left .B left
Goes left one position (in the editor or browser). Goes left one position (in the editor or browser).
.TP .TP

Просмотреть файл

@ -2,6 +2,7 @@
syntax "asm" "\.(S|s|asm)$" syntax "asm" "\.(S|s|asm)$"
magic "[Aa]ssembl(y|er)" magic "[Aa]ssembl(y|er)"
comment "//"
color red "\<[A-Z_]{2,}\>" color red "\<[A-Z_]{2,}\>"
color brightgreen "\.(data|subsection|text)" color brightgreen "\.(data|subsection|text)"

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for Autoconf. ## Here is an example for Autoconf.
syntax "autoconf" "\.(ac|m4)$" syntax "autoconf" "\.(ac|m4)$"
comment "#"
# Keywords: # Keywords:
color yellow "\<(if|test|then|elif|else|fi|for|in|do|done)\>" color yellow "\<(if|test|then|elif|else|fi|for|in|do|done)\>"

Просмотреть файл

@ -2,6 +2,7 @@
syntax "awk" "\.awk$" syntax "awk" "\.awk$"
magic "awk.*script text" magic "awk.*script text"
comment "#"
# Records. # Records.
icolor brightred "\$[0-9A-Z_!@#$*?-]+" icolor brightred "\$[0-9A-Z_!@#$*?-]+"

Просмотреть файл

@ -2,6 +2,7 @@
syntax "c" "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$" syntax "c" "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
magic "(ASCII|UTF-8 Unicode) C(\+\+)? program text" magic "(ASCII|UTF-8 Unicode) C(\+\+)? program text"
comment "//"
color brightred "\<[A-Z_][0-9A-Z_]+\>" 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)\>" 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 highlighting for CMake files.
syntax "cmake" "(CMakeLists\.txt|\.cmake)$" syntax "cmake" "(CMakeLists\.txt|\.cmake)$"
comment "#"
icolor green "^[[:space:]]*[A-Z0-9_]+" icolor green "^[[:space:]]*[A-Z0-9_]+"
icolor brightyellow "^[[:space:]]*(include|include_directories|include_external_msproject)\>" icolor brightyellow "^[[:space:]]*(include|include_directories|include_external_msproject)\>"

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for CSS files. ## Here is an example for CSS files.
syntax "css" "\.css$" syntax "css" "\.css$"
comment "/*|*/"
color brightred "." color brightred "."
color brightyellow start="\{" end="\}" color brightyellow start="\{" end="\}"

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for apt's sources.list. ## Here is an example for apt's sources.list.
syntax "sources.list" "sources\.list(~|\.old|\.save)?$" "sources\.list\.d/.*\.list(~|\.old|\.save)?$" 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 # Coloring the deb lines, working from tail to head. First the
# components -- well, everything, and thus also the components. # components -- well, everything, and thus also the components.

Просмотреть файл

@ -2,6 +2,7 @@
## for files that do not match any other syntax. ## for files that do not match any other syntax.
syntax "default" syntax "default"
comment "#"
# Spaces in front of tabs. # Spaces in front of tabs.
color ,red " + +" color ,red " + +"

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for Emacs Lisp. ## Here is an example for Emacs Lisp.
syntax "elisp" "\.el$" syntax "elisp" "\.el$"
comment ";"
# Basic functions/macros # Basic functions/macros
color brightcyan "\<(if|when|unless|cond|and|or|lambda|let|progn|while|dolist|dotimes)\>" 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. ## Here is an example for Fortran 90/95.
syntax "fortran" "\.(f|f90|f95)$" syntax "fortran" "\.(f|f90|f95)$"
comment "!"
color red "\<[0-9]+\>" color red "\<[0-9]+\>"

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for Gentoo ebuilds/eclasses. ## Here is an example for Gentoo ebuilds/eclasses.
syntax "ebuild" "\.e(build|class)$" syntax "ebuild" "\.e(build|class)$"
comment "#"
## All the standard portage functions ## All the standard portage functions
color brightgreen "(^|\<default_)src_(unpack|prepare|configure|compile|install|test)\>" color brightgreen "(^|\<default_)src_(unpack|prepare|configure|compile|install|test)\>"

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for Go. ## Here is an example for Go.
syntax "go" "\.go$" syntax "go" "\.go$"
comment "//"
# Set up a formatter since spelling is probably useless... # Set up a formatter since spelling is probably useless...
formatter gofmt -w formatter gofmt -w

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for groff. ## Here is an example for groff.
syntax "groff" "\.m[ems]$" "\.rof" "\.tmac$" "^tmac." syntax "groff" "\.m[ems]$" "\.rof" "\.tmac$" "^tmac."
comment ".\""
# The argument of .ds or .nr # The argument of .ds or .nr
color cyan "^\.(ds|nr) [^[:space:]]*" color cyan "^\.(ds|nr) [^[:space:]]*"

Просмотреть файл

@ -3,6 +3,7 @@
syntax "guile" "\.scm$" syntax "guile" "\.scm$"
header "^#!.*guile" header "^#!.*guile"
magic "guile" magic "guile"
comment ";"
# Basic scheme functions # Basic scheme functions
color green "\<(do|if|lambda|let(rec)?|map|unless|when)\>" color green "\<(do|if|lambda|let(rec)?|map|unless|when)\>"

Просмотреть файл

@ -2,7 +2,10 @@
syntax "html" "\.html?$" syntax "html" "\.html?$"
magic "HTML document text" magic "HTML document text"
comment "<!--|-->"
color cyan start="<" end=">" color cyan start="<" end=">"
color red "&[^;[:space:]]*;" color red "&[^;[:space:]]*;"
color green ""(\\.|[^"])*"" color green ""(\\.|[^"])*""
color yellow start="<!--" end="-->"

Просмотреть файл

@ -2,6 +2,7 @@
syntax "java" "\.java$" syntax "java" "\.java$"
magic "Java " magic "Java "
comment "//"
color green "\<(boolean|byte|char|double|float|int|long|new|short|this|transient|void)\>" 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)\>" 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. ## Here is an example for Javascript.
syntax "javascript" "\.js$" syntax "javascript" "\.js$"
comment "//"
color brightred "\<[A-Z_][0-9A-Z_]+\>" color brightred "\<[A-Z_][0-9A-Z_]+\>"
color green "\<(const|function|let|this|typeof|var|void)\>" color green "\<(const|function|let|this|typeof|var|void)\>"

Просмотреть файл

@ -5,6 +5,8 @@
# License: GPLv3 or newer # License: GPLv3 or newer
syntax "json" "\.json$" syntax "json" "\.json$"
# No comments are permitted in JSON.
comment ""
# Numbers (used as value). # Numbers (used as value).
color green ":[[:space:]]*\-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee]?[-+]?[0-9]+)?" color green ":[[:space:]]*\-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee]?[-+]?[0-9]+)?"

Просмотреть файл

@ -5,6 +5,7 @@
## Version: 2011-05-05 ## Version: 2011-05-05
syntax "lua" "\.lua$" syntax "lua" "\.lua$"
comment "--"
color brightwhite "\[\[.*\]\]" color brightwhite "\[\[.*\]\]"

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for Makefiles. ## Here is an example for Makefiles.
syntax "makefile" "Makefile[^/]*$" "\.(make|mk)$" syntax "makefile" "Makefile[^/]*$" "\.(make|mk)$"
comment "#"
color red "[:=]" color red "[:=]"
color magenta "\<(if|ifeq|else|endif)\>" color magenta "\<(if|ifeq|else|endif)\>"

Просмотреть файл

@ -2,6 +2,7 @@
syntax "man" "\.[1-9]x?$" syntax "man" "\.[1-9]x?$"
magic "troff or preprocessor input text" magic "troff or preprocessor input text"
comment ".\""
color green "\.(SH|SS|TH) .*$" color green "\.(SH|SS|TH) .*$"
color brightgreen "\.(SH|SS|TH) " "\.([HIT]P)" color brightgreen "\.(SH|SS|TH) " "\.([HIT]P)"

Просмотреть файл

@ -2,6 +2,7 @@
syntax "mgp" "\.mgp$" syntax "mgp" "\.mgp$"
header "^%include.*" header "^%include.*"
comment "#"
icolor green "^%[a-z].*$" icolor green "^%[a-z].*$"
color cyan "(^|[[:space:]])#.*$" color cyan "(^|[[:space:]])#.*$"

Просмотреть файл

@ -1,9 +1,10 @@
## Here is an example for nanorc files. ## Here is an example for nanorc files.
syntax "nanorc" "\.?nanorc$" syntax "nanorc" "\.?nanorc$"
comment "#"
# Possible errors and parameters # 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 # 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)\>" 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:]]*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:]]*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:]]*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 brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|linter|formatter)[[:space:]]+.*$"
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|linter|formatter|extendsyntax)\>" icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|extendsyntax)\>"
# Colors # Colors
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>" 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)$" syntax "nftables" "\.(nft|nftables)$"
header "^#!.*(nft|nftables)" header "^#!.*(nft|nftables)"
comment "#"
# Objects and operations # Objects and operations
color green "\<(chain|hook|policy|priority|ruleset|set|table|type|v?map)\>" 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. ## Here is an example for C/C++/Obj-C.
syntax "m" "\.m$" syntax "m" "\.m$"
comment "//"
# Stuffs, # Stuffs,
color brightwhite "\<[A-Z_][0-9A-Z_]+\>" color brightwhite "\<[A-Z_][0-9A-Z_]+\>"

Просмотреть файл

@ -1,6 +1,7 @@
## Syntax highlighting for OCaml. ## Syntax highlighting for OCaml.
syntax "ocaml" "\.mli?$" syntax "ocaml" "\.mli?$"
comment "(*|*)"
# Uid: # Uid:
color red "\<[A-Z][0-9a-z_]{2,}\>" color red "\<[A-Z][0-9a-z_]{2,}\>"

Просмотреть файл

@ -2,6 +2,8 @@
syntax "patch" "\.(patch|diff|debdiff)$" syntax "patch" "\.(patch|diff|debdiff)$"
magic "diff output text" magic "diff output text"
# There is no official support for comments in patch files.
comment ""
# Added lines. # Added lines.
color brightgreen "^\+.*" color brightgreen "^\+.*"

Просмотреть файл

@ -3,6 +3,7 @@
syntax "perl" "\.p[lm]$" syntax "perl" "\.p[lm]$"
header "^#!.*perl[-0-9._]*" header "^#!.*perl[-0-9._]*"
magic "Perl script text" 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 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)\>" 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~]?$" syntax "php" "\.php[2345s~]?$"
magic "PHP script text" magic "PHP script text"
comment "//"
# PHP markings. # PHP markings.
color brightgreen "(<\?(php)?|\?>)" color brightgreen "(<\?(php)?|\?>)"

Просмотреть файл

@ -1,6 +1,7 @@
## Colouring for PO files. ## Colouring for PO files.
syntax "po" "\.pot?$" syntax "po" "\.pot?$"
comment "#"
# Comments. # Comments.
color green "^#.*$" color green "^#.*$"

Просмотреть файл

@ -2,6 +2,7 @@
syntax "sql" "\.sql[2345s~]?$" syntax "sql" "\.sql[2345s~]?$"
magic "PostgreSQL script text" magic "PostgreSQL script text"
comment "-- "
# Functions. # Functions.
color white "\<[a-z_]*\(" color white "\<[a-z_]*\("

Просмотреть файл

@ -1,6 +1,7 @@
## Here is an example for POV-Ray. ## Here is an example for POV-Ray.
syntax "pov" "\.(pov|POV|povray|POVRAY)$" syntax "pov" "\.(pov|POV|povray|POVRAY)$"
comment "//"
color brightcyan "^[[:space:]]*#[[:space:]]*(declare)" color brightcyan "^[[:space:]]*#[[:space:]]*(declare)"
color brightyellow "\<(sphere|cylinder|translate|matrix|rotate|scale)\>" color brightyellow "\<(sphere|cylinder|translate|matrix|rotate|scale)\>"

Просмотреть файл

@ -3,6 +3,7 @@
syntax "python" "\.py$" syntax "python" "\.py$"
header "^#!.*python[-0-9._]*" header "^#!.*python[-0-9._]*"
linter pyflakes linter pyflakes
comment "#"
# Function definitions. # Function definitions.
icolor brightblue "def [0-9A-Z_]+" icolor brightblue "def [0-9A-Z_]+"

Просмотреть файл

@ -3,6 +3,7 @@
syntax "ruby" "\.rb$" syntax "ruby" "\.rb$"
header "^#!.*ruby[-0-9._]*" header "^#!.*ruby[-0-9._]*"
linter ruby -w -c linter ruby -w -c
comment "#"
# Reserved words. # Reserved words.
color yellow "\<(BEGIN|END|alias|and|begin|break|case|class|def|defined\?|do|else|elsif|end|ensure|false|for|if|in|module)\>" 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)" header "^#!.*((ba|da|k|pdk)?sh[-0-9_]*|openrc-run|runscript)"
magic "(POSIX|Bourne.*) shell script text" magic "(POSIX|Bourne.*) shell script text"
linter dash -n linter dash -n
comment "#"
icolor brightgreen "^[0-9A-Z_]+\(\)" 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)\>" 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 highlighting for RPM spec files.
syntax "spec" "\.(spec$|spec\.*)" syntax "spec" "\.(spec$|spec\.*)"
comment "#"
# Main tags. # Main tags.
color brightblue "((Icon|ExclusiveOs|ExcludeOs)[[:space:]]*:)" color brightblue "((Icon|ExclusiveOs|ExcludeOs)[[:space:]]*:)"

Просмотреть файл

@ -1,6 +1,7 @@
## Syntax highlighting for Tcl files. ## Syntax highlighting for Tcl files.
syntax "tcl" "\.tcl$" syntax "tcl" "\.tcl$"
comment "#"
# Standard Tcl [info commands]: # 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)\>" 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$" syntax "tex" "\.tex$"
linter chktex -v0 -q -I linter chktex -v0 -q -I
comment "%"
icolor green "\\.|\\[A-Z]*" icolor green "\\.|\\[A-Z]*"
color magenta "[{}]" color magenta "[{}]"

Просмотреть файл

@ -3,6 +3,7 @@
syntax "texinfo" "\.texi$" syntax "texinfo" "\.texi$"
header "^\\input texinfo" header "^\\input texinfo"
magic "Texinfo source text" magic "Texinfo source text"
comment "@c "
# Command arguments, trailing and enclosed. # Command arguments, trailing and enclosed.
color cyan "^@[a-z]+[[:space:]]+.*$" 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)$" 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" magic "(XML|SGML) (sub)?document text"
comment "<!--|-->"
# The entire content of the tag: # The entire content of the tag:
color green start="<" end=">" 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 file. This functionality only works when libmagic is installed on the
system and will be silently ignored otherwise. 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{} @item color fgcolor,bgcolor "regex" @dots{}
Display all pieces of text that match the Display all pieces of text that match the
extended regular expression "regex" with foreground color "fgcolor" and extended regular expression "regex" with foreground color "fgcolor" and
@ -918,7 +928,7 @@ to @code{icolor}.
@item extendsyntax str directive [arg @dots{}] @item extendsyntax str directive [arg @dots{}]
Extend the syntax previously defined as str to include new information. Extend the syntax previously defined as str to include new information.
This allows you to add a new @code{color}, @code{icolor}, @code{header}, 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 defined syntax --- useful when you want to slightly improve a syntax defined
in one of the system-installed files (which are normally not writable). 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 @item unindent
Unindents (shifts to the left) the currently marked text. 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 @item left
Goes left one position (in the editor or browser). Goes left one position (in the editor or browser).

Просмотреть файл

@ -554,6 +554,9 @@ void shortcut_init(void)
N_("Copy the current line and store it in the cutbuffer"); N_("Copy the current line and store it in the cutbuffer");
const char *nano_indent_msg = N_("Indent the current line"); const char *nano_indent_msg = N_("Indent the current line");
const char *nano_unindent_msg = N_("Unindent 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_undo_msg = N_("Undo the last operation");
const char *nano_redo_msg = N_("Redo the last undone operation"); const char *nano_redo_msg = N_("Redo the last undone operation");
#endif #endif
@ -937,6 +940,10 @@ void shortcut_init(void)
add_to_funcs(do_suspend_void, MMAIN, add_to_funcs(do_suspend_void, MMAIN,
N_("Suspend"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW); 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 #ifndef NANO_TINY
add_to_funcs(do_savefile, MMAIN, add_to_funcs(do_savefile, MMAIN,
N_("Save"), IFSCHELP(nano_savefile_msg), BLANKAFTER, NOVIEW); 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-{", do_unindent, 0);
add_to_sclist(MMAIN, "M-U", do_undo, 0); add_to_sclist(MMAIN, "M-U", do_undo, 0);
add_to_sclist(MMAIN, "M-E", do_redo, 0); add_to_sclist(MMAIN, "M-E", do_redo, 0);
#endif
#ifdef ENABLE_COMMENT
add_to_sclist(MMAIN, "M-3", do_comment, 0);
#endif #endif
add_to_sclist(MMOST, "^B", do_left, 0); add_to_sclist(MMOST, "^B", do_left, 0);
add_to_sclist(MMOST, "Left", 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")) else if (!strcasecmp(input, "endpara"))
s->scfunc = do_para_end_void; s->scfunc = do_para_end_void;
#endif #endif
#ifdef ENABLE_COMMENT
else if (!strcasecmp(input, "comment"))
s->scfunc = do_comment;
#endif
#ifndef NANO_TINY #ifndef NANO_TINY
else if (!strcasecmp(input, "indent")) else if (!strcasecmp(input, "indent"))
s->scfunc = do_indent_void; s->scfunc = do_indent_void;

Просмотреть файл

@ -996,6 +996,9 @@ void version(void)
#ifdef DISABLE_COLOR #ifdef DISABLE_COLOR
printf(" --disable-color"); printf(" --disable-color");
#endif #endif
#ifndef ENABLE_COMMENT
printf(" --disable-comment");
#endif
#ifdef DISABLE_EXTRA #ifdef DISABLE_EXTRA
printf(" --disable-extra"); printf(" --disable-extra");
#endif #endif

Просмотреть файл

@ -191,6 +191,9 @@ typedef enum {
ADD, DEL, BACK, CUT, CUT_EOF, REPLACE, ADD, DEL, BACK, CUT, CUT_EOF, REPLACE,
#ifndef DISABLE_WRAPPING #ifndef DISABLE_WRAPPING
SPLIT_BEGIN, SPLIT_END, SPLIT_BEGIN, SPLIT_END,
#endif
#ifndef DISABLE_COMMENT
COMMENT, UNCOMMENT, PREFLIGHT,
#endif #endif
JOIN, PASTE, INSERT, ENTER, OTHER JOIN, PASTE, INSERT, ENTER, OTHER
} undo_type; } undo_type;
@ -251,6 +254,8 @@ typedef struct syntaxtype {
/* The command with which to lint this type of file. */ /* The command with which to lint this type of file. */
char *formatter; char *formatter;
/* The formatting command (for programming languages mainly). */ /* The formatting command (for programming languages mainly). */
char *comment;
/* The line comment prefix (and postfix) for this type of file. */
colortype *color; colortype *color;
/* The colors and their regexes used in this syntax. */ /* The colors and their regexes used in this syntax. */
int nmultis; int nmultis;
@ -322,6 +327,14 @@ typedef struct partition {
} partition; } partition;
#ifndef NANO_TINY #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 { typedef struct undo {
ssize_t lineno; ssize_t lineno;
undo_type type; undo_type type;
@ -336,6 +349,8 @@ typedef struct undo {
/* The file size after the action. */ /* The file size after the action. */
int xflags; int xflags;
/* Some flag data we need. */ /* Some flag data we need. */
undo_group *grouping;
/* Undo info specific to groups of lines. */
/* Cut-specific stuff we need. */ /* Cut-specific stuff we need. */
filestruct *cutbuffer; filestruct *cutbuffer;

Просмотреть файл

@ -653,6 +653,9 @@ void do_unindent(void);
void do_undo(void); void do_undo(void);
void do_redo(void); void do_redo(void);
#endif #endif
#ifndef DISABLE_COMMENT
void do_comment(void);
#endif
void do_enter(void); void do_enter(void);
#ifndef NANO_TINY #ifndef NANO_TINY
RETSIGTYPE cancel_command(int signal); 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 discard_until(const undo *thisitem, openfilestruct *thefile);
void add_undo(undo_type action); void add_undo(undo_type action);
void update_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 #endif
size_t get_totsize(const filestruct *begin, const filestruct *end); size_t get_totsize(const filestruct *begin, const filestruct *end);
filestruct *fsfromline(ssize_t lineno); filestruct *fsfromline(ssize_t lineno);

Просмотреть файл

@ -306,6 +306,7 @@ void parse_syntax(char *ptr)
live_syntax->magics = NULL; live_syntax->magics = NULL;
live_syntax->linter = NULL; live_syntax->linter = NULL;
live_syntax->formatter = NULL; live_syntax->formatter = NULL;
live_syntax->comment = NULL;
live_syntax->color = NULL; live_syntax->color = NULL;
lastcolor = NULL; lastcolor = NULL;
live_syntax->nmultis = 0; 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. */ /* Allow unsetting the command by using an empty string. */
if (!strcmp(ptr, "\"\"")) if (!strcmp(ptr, "\"\""))
*storage = NULL; *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 else
*storage = mallocstrcpy(NULL, ptr); *storage = mallocstrcpy(NULL, ptr);
} }
@ -982,6 +1001,12 @@ void parse_rcfile(FILE *rcstream
grab_and_store("magic", ptr, &live_syntax->magics); grab_and_store("magic", ptr, &live_syntax->magics);
#else #else
; ;
#endif
else if (strcasecmp(keyword, "comment") == 0)
#ifdef ENABLE_COMMENT
pick_up_name("comment", ptr, &live_syntax->comment);
#else
;
#endif #endif
else if (strcasecmp(keyword, "color") == 0) else if (strcasecmp(keyword, "color") == 0)
parse_colors(ptr, NANO_REG_EXTENDED); parse_colors(ptr, NANO_REG_EXTENDED);

Просмотреть файл

@ -425,7 +425,194 @@ void do_unindent(void)
{ {
do_indent(-tabsize); 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 redo_paste undo_cut
#define undo_paste redo_cut #define undo_paste redo_cut
@ -574,6 +761,16 @@ void do_undo(void)
unlink_node(f->next); unlink_node(f->next);
goto_line_posx(u->lineno, u->begin); goto_line_posx(u->lineno, u->begin);
break; 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: case INSERT:
undidmsg = _("text insert"); undidmsg = _("text insert");
filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom; filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
@ -738,6 +935,16 @@ void do_redo(void)
free_filestruct(u->cutbuffer); free_filestruct(u->cutbuffer);
u->cutbuffer = NULL; u->cutbuffer = NULL;
break; 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: default:
statusline(ALERT, _("Internal error: unknown type. " statusline(ALERT, _("Internal error: unknown type. "
"Please save your work.")); "Please save your work."));
@ -909,11 +1116,20 @@ bool execute_command(const char *command)
void discard_until(const undo *thisitem, openfilestruct *thefile) void discard_until(const undo *thisitem, openfilestruct *thefile)
{ {
undo *dropit = thefile->undotop; undo *dropit = thefile->undotop;
undo_group *group;
while (dropit != NULL && dropit != thisitem) { while (dropit != NULL && dropit != thisitem) {
thefile->undotop = dropit->next; thefile->undotop = dropit->next;
free(dropit->strdata); free(dropit->strdata);
free_filestruct(dropit->cutbuffer); 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); free(dropit);
dropit = thefile->undotop; dropit = thefile->undotop;
} }
@ -969,6 +1185,7 @@ void add_undo(undo_type action)
u->mark_set = FALSE; u->mark_set = FALSE;
u->wassize = openfile->totsize; u->wassize = openfile->totsize;
u->xflags = 0; u->xflags = 0;
u->grouping = NULL;
switch (u->type) { switch (u->type) {
/* We need to start copying data into the undo buffer /* We need to start copying data into the undo buffer
@ -1036,6 +1253,11 @@ void add_undo(undo_type action)
break; break;
case ENTER: case ENTER:
break; break;
#ifdef ENABLE_COMMENT
case COMMENT:
case UNCOMMENT:
break;
#endif
default: default:
statusline(ALERT, _("Internal error: unknown type. " statusline(ALERT, _("Internal error: unknown type. "
"Please save your work.")); "Please save your work."));
@ -1049,6 +1271,42 @@ void add_undo(undo_type action)
openfile->last_action = 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 /* Update an undo item, or determine whether a new one is really needed
* and bounce the data to add_undo instead. The latter functionality * and bounce the data to add_undo instead. The latter functionality
* just feels gimmicky and may just be more hassle than it's worth, * just feels gimmicky and may just be more hassle than it's worth,