VerilogFindPair

From Niki

Jump to: navigation, search

Verilog Find Pair

######################################################################
#
#  Custom token-based navigation for NEdit 5.1
#  Joachim Lous (joachim@nr.no)
#  March 2000
#
#  Modified by Gal Aviel Jan 2004
#
#  find_verilog_pair written by Guy Inbar, Jan 2005
#
#  Modified by Erez Amit, Jul 2006
#  erez.amit@gmail.com
#
######################################################################


$w = "a-zA-Z0-9_"  # word characters (explicitly, so they're easy to adjust)
$s = " \t\n"        # whitespace characters

define token_start_right {
    # What sort of character are we starting at?
    pos = $cursor
    pos_char = get_character(pos)

    # A word character:
    if ( search_string(pos_char, "["$w"]", 0, "regex") > -1 ){
        hit = search("["$w"]*["$s"]*", pos, "regex")
    }
    # A whitespace character:
    else if (search_string(pos_char, "["$s"]", 0, "regex") > -1 ) {
        hit = search("["$s"]*", pos, "regex")
    }
    # Other (=delimiter):
    else {
        hit = search("[^"$w$s"]*["$s"]*", pos, "regex")
    }

    if(hit == -1) return $text_length
    return $search_end
}

define token_end_right {
    # What sort of character are we starting at?
    pos = $cursor
    pos_char = get_character(pos)

    # A word character:
    if ( search_string(pos_char, "["$w"]", 0, "regex") > -1 ){
        hit = search("["$w"]*", pos, "regex")
    }
    # A whitespace character:
    else if (search_string(pos_char, "["$s"]", 0, "regex") > -1 ) {
        hit = search("["$s"]+(["$w"]+|[^"$w$s"]+)", pos, "regex")
    }
    # Other (=delimiter):
    else {
        hit = search("[^"$w$s"]*", pos, "regex")
    }

    # Handle end-of file:
    if(hit == -1) return $text_length
    return $search_end
}

define token_start_left {
    # What sort of character are we starting at?
    pos = $cursor-1
    pos_char = get_character(pos)

    # A word character?
    if ( search_string(pos_char, "["$w"]", 0, "regex") > -1 ){
        hit = search("[^"$w"]|\n", pos, "regex", "backward")
    }
    # A whitespace character?
    else if (search_string(pos_char, "["$s"]", 0, "regex") > -1 ) {
        hit = search("([^"$w"]["$w"]|["$s$w"][^"$s$w"])", pos-1, "regex", "backward")
    }
    # Other (=delimiter)
    else {
        hit = search("["$w$s"]|\n", pos, "regex", "backward")
    }
    return hit+1
}

define token_end_left {
    # What sort of character are we starting at?
    pos = $cursor-1
    pos_char = get_character(pos)

    # A word character?
    if ( search_string(pos_char, "["$w"]", 0, "regex") > -1 ){
        hit = search("([^"$s"]["$s"]|[^"$w$s"])", pos-1, "regex", "backward")
    }
    # A whitespace character?
    else if (search_string(pos_char, "["$s"]", 0, "regex") > -1 ) {
        hit = search("[^"$s"]", pos, "regex", "backward")
    }
    # Other (=delimiter)
    else {
        hit = search("([^"$s"]["$s"]|["$w"])", pos-1, "regex", "backward")
    }
    return hit+1
}

define get_right {
    # get the minimum
    if ( token_start_right() <= token_end_right() ) {
        right = token_start_right()
    }
    else {
        right = token_end_right()
    }
    return right
}

define get_left {
    # get the maximum
    if ( token_start_left() <= token_end_left() ) {
        left = token_end_left()
    }
    else {
        left = token_start_left()
    }
    return left
}

define select_word {
  deselect_all()

  right_char = get_character($cursor)
  backward_character("nobell")
  left_char = get_character($cursor)
  forward_character("nobell")

  is_rc_space = search_string(right_char,"[ \n\t]",0,"regex")
  is_lc_space = search_string(left_char,"[ \n\t]",0,"regex")

  if ((is_rc_space == 0) && (is_lc_space == 0)) {
    move_token_boundry_right()
    select_token_boundry_left()
  } else {
    is_rc_part_of_word = search_string(right_char,"[a-zA-Z0-9_]",0,"regex")
    is_lc_part_of_word = search_string(left_char ,"[a-zA-Z0-9_]",0,"regex")
    if ((is_lc_part_of_word == -1) && (is_rc_part_of_word == -1)) {
      forward_word("nobell")
    }
    if (!((is_lc_part_of_word == -1) && (is_rc_part_of_word != -1))) {
      backward_word("nobell")
    }
    sel_start = $cursor
    forward_word("tail","nobell")
    sel_end = $cursor
    select (sel_start, sel_end)
  }
}

