Problems with New Language Mode

Tony Balinski ajbj at free.fr
Thu Apr 26 16:59:12 CEST 2007


Quoting Aaron Hsu <arcfide at sacrificumdeo.net>:

> On Tue, 24 Apr 2007 07:59:54 -0500, Joerg Fischer <jf505 at gmx.de> wrote:
>
> >> Here's an algorithm:
> > I'll have a look.
>
> I have the following code that I am trying, but obviously it isn't
> working. Maybe someone who is better at NEdit macrology would be able to
> help? newlineInserted is actually the macro whose body I am pasting into
> the newline macro box in the Program Smart Indent macros window.
...
It looks like you're nearly there. The problem, I think (I haven't tested),
is that you are returning a position from your newlineInserted() function,
not a distance. I expect you find it creates ridiculously long lines!

You have your position s of the previously non-balanced open paren: you need
to measure its distance from the left margin:

define startOfLine {
  # Start searching at prev position, since search stop at match
  # but if get_character($1) == \n, we would stop immediately, but be at
  # a line end!
  # We add 1 to the result because we want the position FOLLOWING the \n;
  # note that this conveniently gives us 0 if search fails (on the first
  # line of the file).
  pos = $1
  return 1 + search("\n", pos - 1, "backward")
}

define columnAtPos {
  # measure the display columns from the left margin to the position
  # passed as $1
  right = $1
  left = startOfLine(right)
  pos = left
  col = 0
  end = pos
  while (1) {
    pos = search("\t", end); # find next tabs in line segment
    if (pos < 0 || pos > right) {
      col += right - end # count remaining single width chars upto right
      break
    }
    # else
    col += pos - end  # single-col chars from last end upto next tab at pos
    end = pos + 1 # position after last tab in tab sequence found
    col += $tab_dist - (col % $tab_dist)
  }
  return col
}

# your function, amended
define newlineInserted {
  special["let"] = 2
  special["lambda"] = 2
  special["case"] = 2
  special["let*"] = 2
  special["letrec"] = 2

  s = findOpenParen($1)
  if (s <= 0) # no unmatched open paren
    return 0  # next line starts with no indent

  cols = columnAtPos(s) # how many cols at open paren?
  # how many "arguments" on the open paren line?
  args = split(get_range(s, endOfLine(s)), "\\s+", "regexp")
  n_args = args[]

  if (n_args == 0) {
    return cols + 1
  } else if (n_args == 1) {
    return cols + 2
  } else if (n_args > 1) {
    if (args[0] in special) {
      if (n_args >= special[args[0]]) {
        return cols + 2
      } else {
        return cols + argStart(s)
      }
    } else {
      return cols + argStart(s)
    }
  }
  # if in doubt just indent this line like the last!
  return -1
}


More information about the Discuss mailing list