let indent_line (v : Ed_sourceview.sourceview) args =
  let line = v#current_line in
  let b = v#file#buffer in
  let pos = b#get_iter `INSERT in
  let cnum = pos#line_offset in
  let bol = b#get_iter (`LINE line) in
  let eol = bol#forward_to_line_end in

  let code =
    v#file#of_utf8
      (v#file#mode_from_display
       (b#get_text ~start: b#start_iter ~stop: eol ()))
  in
  let indentations =
    match Ed_ocaml_lexer.get_lines_indentation code with
      `Failure (e,(start,stop),l) ->
        let err = Printf.sprintf "chars %d-%d: %s"
            start stop (Ed_ocaml_lexer.report_error e) in
        Ed_misc.set_active_action_message (Ed_misc.to_utf8 err);
        l
    | `Success l ->
        l
  in
  if List.length indentations <= line then
    ()
  else
    match List.rev indentations with
      [] -> ()
    | None :: _ -> ()
    | (Some n) :: _ ->
        let codeline = v#file#of_utf8
          (b#get_text ~start: bol ~stop: eol ())
        in
        let len = String.length codeline in
        let new_codeline = remove_first_blanks codeline in
        let len2 = String.length new_codeline in
        let user_pos =
          let beg = len - len2 in
          if cnum < beg then 0 else cnum - beg
        in
        let new_codeline = Printf.sprintf "%s%s"
            (String.make n ' ')
            new_codeline
        in
        if new_codeline <> codeline then
          begin
            b#delete ~start: bol ~stop: eol;
            let pos = b#get_iter (`LINE line) in
            v#place_cursor pos;
            b#insert (v#file#mode_to_display (v#file#to_utf8 new_codeline));
            let pos = b#get_iter (`LINECHAR (line,n+user_pos)) in
            v#place_cursor pos
          end
        else
          ()