define find_verilog_pair {
  # find the pair for a verilog reserved word
  select_word()

  # can be begin, end , case, endcase (module , endmodule)
  user_sel=get_selection()

  if (user_sel=="begin") {
    find_forward_pair("begin","end")
    return
  }

  if (user_sel=="end") {
    find_backward_pair("begin","end")
    return
  }

  if (user_sel=="case") {
    find_forward_pair("case","endcase","[\*\/ \t\n]","x?z?[\*\/ \t\n\(]","[\*\/ \t\n]","[\*\/ \t\n]")
    return
  }

  if (user_sel=="endcase") {
    find_backward_pair("case","endcase","[\*\/ \t\n]","x?z?[\*\/ \t\n\(]","[\*\/ \t\n]","[\*\/ \t\n]")
    return
  }

  if (user_sel=="module") {
    find_forward_pair("module","endmodule")
    return
  }

  if (user_sel=="endmodule") {
    find_backward_pair("module","endmodule")
    return
  }

  if (user_sel=="function") {
    find_forward_pair("function","endfunction")
    return
  }

  if (user_sel=="endfunction") {
    find_backward_pair("function","endfunction")
    return
  }

  if (user_sel=="for") {
    find_forward_pair("`for","`endfor")
    return
  }

  if (user_sel=="endfor") {
    find_backward_pair("`for","`endfor")
    return
  }

  errmsg = "Error: ["user_sel "] has no perdefined verilog pair\n"
  beep()
  dialog(errmsg ,"OK")
  return
}


define find_forward_pair {

  if ($n_args == 6) {
    pair1 = $3 $1 $4
    pair2 = $5 $2 $6
  } else {
    pair1 = "[\*:\/ \t\n]" $1 "[\*\/ \t\n]"
    pair2 = "[\*\/ \t\n]" $2 "[\*\/ \t\n]"
  }

  num_of_begin = 1

  while (num_of_begin > 0) {
    prev_cursor = $cursor
    next_begin_pos = search(pair1,prev_cursor,"regex")
    next_end_pos = search(pair2,prev_cursor,"regex")

    if (next_end_pos == -1) {
      errmsg = "no more " $2 "\n"
      dialog(errmsg ,"OK")
      break
    } else {
      if (next_begin_pos == -1) {
        #no more begin -
        set_cursor_pos(next_end_pos + 1)
        text_style = get_style_at_pos($cursor)
        if (text_style["style"] != "Comment") {
          num_of_begin = num_of_begin - 1
        }
      } else {
        # begin & end found
        if (next_begin_pos < next_end_pos) {
          set_cursor_pos(next_begin_pos + 1)
          text_style = get_style_at_pos($cursor)
          if (text_style["style"] != "Comment") {
            num_of_begin = num_of_begin + 1
          }
        } else {
          set_cursor_pos(next_end_pos + 1)
          text_style = get_style_at_pos($cursor)
          if (text_style["style"] != "Comment") {
            num_of_begin = num_of_begin - 1
          }
        }
      }
    }
  }
}


define find_backward_pair {

  if ($n_args == 6) {
    pair1 = $3 $1 $4
    pair2 = $5 $2 $6
  } else {
    pair1 = "[\*:\/ \t\n]" $1 "[\*\/ \t\n]"
    pair2 = "[\*\/ \t\n]" $2 "[\*\/ \t\n]"
  }

  num_of_end = 1

  prev_cursor = $cursor
  set_cursor_pos(search(pair2,prev_cursor,"regex","backward"))

  while (num_of_end > 0) {
    prev_cursor =get_left()
    next_begin_pos=search(pair1,prev_cursor,"regex","backward")
    next_end_pos=search(pair2,prev_cursor,"regex","backward")

    if (next_begin_pos==-1) {
      errmsg = "no more " $1 "\n"
      dialog(errmsg ,"OK")
      break
    } else {
      if (next_end_pos==-1) {
        #no more end
        set_cursor_pos(next_begin_pos)
        text_style = get_style_at_pos($cursor)
        if (text_style["style"] != "Comment") {
          num_of_end = num_of_end - 1
        }
      } else {
        # begin & end found
        if (next_begin_pos < next_end_pos) {
          set_cursor_pos(next_end_pos)
          text_style = get_style_at_pos($cursor)
          if (text_style["style"] != "Comment") {
            num_of_end = num_of_end + 1
          }
        } else {
          set_cursor_pos(next_begin_pos)
          text_style = get_style_at_pos($cursor)
          if (text_style["style"]!="Comment") {
            num_of_end = num_of_end - 1
          }
        }
      }
    }
  }
  set_cursor_pos($cursor + 1)
}