==What it does==
The Lisp:comment-edit.el lib allows creation/editing of shell-like (aka end-of-line) comments in a dedicated buffer. When the ##comment-edit## command is invoked, a buffer is popped up and the user edits the command as ordinary text in that buffer. When she is finished editing, ##C-cC-c## pops down the edit buffer and inserts the text with proper comment syntax into the original buffer.

==Installation==
Put the source file  into your %%load-path%%, optionally byte  compile it (with:
##emacs  -batch -f  batch-byte-compile comment-edit.el##)  and plop  the
following into your ##~/.emacs##:

{{{
(require 'comment-edit)
}}}



==Usage and description==
This code allows to create and/or edit shell-like (aka end-of-line)
comments in a dedicated buffer.

When the user invokes the main command, ##M-x comment-edit##, a
temporary buffer is popped up and the user typesets the comment as
ordinary text. When finished, typing ##C-cC-c## in the temporary
buffer pops down it and inserts the comment text into the original
buffer with the proper comment syntax.

The code was inspired by (and partially stolen from) ##c-comment-edit2##,
which does the same service for the block comments of the C language.

The main end-user commands are:

; ##M-x comment-edit##: create/edit a comment using current style (I bind this to ##C-ce##)
; ##C-uN M-x comment-edit##: create/edit a comment using style N
and set style N as the current
style (N=1,4; comment styles shown below)
; ##C-cC-c##: finish editing and insert comment text into the original buffer
; ##C-uC-cC-c##: abort current edit, pop down the edit buffer and go back to the original buffer unchanged
; ##C-u M-x comment-edit##: ask in the minibuffer for the style to be set as the default for future calls

When the edited text is pasted into the original buffer, this can be
done in one of (presently) four possible (fairly customizable) comment styles
(following examples are for the unix shell language)

; Style n. 1: "simplest"
 
{{{
     # comment line 1
     # comment line 2
     # comment line 3
}}}
 
; Style n. 2: "simple"
 
{{{
     #
     # comment line 1
     # comment line 2
     # comment line 3
     #
}}}
 
; Style n. 3: "narrow-box"
 
{{{
     ##################
     # comment line 1 #
     # comment line 2 #
     # comment line 3 #
     ##################
}}}
 
; Style n. 4: "wide-box"
 
{{{
     ########################################################################
     # comment line 1                                                       #
     # comment line 2                                                       #
     # comment line 3                                                       #
     ########################################################################
}}}

===Comment style customization===

Comments have the following general structure:

{{{
       <s1><b2><c><c>...<c><c><b3>
       <s1><s2>comment line 1 <s3>
       <s1><s2>comment line 2 <s3>
               .....
       <s1><s2>comment line n <s3>
       <s1><b2><c><c>...<c><c><b3>
}}}

where the various components are stored into user customizable variables as
detailed below.

{{{
comp.     variable                 explanation
-----------------------------------------------------------------------
<s1> comment-edit-comment-string  this is the comment string as defined  by the language (i.e. # for shell, % for latex,
                                  ; for lisp etc). NOTE: it is a string  (not a char), since for some languages this can
                                  have >1 chars (e.g.  "REM") or the user might want to define  this to multiple comment
                                  chars, e.g. "###"||
<s2> comment-edit-comment-leader  this  string is inserted *AFTER* comment-edit-comment-string at  the beginning of each
                                  line of the comment text
<s3> comment-edit-comment-trailer this string is  used for *-box style comments only and is inserted  at the end of each
                                  line of the comment text
<b2>  comment-edit-line-leader    this  string  is  used  for  *-box style  comments  only  and  is  inserted  *AFTER*
                                  comment-edit-comment-string  at the  beginning  of the  FIRST and  LAST  lines of  the
                                  comment text (see above)
<b3> comment-edit-line-trailer    this  string is used for *-box style  comments only and is inserted at  the end of the
                                  FIRST and LAST lines of the comment text (see above)
<c>  comment-edit-line-filler     this is a  char (not a string) used for *-box style comments  only; the FIRST and LAST
                                  lines of the boxed comment will be filled with this character
}}}

Example.

If:

{{{
comment-edit-comment-string   "REM"
comment-edit-comment-leader   " "
comment-edit-comment-trailer  " |"
comment-edit-line-leader      " + "
comment-edit-line-filler      ?-
comment-edit-line-trailer     " +"
}}}

then the appearance of the comments in the four styles is like this:

{{{
REM I am a comment
REM in the simplest style


REM
REM I am a comment
REM in the simple style
REM


REM +-------------------- +
REM I am a comment in the |
REM narrow-box style      |
REM +-------------------- +


REM +------------------------------------------------------------------- +
REM I am a comment in the                                                |
REM wide-box style                                                       |
REM +------------------------------------------------------------------- +
}}}

The variables defining the different comment styles are set according
to the buffer mode and, optionally, to the extension of the name of
the file being edited or the name of the buffer (if the buffer is not
visiting any file). Basically, the buffer mode and optionally the file or
buffer name are matched against corresponding regexes: if the match
succeeds, then the variables are set accordingly. All the pieces
needed for this mechanism are stored into the user customizable
##comment-edit-language-selector## variable. This is a list of 2-elements
lists: the first element of each is a list of 1 or 2 elements, the
second element is a list of 6 elements:

{{{
        comment-edit-language-selector:

         '(
           ( (regex1 [regex2]) (s1 s2 s3 s4 c s5) )
          ...
           ( (regex1 [regex2]) (s1 s2 s3 s4 c s5) )
          )

}}}

; ##(regex1 [regex2])##:   is a list of 1 or 2 elements
                    The first element is a regex (string) to be
                    matched against
                    ##(format-mode-line mode-line-format)##
                    If the second element is
                    present, it is interpreted as a regex (string)
                    to be matched against either the extension of
                    the name of the file being visited or the
                    buffer name
                    If both elements are present, then both matches
                    must be successful
; ##(s1 s2 s3 s4 c s5)##:  is a list of 6 elements: s1 s2 s3 s4 and s5 are
                    strings, while c is a char.
                    These are the values of the variables defining the
                    comment styles for the buffer matching the
                    conditions defined by the ##(regex1 [regex2])##
                    list. More specifically:

{{{
             s1  -->  comment-edit-comment-string   
             s2  -->  comment-edit-comment-leader   
             s3  -->  comment-edit-comment-trailer  
             s4  -->  comment-edit-line-leader      
             c   -->  comment-edit-line-filler      
             s5  -->  comment-edit-line-trailer     
}}}

The tests defined by the elements of ##comment-edit-language-selector##
are performed sequentially and the loop terminates on the first
success.

A default ##comment-edit-language-selector## value is set in the code:

{{{
          (defcustom comment-edit-language-selector
            '(
              (("(Shell-script")("#"" "" #"""?#""))
              (("(Tcl")("#"" "" #"""?#""))
              (("(Fundamental")("#"" "" #"""?#""))
              (("(Text")("#"" "" #"""?#""))
              (("(Octave")("#"" "" #"""?#""))
              (("(Lisp")(";;" " " " ;;" "" ?; ""))
              (("(Emacs-Lisp")(";;" " " " ;;" "" ?; ""))
              (("(TeX")("%%" " " " %%" "" ?% ""))
              (("(LaTeX")("%%" " " " %%" "" ?% ""))
              (("(BibTeX")("%%" " " " %%" "" ?% ""))
              (("(Texinfo")("@c" " " " |" "" ?= "|"))
              (("(C\+\+")("//" " " " |" "" ?= "|"))
              (("(Fortran")("C" " " " |" "" ?= "|"))
              (("(F90")("!" " " " |" "" ?= "|"))
              )
}}}

but the user is expected to define her own
##comment-edit-language-selector## variable, based on the languages
usually spoken and preferences for the comment appearance.

===Creating new comments vs editing existing comments===
* In order to edit an existing comment, position the cursor anywhere inside the comment text and invoke ##comment-edit##: the whole commented region is copied into the edit buffer for editing. The comment style currently in use should match that of the original comment region. However, if that is not the case, the comment will be pasted back in the *current* comment style, no matter what was the style of the original comment. Note that this doesn't always work since it wasn't planned, but it turns out that it works almost always.\\\\
If you want to change the style of an existing comment, just edit it with the new style as the current style  and make the necessary changes in the edit buffer, if needed (eg, delete end-of-line characters when converting ##*-box## into ##simple*## comments).\\\\

* In order to create a new comment, place the cursor at the position where you want the comment to appear

** if the cursor is placed on a non-empty, non-comment line, the comment
will be inserted before that line, indented as much as the
cursor position

** if the cursor is placed on an empty line, the comment is inserted at
that one line, indentation being determined again by the
cursor position

==Limitations==
* comments after code on the same line are *NOT* supported; eg:
{{{
     a=1  # comment-edit does not handle this comment
}}}


-------------------------------
CategoryComments
