branch: elpa/caml
commit 744333dc4c4bd8b93e037efa8f7362b0903b96a2
Author: Stefan Monnier <[email protected]>
Commit: Stefan Monnier <[email protected]>
camldebug.el: Partially sync with Tuareg's `ocamldebug.el`
Use standard formatting for first and last lines.
Mention `ocamldebug` in the title since that's what we run by default.
Align license version with that of `caml.el`.
Add copyright for my contributions.
Group historical info together.
Add new commands for `open` and `close`.
(camldebug-overlay-event, camldebug-overlay-under): Improve docstring
and disconnect from the current buffer.
(camldebug-event, camldebug-underline): Add docstring.
(camldebug-prefix-map): New map.
(def-camldebug): Add entries to it.
(caml-mode-map): Add it under the `C-x C-a` prefix here, so
`def-camldebug` doesn't need to touch `caml-mode-map` any more.
(camldebug-mode-map): Define it explicitly.
(comint-input-sentinel): Delete, this was an XEmacs-ism.
(camldebug-mode): Use `setq-local`.
Hook into `comint-input-filter-functions` rather than
`comint-input-sentinel`.
(current-camldebug-buffer): Rename to `camldebug-current-buffer` to
obey the prefix naming convention.
(camldebug-goto-filter): Use `when`.
(camldebug-goto): Use `unless`.
(camldebug-capf): Simplify a bit.
(camldebug--get-completions): Rename arg `command-word` to `str`.
(camldebug-command-name): Don't autoload.
(camldebug-marker-filter): Use `unless`.
(camldebug-filter): Prefer `let` over `setq`. Use `when`.
(camldebug-display-line): Use `filepos-to-bufferpos` when available.
(camldebug-set-current-event): Use `1-`.
(camldebug-module-name): Prefer \' to match end of string.
(camldebug-format-command): Prefer `let` over `setq`.
Use `bufferpos-to-filepos` when available.
(camldebug-call-1): Use `save-excursion` to avoid "point jumping in
ocamldebug completion".
(camldebug-event): Use `:invert-video` to avoid compiler warning.
---
camldebug.el | 375 ++++++++++++++++++++++++++++++-----------------------------
1 file changed, 191 insertions(+), 184 deletions(-)
diff --git a/camldebug.el b/camldebug.el
index 3cf8fd61ac..c0ac4c5c43 100644
--- a/camldebug.el
+++ b/camldebug.el
@@ -1,29 +1,25 @@
-;****************************************** -*- lexical-binding: t; -*- ***
-;* *
-;* OCaml *
-;* *
-;* Jacques Garrigue and Ian T Zimmerman *
-;* *
-;* Copyright 1997 Institut National de Recherche en Informatique et *
-;* en Automatique. *
-;* *
-;* All rights reserved. This file is distributed under the terms of *
-;* the GNU General Public License. *
-;* *
-;**************************************************************************
-
-;; Run camldebug under Emacs
-;; Derived from gdb.el.
-;; gdb.el is Copyright (C) 1988 Free Software Foundation, Inc, and is part
-;; of GNU Emacs
-;; Modified by Jerome Vouillon, 1994.
-;; Modified by Ian T. Zimmerman, 1996.
-;; Modified by Xavier Leroy, 1997.
+;;; camldebug.el --- Run ocamldebug / camldebug under Emacs -*-
lexical-binding:t -*-
+
+;;**************************************************************************
+;;* *
+;;* OCaml *
+;;* *
+;;* Jacques Garrigue and Ian T Zimmerman *
+;;* *
+;;* Copyright 1997 Institut National de Recherche en Informatique et *
+;;* en Automatique. *
+;;* *
+;;* All rights reserved. This file is distributed under the terms of *
+;;* the GNU General Public License. *
+;;* *
+;;**************************************************************************
+
+;; Copyright (C) 2021-2025 Free Software Foundation, Inc.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 1, or (at your option)
-;; any later version.
+;; the Free Software Foundation; either version 3 of the License, or
+;; (at your option) any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -40,8 +36,17 @@
;;assume that a sane person doesn't use gdb and dbx at the same time,
;;it's not so OK (IMHO) for gdb and camldebug.
+;; Derived from gdb.el.
+;; gdb.el is Copyright (C) 1988 Free Software Foundation, Inc, and is part
+;; of GNU Emacs
+;; Modified by Jerome Vouillon, 1994.
+;; Modified by Ian T. Zimmerman, 1996.
+;; Modified by Xavier Leroy, 1997.
+
;; Xavier Leroy, 21/02/97: adaptation to ocamldebug.
+;;; Code:
+
(require 'comint)
(require 'shell)
(require 'caml)
@@ -60,15 +65,17 @@
"A regexp to recognize the prompt for ocamldebug.")
(defvar camldebug-overlay-event
- (let ((ol (make-overlay (point-min) (point-min))))
+ (let ((ol (make-overlay (point) (point))))
(overlay-put ol 'face 'camldebug-event)
+ (delete-overlay ol) ;; Disconnect it from current buffer.
ol)
- "Overlay for displaying the current event.")
+ "Overlay for displaying the first/last char of current event.")
(defvar camldebug-overlay-under
- (let ((ol (make-overlay (point-min) (point-min))))
+ (let ((ol (make-overlay (point) (point))))
(overlay-put ol 'face 'camldebug-underline)
+ (delete-overlay ol) ;; Disconnect it from current buffer.
ol)
- "Overlay for displaying the current event.")
+ "Overlay for displaying the rest of current event.")
(defvar camldebug-event-marker (make-marker)
"Marker for displaying the current event.")
@@ -76,31 +83,47 @@
"*If non-nil, always display current frame position in another window.")
(defface camldebug-event
- '((t :invert t))
- "?FIXME?")
+ '((t :inverse-video t))
+ "Face to highlight the first/last char of current event.")
(defface camldebug-underline
+ ;; FIXME: The name should describe what it's used for, not what it looks
+ ;; like by default!
'((t :underline t))
- "?FIXME?")
+ "Face to highlight the rest of current event.")
;;; Camldebug mode.
-(defvar comint-input-sentinel)
+(defvar camldebug-prefix-map (make-sparse-keymap)
+ "Keymap bound to prefix keys in `camldebug-mode' and `caml-mode'.")
+
+(define-key caml-mode-map "\C-x\C-a" camldebug-prefix-map)
+
+(defvar camldebug-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-c" camldebug-prefix-map)
+ (define-key map "\C-l" #'camldebug-refresh)
+ ;; This is already the default anyway!
+ ;;(define-key map "\t" #'comint-dynamic-complete)
+ ;; FIXME: This binding is wrong since `comint-dynamic-list-completions'
+ ;; is a function, not a command.
+ ;;(define-key camldebug-mode-map "\M-?" #'comint-dynamic-list-completions)
+ map))
(define-derived-mode camldebug-mode comint-mode "Inferior CDB"
- "Major mode for interacting with an inferior ocamldebug process.
+ "Major mode for interacting with an ocamldebug process.
The following commands are available:
-\\{camldebug-mode-map}
+\\<camldebug-mode-map>\\{camldebug-mode-map}
\\[camldebug-display-frame] displays in the other window
the last line referred to in the camldebug buffer.
-\\[camldebug-step], \\[camldebug-back] and \\[camldebug-next], in the camldebug
-window, call camldebug to step, backstep or next and then update the other
-window with the current file and position.
+\\[camldebug-step], \\[camldebug-back] and \\[camldebug-next], in the
camldebug window,
+call camldebug to step, backstep or next and then update the other window
+with the current file and position.
If you are in a source file, you may select a point to break
at, by doing \\[camldebug-break].
@@ -112,23 +135,16 @@ Additionally we have:
\\[camldebug-display-frame] display frames file in other window
\\[camldebug-step] advance one line in program
C-x SPACE sets break point at current line."
-
- (mapc #'make-local-variable
- '(camldebug-last-frame-displayed-p camldebug-last-frame
- camldebug-delete-prompt-marker camldebug-filter-function
- camldebug-filter-accumulator paragraph-start))
- (setq
- camldebug-last-frame nil
- camldebug-delete-prompt-marker (make-marker)
- camldebug-filter-accumulator ""
- camldebug-filter-function #'camldebug-marker-filter
- comint-prompt-regexp camldebug-prompt-pattern
- paragraph-start comint-prompt-regexp
- camldebug-last-frame-displayed-p t)
- (add-hook 'comint-dynamic-complete-functions #'camldebug-capf nil t)
- (make-local-variable 'shell-dirtrackp)
- (setq shell-dirtrackp t)
- (setq comint-input-sentinel #'shell-directory-tracker))
+ (setq-local camldebug-last-frame nil)
+ (setq-local camldebug-delete-prompt-marker (make-marker))
+ (setq-local camldebug-filter-accumulator "")
+ (setq-local camldebug-filter-function #'camldebug-marker-filter)
+ (setq-local comint-prompt-regexp camldebug-prompt-pattern)
+ (setq-local paragraph-start comint-prompt-regexp)
+ (setq-local camldebug-last-frame-displayed-p t)
+ (add-hook 'comint-dynamic-complete-functions #'camldebug-capf nil 'local)
+ (setq-local shell-dirtrackp t)
+ (add-hook 'comint-input-filter-functions #'shell-directory-tracker nil t))
;;; Keymaps.
@@ -144,10 +160,10 @@ interpreted specially if present. These are:
%m module name of current module.
%d directory of current source file.
%c number of current character position
- %e text of the caml variable surrounding point.
+ %e text of the Caml variable surrounding point.
The `current' source file is the file of the current buffer (if
-we're in a caml buffer) or the source file current at the last break
+we're in a Caml buffer) or the source file current at the last break
or step (if we're in the camldebug buffer), and the `current' module
name is the filename stripped of any *.ml* suffixes (this assumes the
usual correspondence between module and file naming is observed). The
@@ -166,8 +182,7 @@ representation is simply concatenated with the COMMAND."
(interactive "P")
(camldebug-call ,name ,args
(camldebug-numeric-arg arg))))
- (define-key camldebug-mode-map ,(concat "\C-c" key) #',fun)
- (define-key caml-mode-map ,(concat "\C-x\C-a" key) #',fun))))
+ (define-key camldebug-prefix-map ,key #',fun))))
(def-camldebug "step" "\C-s" "Step one event forward.")
(def-camldebug "backstep" "\C-k" "Step one event backward.")
@@ -175,6 +190,8 @@ representation is simply concatenated with the COMMAND."
(def-camldebug "reverse" "\C-v" "Run the program in reverse.")
(def-camldebug "last" "\C-l" "Go to latest time in execution history.")
(def-camldebug "backtrace" "\C-t" "Print the call stack.")
+(def-camldebug "open" "\C-o" "Open the current module." "%m")
+(def-camldebug "close" "\C-c" "Close the current module." "%m")
(def-camldebug "finish" "\C-f" "Finish executing current function.")
(def-camldebug "print" "\C-p" "Print value of symbol at point." "%e")
(def-camldebug "display" "\C-d" "Display value of symbol at point." "%e")
@@ -203,7 +220,7 @@ representation is simply concatenated with the COMMAND."
(defvar camldebug-kill-output)
(defun camldebug-kill-filter (string)
- ;gob up stupid questions :-)
+ ;; Gob up stupid questions :-)
(setq camldebug-filter-accumulator
(concat camldebug-filter-accumulator string))
(when (string-match "\\(.* \\)(y or n) " camldebug-filter-accumulator)
@@ -222,7 +239,7 @@ representation is simply concatenated with the COMMAND."
(def-camldebug "kill" "\C-k")
-(defvar current-camldebug-buffer nil)
+(defvar camldebug-current-buffer nil)
(defvar camldebug-goto-output)
(defvar camldebug-goto-position)
@@ -230,7 +247,7 @@ representation is simply concatenated with the COMMAND."
"Kill the program."
(interactive)
(let ((camldebug-kill-output))
- (with-current-buffer current-camldebug-buffer
+ (with-current-buffer camldebug-current-buffer
(let ((proc (get-buffer-process (current-buffer)))
(camldebug-filter-function #'camldebug-kill-filter))
(camldebug-call "kill")
@@ -244,7 +261,7 @@ representation is simply concatenated with the COMMAND."
;;FIXME: camldebug doesn't output the Hide marker on kill
(defun camldebug-goto-filter (string)
- ;accumulate onto previous output
+ ;; Accumulate onto previous output
(setq camldebug-filter-accumulator
(concat camldebug-filter-accumulator string))
;; Address Characters Kind Repr.
@@ -272,31 +289,29 @@ representation is simply concatenated with the COMMAND."
(when (string-match comint-prompt-regexp camldebug-filter-accumulator)
(setq camldebug-goto-output (or camldebug-goto-output 'fail))
(setq camldebug-filter-accumulator ""))
- (if (string-match "\n\\(.*\\)\\'" camldebug-filter-accumulator)
- (setq camldebug-filter-accumulator
- (match-string 1 camldebug-filter-accumulator)))
+ (when (string-match "\n\\(.*\\)\\'" camldebug-filter-accumulator)
+ (setq camldebug-filter-accumulator
+ (match-string 1 camldebug-filter-accumulator)))
"")
(def-camldebug "goto" "\C-g")
(defun camldebug-goto (&optional time)
-
"Go to the execution time TIME.
Without TIME, the command behaves as follows: In the camldebug buffer,
-if the point at buffer end, goto time 0\; otherwise, try to obtain the
-time from context around point. In a caml mode buffer, try to find the
+if the point at buffer end, goto time 0; otherwise, try to obtain the
+time from context around point. In a Caml mode buffer, try to find the
time associated in execution history with the current point location.
With a negative TIME, move that many lines backward in the camldebug
buffer, then try to obtain the time from context around point."
-
(interactive "P")
(cond
(time
(let ((ntime (camldebug-numeric-arg time)))
(if (>= ntime 0) (camldebug-call "goto" nil ntime)
(save-selected-window
- (select-window (get-buffer-window current-camldebug-buffer))
+ (select-window (get-buffer-window camldebug-current-buffer))
(save-excursion
(if (re-search-backward
"^Time *: [0-9]+ - pc *: [0-9]+\\(?::[0-9]+\\)? "
@@ -304,7 +319,7 @@ buffer, then try to obtain the time from context around
point."
(camldebug-goto nil)
(error "I don't have %d times in my history"
(- 1 ntime))))))))
- ((eq (current-buffer) current-camldebug-buffer)
+ ((eq (current-buffer) camldebug-current-buffer)
(let ((time (cond
((eobp) 0)
((save-excursion
@@ -318,15 +333,15 @@ buffer, then try to obtain the time from context around
point."
(let ((module (camldebug-module-name (buffer-file-name)))
(camldebug-goto-position (int-to-string (1- (point))))
(camldebug-goto-output) (address))
- ;get a list of all events in the current module
- (with-current-buffer current-camldebug-buffer
+ ;; Get a list of all events in the current module
+ (with-current-buffer camldebug-current-buffer
(let* ((proc (get-buffer-process (current-buffer)))
(camldebug-filter-function #'camldebug-goto-filter))
(camldebug-call-1 (concat "info events " module))
(while (not (and camldebug-goto-output
(zerop (length camldebug-filter-accumulator))))
(accept-process-output proc))
- (setq address (if (eq camldebug-goto-output 'fail) nil
+ (setq address (unless (eq camldebug-goto-output 'fail)
(re-search-backward
(concat "^Time *: \\([0-9]+\\) - pc *: "
camldebug-goto-output
@@ -373,27 +388,25 @@ buffer, then try to obtain the time from context around
point."
"Delete the breakpoint numbered ARG.
Without ARG, the command behaves as follows: In the camldebug buffer,
-try to obtain the time from context around point. In a caml mode
-buffer, try to find the breakpoint associated with the current point
-location.
+try to obtain the time from context around point. In a Caml buffer,
+try to find the breakpoint associated with the current point location.
With a negative ARG, look for the -ARGth breakpoint pattern in the
camldebug buffer, then try to obtain the breakpoint info from context
around point."
-
(interactive "P")
(cond
(arg
(let ((narg (camldebug-numeric-arg arg)))
(if (> narg 0) (camldebug-call "delete" nil narg)
- (with-current-buffer current-camldebug-buffer
+ (with-current-buffer camldebug-current-buffer
(if (re-search-backward
"^Breakpoint [0-9]+ at [0-9]+\\(?::[0-9]+\\)? *: file "
nil t (- 1 narg))
(camldebug-delete nil)
(error "I don't have %d breakpoints in my history"
(- 1 narg)))))))
- ((eq (current-buffer) current-camldebug-buffer)
+ ((eq (current-buffer) camldebug-current-buffer)
(let* ((bpline
"^Breakpoint \\([0-9]+\\) at [0-9]+\\(?::[0-9]+\\)? *: file ")
(arg (cond
@@ -410,7 +423,7 @@ around point."
(let ((camldebug-delete-file
(concat (camldebug-format-command "%m") ".ml"))
(camldebug-delete-position (camldebug-format-command "%c")))
- (with-current-buffer current-camldebug-buffer
+ (with-current-buffer camldebug-current-buffer
(let ((proc (get-buffer-process (current-buffer)))
(camldebug-filter-function #'camldebug-delete-filter)
(camldebug-delete-output))
@@ -458,38 +471,35 @@ around point."
#'string-lessp))))
(defun camldebug-capf ()
+ ;; FIXME: Use an `end' after point when applicable.
(let* ((end (point))
(cmd-start (save-excursion
- (beginning-of-line)
- (and (looking-at comint-prompt-regexp)
- (goto-char (match-end 0)))
- (point)))
- (command (buffer-substring cmd-start end))
- ;; Find the word break. This match will always succeed.
- (_ (string-match "\\(\\`\\| \\)\\([^ ]*\\)\\'" command))
- (command-word (match-string 2 command))
- (word-end end)
- (word-beg (- word-end (length command-word))))
-
- `(,word-beg ,word-end
- ,(completion-table-dynamic
- (apply-partially
- #'camldebug--get-completions
- (buffer-substring cmd-start word-beg))))))
-
-(defun camldebug--get-completions (command-prefix command-word)
+ (beginning-of-line)
+ (if (looking-at comint-prompt-regexp)
+ (match-end 0) (point))))
+ (start (save-excursion
+ (skip-chars-backward "^ \n" cmd-start)
+ (point))))
+
+ `(,start ,end
+ ,(completion-table-dynamic
+ (apply-partially #'camldebug--get-completions
+ (buffer-substring cmd-start start))))))
+
+(defun camldebug--get-completions (command-prefix str)
+ ;; FIXME: Add some caching?
(let ((camldebug-complete-list nil))
- ;;itz 04-21-96 if we are trying to complete a word of nonzero
- ;;length, chop off the last character. This is a nasty hack, but it
- ;;works - in general, not just for this set of words: the comint
- ;;call below will weed out false matches - and it avoids further
- ;;mucking with camldebug's lexer.
+ ;; itz 04-21-96 If we are trying to complete a word of nonzero
+ ;; length, chop off the last character. This is a nasty hack, but it
+ ;; works - in general, not just for this set of words: the completion
+ ;; code will weed out false matches - and it avoids further
+ ;; mucking with camldebug's lexer.
;; FIXME: Which problem is this trying to fix/avoid/circumvent?
- (when (> (length command-word) 0)
- (setq command-word (substring command-word 0 (1- (length
command-word)))))
+ (when (> (length str) 0)
+ (setq str (substring str 0 (1- (length str)))))
(let ((camldebug-filter-function #'camldebug-complete-filter))
- (camldebug-call-1 (concat "complete " command-prefix command-word))
+ (camldebug-call-1 (concat "complete " command-prefix str))
(set-marker camldebug-delete-prompt-marker nil)
(while (not (and camldebug-complete-list
(zerop (length camldebug-filter-accumulator))))
@@ -499,17 +509,8 @@ around point."
nil
(sort camldebug-complete-list #'string-lessp))))
-(define-key camldebug-mode-map "\C-l" #'camldebug-refresh)
-;; This is already the default anyway!
-;;(define-key camldebug-mode-map "\t" #'comint-dynamic-complete)
-;; FIXME: This binding is wrong since `comint-dynamic-list-completions'
-;; is a function, not a command.
-;;(define-key camldebug-mode-map "\M-?" #'comint-dynamic-list-completions)
-
(define-key caml-mode-map "\C-x " #'camldebug-break)
-
-;;;###autoload
(defvar camldebug-command-name "ocamldebug"
"*Pathname for executing camldebug.")
@@ -540,8 +541,8 @@ the camldebug commands `cd DIR' and `directory'."
(defun camldebug-set-buffer ()
(if (eq major-mode 'camldebug-mode)
- (setq current-camldebug-buffer (current-buffer))
- (save-selected-window (pop-to-buffer current-camldebug-buffer))))
+ (setq camldebug-current-buffer (current-buffer))
+ (save-selected-window (pop-to-buffer camldebug-current-buffer))))
;;; Filter and sentinel.
@@ -555,9 +556,8 @@ the camldebug commands `cd DIR' and `directory'."
"\032\032\\(H\\|M\\(.+\\):\\(.+\\):\\(.+\\):\\(before\\|after\\)\\)\n"
camldebug-filter-accumulator))
(setq camldebug-last-frame
- (if (char-equal ?H (aref camldebug-filter-accumulator
- (1+ (1+ begin))))
- nil
+ (unless (char-equal ?H (aref camldebug-filter-accumulator
+ (1+ (1+ begin))))
(let ((isbefore
(string= "before"
(match-string 5 camldebug-filter-accumulator)))
@@ -580,7 +580,6 @@ the camldebug commands `cd DIR' and `directory'."
(match-end 0))
camldebug-last-frame-displayed-p nil))
-
;; Does the remaining text look like it might end with the
;; beginning of another marker? If it does, then keep it in
;; camldebug-filter-accumulator until we receive the rest of it. Since we
@@ -602,37 +601,35 @@ the camldebug commands `cd DIR' and `directory'."
output))
(defun camldebug-filter (proc string)
- (let ((output))
- (if (buffer-name (process-buffer proc))
- (let ((process-window))
- ;; it does not seem necessary to save excursion here,
- ;; since set-buffer as a temporary effect.
- ;; comint-output-filter explicitly avoids it.
- ;; in version 23, it prevents the marker to stay at end of buffer
- (with-current-buffer (process-buffer proc)
- ;; If we have been so requested, delete the debugger prompt.
- (if (marker-buffer camldebug-delete-prompt-marker)
- (progn
- (delete-region (process-mark proc)
- camldebug-delete-prompt-marker)
- (set-marker camldebug-delete-prompt-marker nil)))
- (setq output (funcall camldebug-filter-function string))
- ;; Don't display the specified file unless
- ;; (1) point is at or after the position where output appears
- ;; and (2) this buffer is on the screen.
- (setq process-window (and camldebug-track-frame
- (not camldebug-last-frame-displayed-p)
- (>= (point) (process-mark proc))
- (get-buffer-window (current-buffer))))
- ;; Insert the text, moving the process-marker.
- (comint-output-filter proc output))
- ;; if save-excursion is used (comint-next-prompt 1) would be needed
- ;; to move the mark past then next prompt, but this is not as good
- ;; as solution.
- (if process-window
- (save-selected-window
- (select-window process-window)
- (camldebug-display-frame)))))))
+ (when (buffer-name (process-buffer proc))
+ (let ((process-window))
+ ;; it does not seem necessary to save excursion here,
+ ;; since set-buffer as a temporary effect.
+ ;; comint-output-filter explicitly avoids it.
+ ;; in version 23, it prevents the marker to stay at end of buffer
+ (with-current-buffer (process-buffer proc)
+ ;; If we have been so requested, delete the debugger prompt.
+ (when (marker-buffer camldebug-delete-prompt-marker)
+ (delete-region (process-mark proc)
+ camldebug-delete-prompt-marker)
+ (set-marker camldebug-delete-prompt-marker nil))
+ (let ((output (funcall camldebug-filter-function string)))
+ ;; Don't display the specified file unless
+ ;; (1) point is at or after the position where output appears
+ ;; and (2) this buffer is on the screen.
+ (setq process-window (and camldebug-track-frame
+ (not camldebug-last-frame-displayed-p)
+ (>= (point) (process-mark proc))
+ (get-buffer-window (current-buffer))))
+ ;; Insert the text, moving the process-marker.
+ (comint-output-filter proc output)))
+ ;; if save-excursion is used (comint-next-prompt 1) would be needed
+ ;; to move the mark past then next prompt, but this is not as good
+ ;; as solution.
+ (when process-window
+ (save-selected-window
+ (select-window process-window)
+ (camldebug-display-frame))))))
(defun camldebug-sentinel (proc msg)
(cond ((null (buffer-name (process-buffer proc)))
@@ -694,7 +691,7 @@ Obeying it means displaying in another window the specified
file and line."
;; and that its character CHARACTER is visible.
;; Put the mark on this character in that buffer.
-(defvar pre-display-buffer-function)
+(defvar pre-display-buffer-function) ;XEmacs variable.
(defun camldebug-display-line (true-file schar echar kind)
(let* ((pre-display-buffer-function nil) ; screw it, put it all in one screen
@@ -705,8 +702,12 @@ Obeying it means displaying in another window the
specified file and line."
(with-current-buffer buffer
(save-restriction
(widen)
- (setq spos (+ (point-min) schar))
- (setq epos (+ (point-min) echar))
+ (setq spos (if (fboundp 'filepos-to-bufferpos) ;Emacs-25
+ (filepos-to-bufferpos schar 'approximate)
+ (+ (point-min) schar)))
+ (setq epos (if (fboundp 'filepos-to-bufferpos)
+ (filepos-to-bufferpos echar 'approximate)
+ (+ (point-min) echar)))
(setq pos (if kind spos epos))
(camldebug-set-current-event spos epos (current-buffer) kind))
(cond ((or (< pos (point-min)) (> pos (point-max)))
@@ -729,7 +730,7 @@ Obeying it means displaying in another window the specified
file and line."
(move-overlay camldebug-overlay-under
(+ spos 1) epos buffer))
(move-overlay camldebug-overlay-event (1- epos) epos buffer)
- (move-overlay camldebug-overlay-under spos (- epos 1) buffer))
+ (move-overlay camldebug-overlay-under spos (1- epos) buffer))
(with-current-buffer buffer
(goto-char spos)
(beginning-of-line)
@@ -739,7 +740,7 @@ Obeying it means displaying in another window the specified
file and line."
;;; Miscellaneous.
(defun camldebug-module-name (filename)
- (substring filename (string-match "\\([^/]*\\)\\.ml$" filename)
+ (substring filename (string-match "\\([^/]*\\)\\.ml\\'" filename)
(match-end 1)))
;; The camldebug-call function must do the right thing whether its
@@ -748,25 +749,31 @@ Obeying it means displaying in another window the
specified file and line."
;; to supply data from camldebug-last-frame. Here's how we do it:
(defun camldebug-format-command (str)
- (let* ((insource (not (eq (current-buffer) current-camldebug-buffer)))
- (frame (if insource nil camldebug-last-frame)) (result))
+ (let* ((insource (not (eq (current-buffer) camldebug-current-buffer)))
+ (frame (if insource nil camldebug-last-frame))
+ (result ""))
(while (and str (string-match "\\([^%]*\\)%\\([mdcep]\\)" str))
- (let ((key (string-to-char (substring str (match-beginning 2))))
- (cmd (substring str (match-beginning 1) (match-end 1)))
- (subst))
- (setq str (substring str (match-end 2)))
- (cond
- ((eq key ?m)
- (setq subst (camldebug-module-name
- (if insource (buffer-file-name) (nth 0 frame)))))
- ((eq key ?d)
- (setq subst (file-name-directory
- (if insource (buffer-file-name) (nth 0 frame)))))
- ((eq key ?c)
- (setq subst (int-to-string
- (if insource (1- (point)) (nth 1 frame)))))
- ((eq key ?e)
- (setq subst (thing-at-point 'symbol))))
+ (let* ((key (aref str (match-beginning 2)))
+ (cmd (match-string 1 str))
+ (end (match-end 0))
+ (subst
+ (cond
+ ((eq key ?m)
+ (camldebug-module-name
+ (if insource buffer-file-name (nth 0 frame))))
+ ((eq key ?d)
+ (file-name-directory
+ (if insource buffer-file-name (nth 0 frame))))
+ ((eq key ?c)
+ (int-to-string
+ (if insource
+ (if (fboundp 'bufferpos-to-filepos)
+ (bufferpos-to-filepos (point))
+ (1- (point)))
+ (nth 1 frame))))
+ ((eq key ?e)
+ (thing-at-point 'symbol)))))
+ (setq str (substring str end))
(setq result (concat result cmd subst))))
;; There might be text left in STR when the loop ends.
(concat result str)))
@@ -780,10 +787,10 @@ These are:
%m module name of current module.
%d directory of current source file.
%c number of current character position
- %e text of the caml variable surrounding point.
+ %e text of the Caml variable surrounding point.
The `current' source file is the file of the current buffer (if
-we're in a caml buffer) or the source file current at the last break
+we're in a Caml buffer) or the source file current at the last break
or step (if we're in the camldebug buffer), and the `current' module
name is the filename stripped of any *.ml* suffixes (this assumes the
usual correspondence between module and file naming is observed). The
@@ -799,22 +806,22 @@ representation is simply concatenated with the COMMAND."
(message "Command: %s" (camldebug-call-1 command fmt arg)))
(defun camldebug-call-1 (command &optional fmt arg)
-
;; Record info on the last prompt in the buffer and its position.
- (with-current-buffer current-camldebug-buffer
- (goto-char (process-mark (get-buffer-process current-camldebug-buffer)))
- (let () ;;(pt (point))
+ (with-current-buffer camldebug-current-buffer
+ (save-excursion
+ (goto-char (process-mark (get-buffer-process camldebug-current-buffer)))
(beginning-of-line)
- (if (looking-at comint-prompt-regexp)
- (set-marker camldebug-delete-prompt-marker (point)))))
+ (when (looking-at comint-prompt-regexp)
+ (set-marker camldebug-delete-prompt-marker (point)))))
(let ((cmd (cond
(arg (concat command " " (int-to-string arg)))
(fmt (camldebug-format-command
(concat command " " fmt)))
(command))))
- (process-send-string (get-buffer-process current-camldebug-buffer)
+ (process-send-string (get-buffer-process camldebug-current-buffer)
(concat cmd "\n"))
cmd))
(provide 'camldebug)
+;;; camldebug.el ends here