diff options
Diffstat (limited to 'src/nvim/ex_cmds2.c')
| -rw-r--r-- | src/nvim/ex_cmds2.c | 135 | 
1 files changed, 130 insertions, 5 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index df387f9a60..5fe6209a0a 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -144,6 +144,10 @@ void do_debug(char_u *cmd)  #define CMD_FINISH      4  #define CMD_QUIT        5  #define CMD_INTERRUPT   6 +#define CMD_BACKTRACE   7 +#define CMD_FRAME       8 +#define CMD_UP          9 +#define CMD_DOWN        10    ++RedrawingDisabled;          /* don't redisplay the window */ @@ -185,6 +189,7 @@ void do_debug(char_u *cmd)        ignore_script = TRUE;      } +    xfree(cmdline);      cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);      if (typeahead_saved) { @@ -194,6 +199,7 @@ void do_debug(char_u *cmd)      ex_normal_busy = save_ex_normal_busy;      cmdline_row = msg_row; +    msg_starthere();      if (cmdline != NULL) {        /* If this is a debug command, set "last_cmd".         * If not, reset "last_cmd". @@ -210,8 +216,15 @@ void do_debug(char_u *cmd)          case 's': last_cmd = CMD_STEP;            tail = "tep";            break; -        case 'f': last_cmd = CMD_FINISH; -          tail = "inish"; +        case 'f': +          last_cmd = 0; +          if (p[1] == 'r') { +            last_cmd = CMD_FRAME; +            tail = "rame"; +          } else { +            last_cmd = CMD_FINISH; +            tail = "inish"; +          }            break;          case 'q': last_cmd = CMD_QUIT;            tail = "uit"; @@ -219,6 +232,26 @@ void do_debug(char_u *cmd)          case 'i': last_cmd = CMD_INTERRUPT;            tail = "nterrupt";            break; +        case 'b': +          last_cmd = CMD_BACKTRACE; +          if (p[1] == 't') { +            tail = "t"; +          } else { +            tail = "acktrace"; +          } +          break; +        case 'w': +          last_cmd = CMD_BACKTRACE; +          tail = "here"; +          break; +        case 'u': +          last_cmd = CMD_UP; +          tail = "p"; +          break; +        case 'd': +          last_cmd = CMD_DOWN; +          tail = "own"; +          break;          default: last_cmd = 0;          }          if (last_cmd != 0) { @@ -228,8 +261,9 @@ void do_debug(char_u *cmd)              ++p;              ++tail;            } -          if (ASCII_ISALPHA(*p)) +          if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) {              last_cmd = 0; +          }          }        } @@ -259,7 +293,28 @@ void do_debug(char_u *cmd)            /* Do not repeat ">interrupt" cmd, continue stepping. */            last_cmd = CMD_STEP;            break; +        case CMD_BACKTRACE: +          do_showbacktrace(cmd); +          continue; +        case CMD_FRAME: +          if (*p == NUL) { +            do_showbacktrace(cmd); +          } else { +            p = skipwhite(p); +            do_setdebugtracelevel(p); +          } +          continue; +        case CMD_UP: +          debug_backtrace_level++; +          do_checkbacktracelevel(); +          continue; +        case CMD_DOWN: +          debug_backtrace_level--; +          do_checkbacktracelevel(); +          continue;          } +        // Going out reset backtrace_level +        debug_backtrace_level = 0;          break;        } @@ -269,8 +324,6 @@ void do_debug(char_u *cmd)        (void)do_cmdline(cmdline, getexline, NULL,            DOCMD_VERBOSE|DOCMD_EXCRESET);        debug_break_level = n; - -      xfree(cmdline);      }      lines_left = (int)(Rows - 1);    } @@ -294,6 +347,78 @@ void do_debug(char_u *cmd)    debug_did_msg = TRUE;  } +static int get_maxbacktrace_level(void) +{ +  int maxbacktrace = 0; + +  if (sourcing_name != NULL) { +    char *p = (char *)sourcing_name; +    char *q; +    while ((q = strstr(p, "..")) != NULL) { +      p = q + 2; +      maxbacktrace++; +    } +  } +  return maxbacktrace; +} + +static void do_setdebugtracelevel(char_u *arg) +{ +  int level = atoi((char *)arg); +  if (*arg == '+' || level < 0) { +    debug_backtrace_level += level; +  } else { +    debug_backtrace_level = level; +  } + +  do_checkbacktracelevel(); +} + +static void do_checkbacktracelevel(void) +{ +  if (debug_backtrace_level < 0) { +    debug_backtrace_level = 0; +    MSG(_("frame is zero")); +  } else { +    int max = get_maxbacktrace_level(); +    if (debug_backtrace_level > max) { +      debug_backtrace_level = max; +      smsg(_("frame at highest level: %d"), max); +    } +  } +} + +static void do_showbacktrace(char_u *cmd) +{ +  if (sourcing_name != NULL) { +    int i = 0; +    int max = get_maxbacktrace_level(); +    char *cur = (char *)sourcing_name; +    while (!got_int) { +      char *next = strstr(cur, ".."); +      if (next != NULL) { +        *next = NUL; +      } +      if (i == max - debug_backtrace_level) { +        smsg("->%d %s", max - i, cur); +      } else { +        smsg("  %d %s", max - i, cur); +      } +      i++; +      if (next == NULL) { +        break; +      } +      *next = '.'; +      cur = next + 2; +    } +  } +  if (sourcing_lnum != 0) { +    smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd); +  } else { +    smsg(_("cmd: %s"), cmd); +  } +} +  /*   * ":debug".   */  | 
