]> git.eshelyaron.com Git - dict.git/commitdiff
Add initial documentation v0.1.2
authorEshel Yaron <me@eshelyaron.com>
Sat, 6 May 2023 18:45:47 +0000 (21:45 +0300)
committerEshel Yaron <me@eshelyaron.com>
Sat, 6 May 2023 18:45:47 +0000 (21:45 +0300)
.gitignore [new file with mode: 0644]
README.org [new file with mode: 0644]
dict.el

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..d094410
--- /dev/null
@@ -0,0 +1,6 @@
+/README.org~
+/dict-autoloads.el
+/dict-pkg.el
+/dict.elc
+/dict.info
+/dict.texi
diff --git a/README.org b/README.org
new file mode 100644 (file)
index 0000000..a9f23f9
--- /dev/null
@@ -0,0 +1,194 @@
+#+title:                 Dict: Display Word Definitions from RFC2229 Dictionary Servers
+#+author:                Eshel Yaron
+#+email:                 me@eshelyaron.com
+#+language:              en
+#+options:               ':t toc:nil author:t email:t num:nil ^:{}
+#+startup:               content indent
+#+export_file_name:      dict.texi
+#+texinfo_filename:      dict.info
+#+texinfo_dir_category:  Emacs
+#+texinfo_dir_title:     Dict: (dict)
+#+texinfo_dir_desc:      Display Word Definitions from RFC2229 Dictionary Servers
+#+texinfo_header:        @set MAINTAINERSITE @uref{https://eshelyaron.com,maintainer webpage}
+#+texinfo_header:        @set MAINTAINER Eshel Yaron
+#+texinfo_header:        @set MAINTAINEREMAIL @email{me@eshelyaron.com}
+#+texinfo_header:        @set MAINTAINERCONTACT @uref{mailto:me@eshelyaron.com,contact the maintainer}
+
+This manual describes the Emacs package Dict (or =dict.el=), which provides an
+interface for querying RFC2229 dictionary servers and displaying word
+definitions.
+
+#+toc: headlines 8 insert TOC here, with eight headline levels
+
+* TODO Installation
+
+* Displaying Word Definitions
+:PROPERTIES:
+:CUSTOM_ID: word-definitions
+:DESCRIPTION: Obtaining and displaying the word definitions
+:ALT_TITLE: Word Definitions
+:END:
+
+Dict defines a single autoloaded command for displaying the word definitions:
+
+- Command: dict-describe-word :: Prompt for a word and display its definition.
+
+This command prompts for a word in the minibuffer, obtains its definition from a
+dictionary server, and displays it in a =*Help*= buffer.  (See [[info:emacs#Help][Help]] in the Emacs
+manual.)
+
+~dict-describe-word~ uses the word at point, if any, as the minibuffer's default
+argument (see [[info:emacs#Basic Minibuffer][Basic Minibuffer]]).  This means that you can display the definition
+of the word at point by typing ~M-x dict-describe-word RET RET~.
+
+Dictionary servers usually support several dictionaries that you can query.
+When Dict asks the dictionary server for a word definition, it needs to specify
+in which dictionary the server should look.  The dictionary Dict uses is
+determined by the user option ~dict-dictionary~.  By default this is set to
+~nil~, which says to prompt for a supported dictionary the first time you invoke
+~dict-describe-word~.
+
+Similarly, the user option ~dict-strategy~ specifies a dictionary matching
+strategy for finding completion candidates.  This is set to ~nil~ by default,
+like ~dict-dictionary~, which means that ~dict-describe-word~ prompts also for a
+supported matching strategy the first time you use it.
+
+You can customize ~dict-dictionary~ and ~dict-strategy~ to appropriate values
+before calling ~dict-describe-word~ to inhibit these prompts on first use.
+(Also see [[#customization][Customizing Dict]] for more customization options.)
+
+* Customizing Dict
+:PROPERTIES:
+:CUSTOM_ID: customization
+:DESCRIPTION: Customization options for Dict
+:ALT_TITLE: Customization
+:END:
+
+The following user options affect the behavior of ~dict-describe-word~:
+
+- User Option: dict-server-host :: Host name or IP address of the
+  dictionary server to use.  Defaults to ~nil~, which means to first
+  try "localhost", and if no local server is available then fallback
+  to the host specified by ~dict-default-server-host~.
+- User Option: dict-default-server-host :: Remote dictionary server to
+  use when there is no local server and ~dict-server-host~ is ~nil~.
+  Defaults to "dict.org".
+- User Option: dict-server-port :: Port number to use for connecting to the
+  dictionary server.  Defaults to 2628.
+- User Option: dict-dictionary :: Name of the dictionary to query, which must be
+  supported by the dictionary server.  Default to ~nil~, which means to prompt
+  for a supported dictionary on the first invocation of ~dict-describe-word~.
+- User Option: dict-dictionary-prompt :: Prompt string to use when prompting for
+  a dictionary.  Defaults to "Set dictionary".
+- User Option: dict-strategy :: Name of the dictionary matching strategy to use,
+  which must be supported by the dictionary server.  Default to ~nil~, which
+  means to prompt for a supported strategy on the first invocation of
+  ~dict-describe-word~.
+- User Option: dict-strategy-prompt :: Prompt string to use when prompting for a
+  matching strategy.  Defaults to "Set matching strategy".
+- User Option: dict-process-name :: Name to use for the dictionary server
+  connection process.  Defaults to "dict".
+- User Option: dict-process-buffer-name :: Name of the buffer to use for the
+  dictionary server connection process output.  Defaults to "*​dict output*".
+  #+FINDEX: dict-display-definition-in-help-buffer
+- User Option: dict-display-definition-function :: Function to use for
+  displaying word definitions.  The function must take two string arguments, the
+  word and its definition, and display the definition to the user.  Defaults to
+  the function ~dict-display-definition-in-help-buffer~, which displays the
+  definition in a =*Help*= buffer.
+
+* Extending Dict
+:PROPERTIES:
+:CUSTOM_ID: extending-dict
+:DESCRIPTION: Defining bespoke extensions for Dict
+:ALT_TITLE: Extending Dict
+:END:
+
+The best way to extend Dict with bespoke commands for your workflow, is to
+define wrappers around ~dict-describe-word~ that supply specific words or
+locally bind some user options to specific values.  For example, the following
+command looks up the definition of the word at point in the WordNet dictionary
+without prompting:
+
+#+begin_src emacs-lisp
+  (defun my/wordnet-definition-for-word-at-point (word)
+    (interactive (list (word-at-point)))
+    (let ((dict-dictionary "wn"))
+      (dict-describe-word word)))
+#+end_src
+
+To create a command that displays definitions in the echo area (see [[info:emacs#Echo Area][Echo Area]]),
+locally bind ~dict-display-definition-function~ to an appropriate function:
+
+#+begin_src emacs-lisp
+  (defun my/echo-word-definition (word)
+    (interactive (list (dict-read-word)))
+    (let ((dict-display-definition-function
+           (lambda (_word definition)
+             (message definition))))
+      (dict-describe-word word)))
+#+end_src
+
+#+FINDEX: dict-read-word
+Note the use of the function ~dict-read-word~ in the above definition.
+This helper function prompts for a word defined in dictionary, with
+completion, using the word at point as the minibuffer's default
+argument.  This is also what ~dict-describe-word~ uses to prompt for a
+word when you call it interactively.
+
+* TODO How Dict Compares to Other RFC2229 Client Packages
+:PROPERTIES:
+:CUSTOM_ID: alternatives
+:DESCRIPTION: Comparison of Dict with other RFC2229 client packages
+:ALT_TITLE: Alternatives
+:END:
+
+** dictionary
+
+** define-word
+
+** DictEm
+
+
+#+html: <!--
+
+* Indices
+:PROPERTIES:
+:CUSTOM_ID: indices
+:DESCRIPTION:
+:ALT_TITLE: Indices
+:END:
+
+** Function index
+:PROPERTIES:
+:INDEX: fn
+:CUSTOM_ID: findex
+:DESCRIPTION:
+:ALT_TITLE: Function Index
+:END:
+
+** Variable index
+:PROPERTIES:
+:INDEX: vr
+:CUSTOM_ID: vindex
+:DESCRIPTION:
+:ALT_TITLE: Variable Index
+:END:
+
+** Keystroke index
+:PROPERTIES:
+:INDEX: ky
+:CUSTOM_ID: kindex
+:DESCRIPTION:
+:ALT_TITLE: Keystroke Index
+:END:
+
+** Concept index
+:PROPERTIES:
+:INDEX: cp
+:CUSTOM_ID: cindex
+:DESCRIPTION:
+:ALT_TITLE: Concept Index
+:END:
+
+#+html: -->
diff --git a/dict.el b/dict.el
index 1582800af67f2b004be611cb8d70d4ee7cc197f2..fa1b04a4fa3531f5e72c431289e21e8d6dda4007 100644 (file)
--- a/dict.el
+++ b/dict.el
@@ -5,8 +5,8 @@
 ;; Author: Eshel Yaron <me@eshelyaron.com>
 ;; Keywords: help, comm
 ;; URL: https://git.eshelyaron.com/gitweb/dict.git
-;; Package-Version: 0.1.0
-;; Package-Requires: ((emacs "29.1"))
+;; Package-Version: 0.1.1
+;; Package-Requires: ((emacs "28.1"))
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 
 ;; Dict defines a single command that displays the definition of a
 ;; given word, as obtained from an RFC2229 dictionary server.  To use
-;; it, invoke \\[dict-describe-word].
+;; it, do M-x dict-describe-word (or bind it to a key).
 
 ;;; Code:
 
   "Access to RFC2229 dictionary servers."
   :group 'help)
 
+(defcustom dict-strategy-prompt "Set matching strategy"
+  "Prompt to use for dictionary matching strategies selection."
+  :type 'string)
+
+(defcustom dict-dictionary-prompt "Set dictionary"
+  "Prompt to use for dictionary selection."
+  :type 'string)
+
 (defcustom dict-process-buffer-name "*dict output*"
   "Buffer name for dictionary server output."
   :type 'string)
   "Process name for dictionary server connection."
   :type 'string)
 
-(defcustom dict-server-host "dict.org"
+(defcustom dict-server-host nil
   "Host or IP address of dictionary server."
-  :type 'string)
+  :type '(choice (const  :tag "Try local server, fallback to `dict-default-server-host'" nil)
+                 (string :tag "Select host")))
 
 (defcustom dict-server-port 2628
   "Port of dictionary server."
   "Function to use for displaying dictionary definitions."
   :type 'function)
 
+(defcustom dict-default-server-host "dict.org"
+  "Remote server to use when there is no local server.
+This is only considered when the user option `dict-server-host'
+is nil."
+  :type 'string)
+
 (defvar dict-process nil)
 
 (defvar dict-read-word-history nil)
 
 (defvar dict-match-cache nil)
 
+(defun dict-server-host ()
+  (or dict-server-host
+      (when-let ((proc (condition-case _
+                           (make-network-process
+                            :name dict-process-name
+                            :host "localhost"
+                            :service dict-server-port)
+                         (file-error nil))))
+        (delete-process proc)
+        (setq dict-server-host "localhost"))
+      (setq dict-server-host  dict-default-server-host)))
+
 (defun dict-command (command parse)
   "Invoke a dictionary server command.
 COMMAND is an RFC2229 command in string format, without a newline.
@@ -99,7 +126,7 @@ beginning of a buffer with the server's response."
                    (setq dict-process
                          (make-network-process
                           :name dict-process-name
-                          :host dict-server-host
+                          :host (dict-server-host)
                           :service dict-server-port
                           :buffer buffer)))))
       (set-process-filter proc filter)
@@ -156,8 +183,8 @@ beginning of a buffer with the server's response."
                              result))
                      result)))))
 
-(defun dict-read-strategy ()
-  "Prompt for a matching strategy supported by the dictionary server."
+(defun dict-read-strategy (prompt)
+  "Prompt with PROMPT for a matching strategy supported by the server."
   (let* ((strats (dict-get-strategies))
          (len (apply #'max (mapcar #'length (mapcar #'car strats))))
          (completion-extra-properties
@@ -165,15 +192,19 @@ beginning of a buffer with the server's response."
                 (lambda (key)
                   (concat (make-string (1+ (- len (length key))) ?\s)
                           (alist-get key strats nil nil #'string=))))))
-    (completing-read "Strategy: "
-                     strats nil t)))
+    (completing-read (format-prompt prompt dict-strategy)
+                     strats nil t nil nil dict-strategy)))
+
+(defun dict-set-strategy ()
+  "Prompt for a value and set the user option `dict-strategy'."
+  (setq dict-strategy (dict-read-strategy dict-strategy-prompt)))
 
 (defun dict-strategy ()
   "Return the value of the user option `dict-strategy'.
 If its nil, prompt for a supported strategy and set the user
 option to it first."
   (or dict-strategy
-      (setq dict-strategy (dict-read-strategy))))
+      (dict-set-strategy)))
 
 (defun dict-get-dictionaries ()
   "Return the dictionary server's supported dictionaries."
@@ -192,8 +223,8 @@ option to it first."
                              result))
                      result)))))
 
-(defun dict-read-dictionary ()
-  "Prompt for dictionary server's supported by the dictionary server."
+(defun dict-read-dictionary (prompt)
+  "Prompt with PROMPT for a dictionary supported by the server."
   (let* ((dicts (dict-get-dictionaries))
          (len (apply #'max (mapcar #'length (mapcar #'car dicts))))
          (completion-extra-properties
@@ -201,18 +232,22 @@ option to it first."
                 (lambda (key)
                   (concat (make-string (1+ (- len (length key))) ?\s)
                           (alist-get key dicts nil nil #'string=))))))
-    (completing-read "Dictionary: "
-                     dicts nil t)))
+    (completing-read (format-prompt prompt dict-dictionary)
+                     dicts nil t nil nil dict-dictionary)))
+
+(defun dict-set-dictionary ()
+  "Prompt for a value and set the user option `dict-dictionary'."
+  (setq dict-dictionary (dict-read-dictionary dict-dictionary-prompt)))
 
 (defun dict-dictionary ()
   "Return the value of the user option `dict-dictionary'.
 If its nil, prompt for a supported dictionary and set the user
 option to it first."
   (or dict-dictionary
-      (setq dict-dictionary (dict-read-dictionary))))
+      (dict-set-dictionary)))
 
 (defun dict-read-word ()
-  "Prompt for a word known to the dictionary server."
+  "Prompt for a word defined in the dictionary server."
   (let* ((completion-ignore-case t)
          (word-at-point (thing-at-point 'word t))
          (default (car (dict-match-word word-at-point))))