[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/sweeprolog f5a395ce42: ADDED: right-click context menus in
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/sweeprolog f5a395ce42: ADDED: right-click context menus in sweeprolog-mode |
Date: |
Thu, 19 Jan 2023 04:59:55 -0500 (EST) |
branch: elpa/sweeprolog
commit f5a395ce42c8212e44049d8942940ed5ac8aee70
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>
ADDED: right-click context menus in sweeprolog-mode
* sweeprolog.el (sweeprolog-context-menu-find-module)
(sweeprolog-context-menu-find-module-other-window)
(sweeprolog-context-menu-describe-module)
(sweeprolog-context-menu-find-file)
(sweeprolog-context-menu-find-file-other-window)
(sweeprolog-context-menu-describe-predicate): new commands, add to context
menus by...
(sweeprolog-context-menu-for-predicate)
(sweeprolog-context-menu-for-module)
(sweeprolog-context-menu-for-file): new functions, used in...
(sweeprolog-context-menu-functions): new abnormal hook, used by...
(sweeprolog-context-menu-function): new function.
(sweeprolog-mode): add it to context-menu-functions.
* README.org (Context Menu): new section.
---
README.org | 52 +++++++++++++++++----
sweeprolog.el | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 182 insertions(+), 18 deletions(-)
diff --git a/README.org b/README.org
index b232e76839..2d5ebe7528 100644
--- a/README.org
+++ b/README.org
@@ -1547,6 +1547,48 @@ match. Likewise, typing ~C-r~ after a successful term
search invokes
the command ~sweeprolog-term-search-repeat-backward~ which moves
backward to the previous match.
+** Context Menu
+:PROPERTIES:
+:CUSTOM_ID: context-menu
+:DESCRIPTION: Right-click on Prolog code to open contextual menus
+:ALT_TITLE: Context Menu
+:END:
+
+#+CINDEX: context menu
+#+CINDEX: right click menu
+In addition to the keybindings that Sweep provides for invoking its
+commands, it integrates with Emacs's standard Context Menu minor mode
+to provide contextual menus that you operate with the mouse.
+
+- Command: context-menu-mode :: Toggle Context Menu mode. When
+ enabled, clicking the mouse button ~down-mouse-3~ (i.e. right-click)
+ activates a menu whose contents depends on its surrounding context.
+- Variable: sweeprolog-context-menu-functions :: List of functions
+ that create Context Menu entries for Prolog tokens. Each function
+ should receive as its arguments the menu that is being created, the
+ Prolog token's description, its start position, its end position,
+ and the position of the mouse click. It should alter the menu
+ according to that context.
+
+To enable Context Menu, type ~M-x context-menu-mode~ or add a call to
+~(context-menu-mode)~ in your Emacs initialization file to enable it in
+all future sessions. You access the context menu by right-clicking
+anywhere in Emacs. If you do it in a ~sweeprolog-mode~ buffer, you can
+invoke several Prolog-specific commands based on where you click in
+the buffer.
+
+If you right-click on a Prolog file specification or module name,
+Sweep suggests visiting it either in the current window or in another.
+If you right-click on a predicate, it lets you view its documentation
+in dedicated buffer.
+
+You can further extend and customize the context menu that
+~sweeprolog-mode~ provides by adding functions to the variable
+~sweeprolog-context-menu-functions~. Each function on this list
+receives the menu that is being created and a description of the
+clicked Prolog token, and it can extend the menu with entries before
+it's displayed.
+
* Prolog Help
:PROPERTIES:
:CUSTOM_ID: prolog-help
@@ -2088,16 +2130,6 @@ there some further improvements that we want to pursue:
has been loaded into the Prolog runtime and/or if its
cross-reference data is up to date.
-- Provide right-click (~mouse-3~) menus with ~context-menu-mode~ :: To
- accommodate users who prefer a mouse-based workflow, ~sweeprolog-mode~
- should provide context-aware right-click menus by integrating with
- ~context-menu-mode~.
-
-- Provide descriptions for tokens by setting their ~help-echo~ propety :: We
- should annotate tokens in Prolog code with a short text in their
- ~help-echo~ property that says what kind of token this is, to expose
- the precise semantics of each token to the user.
-
- Make predicate completion aware of module-qualification :: predicate
completion should detect when the prefix it's trying to complete
starts with a module-qualification ~foo:ba<|>~ and restrict completion
diff --git a/sweeprolog.el b/sweeprolog.el
index 654b2d4ef4..b4d99d730e 100644
--- a/sweeprolog.el
+++ b/sweeprolog.el
@@ -1028,10 +1028,18 @@ module name, F is a functor name and N is its arity."
'sweeprolog-read-module-history)))
;;;###autoload
-(defun sweeprolog-find-module (mod)
- "Jump to the source file of the Prolog module MOD."
+(defun sweeprolog-find-module (mod &optional other-window)
+ "Jump to the source file of the Prolog module MOD.
+
+If OTHER-WINDOW is non-nil, find it in another window.
+
+Interactively, OTHER-WINDOW is the prefix argument and this
+command prompts for MOD."
(interactive (list (sweeprolog-read-module-name)))
- (find-file (sweeprolog-module-path mod)))
+ (let ((file (sweeprolog-module-path mod)))
+ (if other-window
+ (find-file-other-window file)
+ (find-file file))))
;;;; Completion at point
@@ -2929,13 +2937,18 @@ buffer to load."
(setq fap file))))))
fap))
-(defun sweeprolog-find-file-at-point (point)
+(defun sweeprolog-find-file-at-point (point &optional other-window)
"Find file specified by the Prolog file spec at POINT.
-Interactively, POINT is set to the current point."
- (interactive "d" sweeprolog-mode)
+If OTHER-WINDOW is non-nil, find it in another window.
+
+Interactively, POINT is set to the current point and OTHER-WINDOW
+is the prefix argument."
+ (interactive "d\nP" sweeprolog-mode)
(if-let ((file (sweeprolog-file-at-point point)))
- (find-file file)
+ (if other-window
+ (find-file-other-window file)
+ (find-file file))
(user-error "No file specification found at point!")))
@@ -4232,7 +4245,10 @@ certain contexts to maintain conventional Prolog layout."
(when sweeprolog-enable-cursor-sensor
(add-hook 'sweeprolog-analyze-region-fragment-hook
#'sweeprolog-analyze-fragment-variable nil t)
- (cursor-sensor-mode 1)))
+ (cursor-sensor-mode 1))
+ (when (boundp 'context-menu-functions)
+ (add-hook 'context-menu-functions
+ #'sweeprolog-context-menu-function)))
;;;; Skeletons and auto-insert
@@ -5205,6 +5221,122 @@ GOAL."
"\\[sweeprolog-term-search-repeat-backward] for previous match."))))))
+;;;; Right-Click Context Menu
+
+(defvar sweeprolog-context-menu-file-at-click nil
+ "Prolog file specification at mouse click.")
+
+(defvar sweeprolog-context-menu-module-at-click nil
+ "Prolog module name at mouse click.")
+
+(defvar sweeprolog-context-menu-predicate-at-click nil
+ "Prolog predicate indicator at mouse click.")
+
+(defun sweeprolog-context-menu-find-module ()
+ "Find Prolog module at mouse click."
+ (interactive)
+ (sweeprolog-find-module sweeprolog-context-menu-module-at-click))
+
+(defun sweeprolog-context-menu-find-module-other-window ()
+ "Find Prolog module at mouse click in another window."
+ (interactive)
+ (sweeprolog-find-module sweeprolog-context-menu-module-at-click t))
+
+(defun sweeprolog-context-menu-describe-module ()
+ "Describe Prolog module at mouse click."
+ (interactive)
+ (sweeprolog-describe-module sweeprolog-context-menu-module-at-click))
+
+(defun sweeprolog-context-menu-find-file ()
+ "Find Prolog file at mouse click."
+ (interactive)
+ (find-file sweeprolog-context-menu-file-at-click))
+
+(defun sweeprolog-context-menu-find-file-other-window ()
+ "Find Prolog file at mouse click in another window."
+ (interactive)
+ (find-file-other-window sweeprolog-context-menu-file-at-click))
+
+(defun sweeprolog-context-menu-describe-predicate ()
+ "Describe Prolog predicate at mouse click."
+ (interactive)
+ (sweeprolog-describe-predicate sweeprolog-context-menu-predicate-at-click))
+
+(defun sweeprolog-context-menu-for-predicate (menu tok _beg _end _point)
+ "Extend MENU with predicate-related commands if TOK describes one."
+ (pcase tok
+ ((or `("head" ,_ ,f ,a)
+ `("goal" ,_ ,f ,a))
+ (let ((pred (sweeprolog--query-once "sweep" "sweep_functor_arity_pi"
+ (append (list f a)
+ (buffer-file-name)))))
+ (setq sweeprolog-context-menu-predicate-at-click pred)
+ (define-key menu [sweeprolog-describe-predicate]
+ `(menu-item "Describe This Predicate"
+ sweeprolog-context-menu-describe-predicate
+ :help ,(format "Describe predicate %s" pred)
+ :keys "\\[sweeprolog-describe-predicate]"))))))
+
+(defun sweeprolog-context-menu-for-module (menu tok _beg _end _point)
+ "Extend MENU with module-related commands if TOK describes one."
+ (pcase tok
+ (`("module" . ,module)
+ (setq sweeprolog-context-menu-module-at-click module)
+ (define-key menu [sweeprolog-predicate-module]
+ `(menu-item "Describe This Module"
+ sweeprolog-context-menu-describe-module
+ :help ,(format "Describe module %s" module)
+ :keys "\\[sweeprolog-describe-module]"))
+ (define-key menu [sweeprolog-find-module-other-window]
+ `(menu-item "Find in Other Window"
+ sweeprolog-context-menu-find-module-other-window
+ :help ,(format "Find module %s in other window"
module)
+ :keys "\\[universal-argument]
\\[sweeprolog-find-module]"))
+ (define-key menu [sweeprolog-find-module]
+ `(menu-item "Find This Module"
+ sweeprolog-context-menu-find-module
+ :help ,(format "Find module %s" module)
+ :keys "\\[sweeprolog-find-module]")))))
+
+(defun sweeprolog-context-menu-for-file (menu tok _beg _end _point)
+ "Extend MENU with file-related commands if TOK specifies one."
+ (pcase tok
+ ((or `("file" . ,file)
+ `("file_no_depend" . ,file))
+ (setq sweeprolog-context-menu-file-at-click file)
+ (define-key menu [sweeprolog-find-file-other-window]
+ `(menu-item "Find in Other Window"
+ sweeprolog-context-menu-find-file-other-window
+ :help ,(format "Find %s in other window" file)
+ :keys "\\[universal-argument]
\\[sweeprolog-find-file-at-point]"))
+ (define-key menu [sweeprolog-find-file]
+ `(menu-item "Find This File"
+ sweeprolog-context-menu-find-file
+ :help ,(format "Find %s" file)
+ :keys "\\[sweeprolog-find-file-at-point]")))))
+
+(defvar sweeprolog-context-menu-functions
+ '(sweeprolog-context-menu-for-file
+ sweeprolog-context-menu-for-module
+ sweeprolog-context-menu-for-predicate)
+ "Functions that create context menu entries for Prolog tokens.
+Each function receives as its arguments the menu, the Prolog
+token's description, its start position, its end position, and
+the position for which the menu is created.")
+
+(defun sweeprolog-context-menu-function (menu click)
+ "Populate MENU with Prolog commands at CLICK."
+ (let ((point (posn-point (event-start click))))
+ (save-mark-and-excursion
+ (goto-char point)
+ (sweeprolog-analyze-term-at-point
+ (lambda (beg end tok)
+ (when (<= beg point end)
+ (run-hook-with-args 'sweeprolog-context-menu-functions
+ menu tok beg point end))))))
+ menu)
+
+
;;;; Footer
(provide 'sweeprolog)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [nongnu] elpa/sweeprolog f5a395ce42: ADDED: right-click context menus in sweeprolog-mode,
ELPA Syncer <=