Page 1 of 1

Word wrap in C/C++ comments?

Posted: Fri Feb 24, 2006 4:21 am
by pchapin
Hello! I'm on my first day evaluating Zeus. So far I like what I see.

I've used Emacs for a long time and one Emacs feature that has become very important to me is its ability to do paragraph reformatting inside C/C++ comments. For example, if I edit a comment to clarify its content, I might end up with something like this:

// This is my comment. But it has been edited
// so now
// some lines are long and others are
// very short.
// Personally, I find this exceedingly ugly and I really
// can't tolerate it. However, having to manual fix this
// sort
// of thing is undesirable.

In Emacs I can do M-q and the comment block is semi-intelligently reformatted without disrupting the "//" comment marks at the start of each line.

How can I deal with this problem in Zeus?

Thanks!

Peter

Posted: Fri Feb 24, 2006 5:52 am
by jussij
Currently the only way to do this would be to write a Zeus macro.

For example I took some of the existing comment/uncomment code found in the current set of Zeus macros, and quickly produced this Lua macro that does somthing similar to what you describe:

Code: Select all

--
--        Name: Emacs Line Comment Cleaning Macro
--    Language: Lua Macro
--
-- Description: This Lua takes a commented marked area removes the
--              comments, wraps the text and then re-comments the
--              marked area.

dofile ("commentText.LUA")  -- #include file

function comment_text()
  -- default to the current line
  local top   = get_line_pos()
  local range = 1

  -- macro only works for marked documents
  local marked = is_marked()

  if marked == 1 then
    -- get the marked text details
    top   = get_marked_top()
    range = get_marked_bottom() - top + 1
  end -- if

  -- the default comment string
  local comment

  local comment2

  -- get the current file extensions
  local extension = macro_tag("$Ext")

  -- get the comment based on the file extension
  comment, comment2 = getComment(extension)

  if string.len(comment) > 0 then
    -- disable screen updates
    screen_update_disable()

    -- save the current cursor
    cursor_save()

    -- move to the fist line of the commented text
    set_line_pos(top)

    -- comment the lines selected
    repeat
      -- write out the comment string
      MoveLineHome()
      print(comment)
      if (comment2 ~= nil) then
         MoveLineEnd()
         print (comment2)
      end -- if
      MoveLineDown()
      range = range - 1
    until range == 0

    -- restore original cursor
    cursor_restore()

    -- restore screen updates
    screen_update_enable()
  else
    -- should not happen
    message("Unexoected error!")
  end
end

function uncomment_text()
  -- default to the current line
  local top   = get_line_pos()
  local range = 1

  -- macro only works for marked documents
  local marked = is_marked()

  if marked == 1 then
    -- get the marked text details
    top   = get_marked_top()
    range = get_marked_bottom() - top + 1
  end -- if

  -- the default comment string
  local comment
  local comment2

  -- get the current file extensions
  local extension = macro_tag("$Ext")

  comment, comment2 = getComment (extension)

  -- disable screen updates
  screen_update_disable()

  -- save cursor position
  cursor_save()

  -- move to the fist line of the commented text
  set_line_pos(top)

  local has_comment = false

  -- comment the lines selected
  repeat
    -- Get a copy of the current line to be uncommented.
    local text = get_line_text()

    -- Apparently, "--" does some sort of regular-expression matching that
    -- ends up deleting the first two characters of the line, even if they
    -- aren't an exact match.  Oops!  The first '1' is where to start, '1'
    -- being the first character of the string, and the second '1' means to
    -- turn off the regular expression pattern matching.

    MoveLineHome()
debug_output ("text="..text)
debug_output ("comment="..comment)
    if (string.find (text, comment, 1, 1) == 1) then
      local length = string.len ( comment )
      repeat
        CharDelete()
        length = length - 1
      until length == 0
      has_comment = true
    end -- if

    -- Now handle end-of-line comments.
    if (comment2 ~= nil) then
debug_output ("comment2="..comment2)
      local len = string.len (text)
      local cmtlen = string.len (comment2)
      local start = len-cmtlen+1
      if (start >= 1) then
        if (string.find (text, comment2, start, 1) == start) then
          MoveLineEnd ()
          repeat
            Backspace()
            cmtlen = cmtlen - 1
          until cmtlen == 0
        end -- if
      end -- if
    end -- if

    MoveLineDown()
    range = range - 1
    until range == 0

  -- restore cursor position
  cursor_restore()

  -- restore screen updates
  screen_update_enable()

  return has_comment
end -- key_macro

function key_macro()
  -- macro only works for documents
  local document = is_document()

  if document == 0 then
    message("This macro only works for document files!")
    beep()
    return
  end

  -- macro only works for read/write documents
  local locked = is_read_only()

  if locked == 1 then
    message("The current document is marked as read only!")
    beep()
    return
  end

  -- macro only works for marked documents
  local marked = is_marked()

  if marked == 1 then
    -- remove any comments
    local has_comment = uncomment_text()

    -- line wrap the marked area
    LineWrapMarkedArea()

    if has_comment == true then
        -- put back the comments
        comment_text()
    end
  else
    message("This macro requires a marked area!")
    beep()
  end
end

key_macro() -- run the macro
Given this c++ code snippet:

Code: Select all

// This is my comment. But it has been edited
// so now
// some lines are long and others are
// very short.
// Personally, I find this exceedingly ugly and I really
// can't tolerate it. However, having to manual fix this
// sort
// of thing is undesirable.
Marking the code and running the macro produces this output:

Code: Select all

// This is my comment. But it has been edited so now
// some lines are long and others are very short.
// Personally, I find this exceedingly ugly and I really can't tolerate it. 
// However, having to manual fix this sort
// of thing is undesirable. 
//
//
//
Running the macro a second time produces this output:

Code: Select all

// This is my comment. But it has been edited so now some lines are long and 
// others are very short. Personally, I find this exceedingly ugly and I 
// really can't tolerate it. However, having to manual fix this sort
// of thing is undesirable. 
// 
//
//
//
Note: The macro needed to be run twice because of a bug in the current Zeus line wrap function :(

This bug will be fixed in a future release.

Cheers Jussi

Thanks!

Posted: Fri Feb 24, 2006 4:19 pm
by pchapin
Thank you for your prompt and informative reponse. I appreciate you taking the time to put together that macro. I will try it out. This will also give me an opportunity to look at Lua some. I have no experience with it right now.

Peter