I've been making a bunch of modifications to parts of Emacspeak to get
speech output that I like better; I figured others might also find
them useful so I'm attaching them here as 3 separate patches.
All the features are behind customization variables, so you can
control them through the usual customize interface, and they default
to what Emacspeak does already.
Here's a summary of each patch and the customizations each adds:
======
* pitch.patch:
This has straightforward Espeak-specific settings for default
pitch and pitch-range:
* espeak-default-speech-pitch: (integer, defaults to 50)
* espeak-default-speech-pitch-range: (integer, defaults to 50)
------
* move_line_ends.patch:
This lets you change what gets spoken when moving to the
beginning or end of a line.
* emacspeak-speak-at-ends-of-line: (can be line, word, character,
or nothing; defaults to line)
------
* speak_indent.patch:
This lets you customize precisely how line indentation is spoken.
The settings fall into 3 groups.
* emacspeak-audio-indentation-tab-grouped: (toggle, defaults to off)
When this mode is turned on, indentation levels are split up
into two components:
a tab component which is multiple of the tab-width, and a space offset.
For example, if your tab-width is set to 4,
an indentation of 11 will get split up into a multiple of 2
and an offset of 3.
The text for the indentation level announcements is stitched together
by inserting the digits between string segments which are given in
the following settings.
* settings for normal indentation announcements:
* emacspeak-audio-indentation-before: defaults to "indent "
* emacspeak-audio-indentation-after: defaults to ""
* settings for tab-grouped indentation announcements:
* emacspeak-audio-indentation-before-tab: (defaults to "")
* emacspeak-audio-indentation-after-tab: (defaults to " tabs")
* emacspeak-audio-indentation-tab-grouped-separator: (defaults to " ")
* emacspeak-audio-indentation-before-offset: (defaults to "")
* emacspeak-audio-indentation-after-offset: (defaults to " spaces")
To illustrate how this works:
if you again have tab-width set to 4 and an indentation level of 11,
with the following settings:
emacspeak-audio-indentation-before = "indent "
emacspeak-audio-indentation-after = ""
emacspeak-audio-indentation-before-tab = "indent "
emacspeak-audio-indentation-after-tab = " tabs"
emacspeak-audio-indentation-tab-grouped-separator = ", and "
emacspeak-audio-indentation-before-offset = ""
emacspeak-audio-indentation-after-offset = " spaces"
In normal mode, this gets announced as "indent 11",
and in tab-grouped mode, this gets announced as "indent 2 tabs,
and 3 spaces".
------
Here's the relevant part of my .emacs where I've used these customizations:
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(emacspeak-audio-indentation-after " spaces")
'(emacspeak-audio-indentation-before "")
'(emacspeak-character-echo nil)
'(emacspeak-speak-at-ends-of-line (quote char))
'(espeak-default-speech-pitch 75)
'(espeak-default-speech-pitch-range 100)
'(espeak-default-speech-rate 900)
'(package-selected-packages (quote (evil)))
'(tab-width 4))
======
To build emacspeak with any of these patches:
(1) Clone the Emacspeak source from Github.
(2) Download the patchfile and move it into the emacspeak directory.
(3) In the emacspeak directory, apply the patch by running the command:
git apply <patch_file>
(4) Continue building Emacspeak as usual.
You can also check these modifications out of branches with
corresponding names from this Git repository:
https://www.github.com/hussainmkj/emacspeak.git/.
Note that if you want to do a git-based build with more than one of
the branches, you should check out master and then do a single-merge
of the branches you want:
git checkout master
git merge --no-commit <branch_1> <branch_2> [<branch_3>]
Trying to merge them in sequentially will result in merge conflicts.
------
If anyone does find these useful, or wants more more customization
options for the features, let me know!
Cheers,
Hussain
From 5b5bdc607639d3b0bf2db4486ed11474d625cd30 Mon Sep 17 00:00:00 2001
From: Hussain Jasim <hussain.jasim@xxxxxxxxxxx>
Date: Fri, 8 Jun 2018 10:53:52 -0400
Subject: [PATCH 1/3] Added functions to the Espeak server for setting pitch
and pitch-range.
---
servers/espeak | 20 +++++++++
servers/native-espeak/tclespeak.cpp | 88 +++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+)
diff --git a/servers/espeak b/servers/espeak
index cdc68c487..f4db85ced 100755
--- a/servers/espeak
+++ b/servers/espeak
@@ -206,6 +206,26 @@ proc tts_set_speech_rate {rate} {
return ""
}
+proc tts_set_speech_pitch {pitch} {
+ global tts
+
+ set factor $tts(char_factor)
+ set tts(speech_pitch) $pitch
+ setPitch 0 $pitch
+ service
+ return ""
+}
+
+proc tts_set_speech_pitch_range {pitch_range} {
+ global tts
+
+ set factor $tts(char_factor)
+ set tts(speech_pitch_range) $pitch_range
+ setPitchRange 0 $pitch_range
+ service
+ return ""
+}
+
proc tts_set_character_scale {factor} {
global tts
diff --git a/servers/native-espeak/tclespeak.cpp b/servers/native-espeak/tclespeak.cpp
index c7e64a15d..48143de38 100644
--- a/servers/native-espeak/tclespeak.cpp
+++ b/servers/native-espeak/tclespeak.cpp
@@ -68,6 +68,10 @@ extern "C" EXPORT int Tclespeak_Init(Tcl_Interp *interp);
int SetRate(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
int GetRate(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
+int SetPitch(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
+int GetPitch(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
+int SetPitchRange(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
+int GetPitchRange(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
int getTTSVersion(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
int Punct(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
int Caps(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST[]);
@@ -113,6 +117,14 @@ int Tclespeak_Init(Tcl_Interp *interp) {
TclEspeakFree);
Tcl_CreateObjCommand(interp, "getRate", GetRate, (ClientData)handle,
TclEspeakFree);
+ Tcl_CreateObjCommand(interp, "setPitch", SetPitch, (ClientData)handle,
+ TclEspeakFree);
+ Tcl_CreateObjCommand(interp, "getPitch", GetPitch, (ClientData)handle,
+ TclEspeakFree);
+ Tcl_CreateObjCommand(interp, "setPitchRange", SetPitchRange, (ClientData)handle,
+ TclEspeakFree);
+ Tcl_CreateObjCommand(interp, "getPitchRange", GetPitchRange, (ClientData)handle,
+ TclEspeakFree);
Tcl_CreateObjCommand(interp, "ttsVersion", getTTSVersion, (ClientData)handle,
TclEspeakFree);
Tcl_CreateObjCommand(interp, "punct", Punct, (ClientData)handle, NULL);
@@ -182,6 +194,82 @@ int SetRate(ClientData handle, Tcl_Interp *interp, int objc,
return success ? TCL_OK : TCL_ERROR;
}
+int GetPitch(ClientData handle, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]) {
+ int rc, pitch, voice;
+ if (objc != 2) {
+ Tcl_AppendResult(interp, "Usage: getPitch voiceCode ", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ rc = Tcl_GetIntFromObj(interp, objv[1], &voice);
+ if (rc != TCL_OK) return rc;
+
+ pitch = espeak_GetParameter(espeakPITCH, 1);
+
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pitch));
+ return TCL_OK;
+}
+
+int SetPitch(ClientData handle, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]) {
+ static int current_pitch = -1;
+ int rc, pitch, voice;
+ int success = 1;
+ if (objc != 3) {
+ Tcl_AppendResult(interp, "Usage: setPitch voiceCode speechPitch ",
+ TCL_STATIC);
+ return TCL_ERROR;
+ }
+ rc = Tcl_GetIntFromObj(interp, objv[1], &voice);
+ if (rc != TCL_OK) return rc;
+ rc = Tcl_GetIntFromObj(interp, objv[2], &pitch);
+ if (rc != TCL_OK) return rc;
+
+ if (pitch != current_pitch) {
+ success = (espeak_SetParameter(espeakPITCH, pitch, 0) == EE_OK);
+ if (success) current_pitch = pitch;
+ }
+ return success ? TCL_OK : TCL_ERROR;
+}
+
+int GetPitchRange(ClientData handle, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]) {
+ int rc, pitch_range, voice;
+ if (objc != 2) {
+ Tcl_AppendResult(interp, "Usage: getPitchRange voiceCode ", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ rc = Tcl_GetIntFromObj(interp, objv[1], &voice);
+ if (rc != TCL_OK) return rc;
+
+ pitch_range = espeak_GetParameter(espeakRANGE, 1);
+
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pitch_range));
+ return TCL_OK;
+}
+
+int SetPitchRange(ClientData handle, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]) {
+ static int current_pitch_range = -1;
+ int rc, pitch_range, voice;
+ int success = 1;
+ if (objc != 3) {
+ Tcl_AppendResult(interp, "Usage: setPitchRange voiceCode speechPitchRange ",
+ TCL_STATIC);
+ return TCL_ERROR;
+ }
+ rc = Tcl_GetIntFromObj(interp, objv[1], &voice);
+ if (rc != TCL_OK) return rc;
+ rc = Tcl_GetIntFromObj(interp, objv[2], &pitch_range);
+ if (rc != TCL_OK) return rc;
+
+ if (pitch_range != current_pitch_range) {
+ success = (espeak_SetParameter(espeakRANGE, pitch_range, 0) == EE_OK);
+ if (success) current_pitch_range = pitch_range;
+ }
+ return success ? TCL_OK : TCL_ERROR;
+}
+
//>
//<say
--
2.15.0
From 7f4a4e2246f8918b03e4766652bc613371fa0fd4 Mon Sep 17 00:00:00 2001
From: Hussain Jasim <hussain.jasim@xxxxxxxxxxx>
Date: Wed, 20 Jun 2018 22:27:50 -0400
Subject: [PATCH 2/3] Added functions to the Espeak client for interactively
setting pitch and pitch-range.
---
lisp/espeak-voices.el | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/lisp/espeak-voices.el b/lisp/espeak-voices.el
index e98a7e4a7..59c21c648 100644
--- a/lisp/espeak-voices.el
+++ b/lisp/espeak-voices.el
@@ -57,6 +57,82 @@
(string-match "espeak$" (getenv "DTK_PROGRAM")))
(setq-default dt-speech-rate val))))
+;;{{{ espeak-specific controls
+;; Functions to interface with the Espeak server and interactively set pitch and pitch-range,
+;; which are defined here instead of dtk-speech.el because they are exclusive to Espeak.
+
+;;{{{ espeak pitch
+(defun espeak-interp-set-pitch (pitch)
+ (cl-declare (special dtk-speaker-process))
+ (process-send-string dtk-speaker-process
+ (format "tts_set_speech_pitch %s\n"
+ pitch)))
+
+;;;###autoload
+(defun espeak-set-pitch (pitch &optional prefix)
+ "Set speaking PITCH for espeak.
+Interactive PREFIX arg means set the global default value, and then set the
+current local value to the result."
+ (interactive
+ (list
+ (read-from-minibuffer "Enter new pitch: ")
+ current-prefix-arg))
+ (cl-declare (special espeak-speech-pitch dtk-speaker-process
+ espeak-default-speech-pitch
+ dtk-program dtk-speak-server-initialized))
+ (when dtk-speak-server-initialized
+ (cond
+ (prefix
+ (unless (eq dtk-speaker-process (dtk-notify-process))
+ (let ((dtk-speaker-process (dtk-notify-process)))
+ (espeak-set-pitch pitch)))
+ (setq espeak-default-speech-pitch pitch)
+ (setq-default espeak-speech-pitch pitch)
+ (setq espeak-speech-pitch pitch))
+ (t (setq espeak-speech-pitch pitch)))
+ (espeak-interp-set-pitch pitch)
+ (when (called-interactively-p 'interactive)
+ (message "Set speech pitch to %s %s"
+ pitch
+ (if prefix "" "locally")))))
+
+;;}}}
+;;{{{ espeak pitch-range
+(defun espeak-interp-set-pitch-range (pitch-range)
+ (cl-declare (special dtk-speaker-process))
+ (process-send-string dtk-speaker-process
+ (format "tts_set_speech_pitch_range %s\n"
+ pitch-range)))
+
+;;;###autoload
+(defun espeak-set-pitch-range (pitch-range &optional prefix)
+ "Set speaking PITCH for espeak.
+Interactive PREFIX arg means set the global default value, and then set the
+current local value to the result."
+ (interactive
+ (list
+ (read-from-minibuffer "Enter new pitch-range: ")
+ current-prefix-arg))
+ (cl-declare (special espeak-speech-pitch-range dtk-speaker-process
+ espeak-default-speech-pitch-range
+ dtk-program dtk-speak-server-initialized))
+ (when dtk-speak-server-initialized
+ (cond
+ (prefix
+ (unless (eq dtk-speaker-process (dtk-notify-process))
+ (let ((dtk-speaker-process (dtk-notify-process)))
+ (espeak-set-pitch-range pitch-range)))
+ (setq espeak-default-speech-pitch-range pitch-range)
+ (setq-default espeak-speech-pitch-range pitch-range)
+ (setq espeak-speech-pitch-range pitch-range))
+ (t (setq espeak-speech-pitch-range pitch-range)))
+ (espeak-interp-set-pitch-range pitch-range)
+ (when (called-interactively-p 'interactive)
+ (message "Set speech pitch-range to %s %s"
+ pitch-range
+ (if prefix "" "locally")))))
+
+;;}}}
;;}}}
;;{{{ Top-Level TTS Call
--
2.15.0
From 9174baeefde2f8ff561de1ce485832d3da526c12 Mon Sep 17 00:00:00 2001
From: Hussain Jasim <hussain.jasim@xxxxxxxxxxx>
Date: Wed, 20 Jun 2018 22:33:34 -0400
Subject: [PATCH 3/3] Added defaults and customizations to the Espeak client
for pitch and pitch-range.
---
lisp/espeak-voices.el | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/lisp/espeak-voices.el b/lisp/espeak-voices.el
index 59c21c648..a84435d41 100644
--- a/lisp/espeak-voices.el
+++ b/lisp/espeak-voices.el
@@ -57,6 +57,27 @@
(string-match "espeak$" (getenv "DTK_PROGRAM")))
(setq-default dt-speech-rate val))))
+(defcustom espeak-default-speech-pitch 50
+ "Default speech pitch for eSpeak."
+ :group 'tts
+ :type 'integer
+ :set #'(lambda(sym val)
+ (set-default sym val)
+ (when (and (getenv "DTK_PROGRAM")
+ (string-match "espeak$" (getenv "DTK_PROGRAM")))
+ (setq-default espeak-speech-pitch val))))
+
+(defcustom espeak-default-speech-pitch-range 50
+ "Default speech pitch range for eSpeak."
+ :group 'tts
+ :type 'integer
+ :set #'(lambda(sym val)
+ (set-default sym val)
+ (when (and (getenv "DTK_PROGRAM")
+ (string-match "espeak$" (getenv "DTK_PROGRAM")))
+ (setq-default espeak-speech-pitch-range val))))
+
+;;}}}
;;{{{ espeak-specific controls
;; Functions to interface with the Espeak server and interactively set pitch and pitch-range,
;; which are defined here instead of dtk-speech.el because they are exclusive to Espeak.
@@ -561,6 +582,8 @@ and TABLE gives the values along that dimension."
"Configure TTS environment to use eSpeak."
(cl-declare (special tts-default-speech-rate
espeak-default-speech-rate
+ espeak-default-speech-pitch
+ espeak-default-speech-pitch-range
dtk-speaker-process
emacspeak-unspeakable-rule))
(fset 'tts-list-voices'espeak-list-voices)
@@ -571,6 +594,8 @@ and TABLE gives the values along that dimension."
(setq tts-default-voice nil)
(setq tts-default-speech-rate espeak-default-speech-rate)
(set-default 'tts-default-speech-rate espeak-default-speech-rate)
+ (espeak-set-pitch espeak-default-speech-pitch t)
+ (espeak-set-pitch-range espeak-default-speech-pitch-range t)
(espeak-setup-character-to-speech-table)
(dtk-unicode-update-untouched-charsets '(ascii latin-iso8859-1)))
@@ -579,10 +604,12 @@ and TABLE gives the values along that dimension."
;;;###autoload
(defun espeak-make-tts-env ()
"Constructs a TTS environment for Espeak."
- (cl-declare (special espeak-default-speech-rate))
+ (cl-declare (special espeak-default-speech-rate espeak-default-speech-pitch espeak-default-speech-pitch-range))
(make-tts-env
:name :espeak :default-voice 'paul
:default-speech-rate espeak-default-speech-rate
+ :default-speech-pitch espeak-default-speech-pitch
+ :default-speech-pitch-range espeak-default-speech-pitch-range
:list-voices #'espeak-list-voices
:acss-voice-defined-p #'espeak-voice-defined-p
:get-acss-voice-command #'espeak-get-voice-command
--
2.15.0
From 666f5664ba9a58fd6d6cbc19b9459ffb061bc5e6 Mon Sep 17 00:00:00 2001
From: Hussain Jasim <hussain.jasim@xxxxxxxxxxx>
Date: Wed, 20 Feb 2019 00:09:24 -0500
Subject: [PATCH] Implemented a customization variable for the unit of text
that should be spoken when moving to the beginning and end of a line, and
pulled this behaviour out into its own advice.
---
lisp/emacspeak-advice.el | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/lisp/emacspeak-advice.el b/lisp/emacspeak-advice.el
index baa6abfbc..7f5b2a982 100644
--- a/lisp/emacspeak-advice.el
+++ b/lisp/emacspeak-advice.el
@@ -2247,9 +2247,7 @@ Produce an auditory icon if possible."
(cl-loop
for f in
- '(beginning-of-line end-of-line
- move-beginning-of-line move-end-of-line
- recenter-top-bottom recenter)
+ '(recenter-top-bottom recenter)
do
(eval
`(defadvice ,f (before emacspeak pre act comp)
@@ -2259,6 +2257,34 @@ Produce an auditory icon if possible."
(emacspeak-auditory-icon 'select-object)))))
;;}}}
+;;{{{ speak when moving to beginning and end of line
+
+(defcustom emacspeak-speak-at-ends-of-line 'line
+ "Current text unit under point to speak when moving to the beginning or end of a line. Default is `line'."
+ :group 'emacspeak-advice
+ :type '(choice
+ (const :tag "nothing" nil)
+ (const :tag "line" line)
+ (const :tag "word" word)
+ (const :tag "character" char)))
+
+(cl-loop
+ for f in
+ '(beginning-of-line end-of-line
+ move-beginning-of-line move-end-of-line)
+ do
+ (eval
+ `(defadvice ,f (after emacspeak pre act comp)
+ "Speak `emacspeak-speak-at-ends-of-line' under point."
+ (when (and (ems-interactive-p) (not (eq emacspeak-speak-at-ends-of-line 'nil)))
+ (and dtk-stop-immediately (dtk-stop))
+ (cond
+ ((eq emacspeak-speak-at-ends-of-line 'line) (emacspeak-speak-line))
+ ((eq emacspeak-speak-at-ends-of-line 'word) (emacspeak-speak-word))
+ ((eq emacspeak-speak-at-ends-of-line 'char) (emacspeak-speak-char t)))
+ (emacspeak-auditory-icon 'select-object)))))
+
+;;}}}
;;{{{ yanking and popping
(cl-loop
--
2.15.0
From 932adfe6dc83fed1bad65dc529bfa43e64de3744 Mon Sep 17 00:00:00 2001
From: Hussain Jasim <hussain.jasim@xxxxxxxxxxx>
Date: Wed, 20 Feb 2019 01:43:05 -0500
Subject: [PATCH] Implemented customization variables for: (1) controling the
phrasing of line indentation level announcements; (2) grouping indentation
level by multiples and offsets of the tab-width.
---
lisp/emacspeak-speak.el | 54 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/lisp/emacspeak-speak.el b/lisp/emacspeak-speak.el
index e61448b03..90a04305a 100644
--- a/lisp/emacspeak-speak.el
+++ b/lisp/emacspeak-speak.el
@@ -682,6 +682,46 @@ results in the Dectalk producing a tone whose length is a function of the
line's indentation. Specifying `speak'
results in the number of initial spaces being spoken.")
+(defcustom emacspeak-audio-indentation-before "indent "
+ "Option specifying the phrase that is spoken before the indent level, when speaking line indentation."
+ :group 'emacspeak-speak
+ :type 'string)
+
+(defcustom emacspeak-audio-indentation-after ""
+ "Option specifying the phrase that is spoken after the indent level, when speaking line indentation."
+ :group 'emacspeak-speak
+ :type 'string)
+
+(defcustom emacspeak-audio-indentation-tab-grouped nil
+ "Option indicating whether indentation levels should be grouped into a multiple of the tab-width and an offset, when speaking line indentation."
+ :group 'emacspeak-speak
+ :type 'boolean)
+
+(defcustom emacspeak-audio-indentation-before-tab ""
+ "Option specifying the phrase that is spoken before the tab-width multiple, when speaking tab-grouped line indentation."
+ :group 'emacspeak-speak
+ :type 'string)
+
+(defcustom emacspeak-audio-indentation-after-tab " tabs"
+ "Option specifying the phrase that is spoken after the tab-width multiple, when speaking tab-grouped line indentation."
+ :group 'emacspeak-speak
+ :type 'string)
+
+(defcustom emacspeak-audio-indentation-tab-grouped-separator " "
+ "Option specifying the phrase that is spoken between the tab-width multiple and the tab-width offset, when speaking tab-grouped line indentation."
+ :group 'emacspeak-speak
+ :type 'string)
+
+(defcustom emacspeak-audio-indentation-before-offset ""
+ "Option specifying the phrase that is spoken before the tab-width offset, when speaking tab-grouped line indentation."
+ :group 'emacspeak-speak
+ :type 'string)
+
+(defcustom emacspeak-audio-indentation-after-offset " spaces"
+ "Option specifying the phrase that is spoken after the tab-width offset, when speaking tab-grouped line indentation."
+ :group 'emacspeak-speak
+ :type 'string)
+
;;}}}
;;{{{ filtering columns
@@ -1017,7 +1057,19 @@ with auditory icon `more'. These can then be spoken using command
(when
(and (null arg) indent (> indent 0)
(eq 'speak emacspeak-audio-indentation-method))
- (setq indent (format "indent %d" indent))
+ (setq indent
+ (cond
+ ((not emacspeak-audio-indentation-tab-grouped)
+ (format "%s%d%s" emacspeak-audio-indentation-before indent emacspeak-audio-indentation-after))
+ ((< indent tab-width)
+ (format "%s%d%s" emacspeak-audio-indentation-before-offset indent emacspeak-audio-indentation-after-offset))
+ ((eq 0 (% indent tab-width))
+ (format "%s%d%s" emacspeak-audio-indentation-before-tab (/ indent tab-width) emacspeak-audio-indentation-after-tab))
+ (
+ (format "%s%d%s%s%s%d%s"
+ emacspeak-audio-indentation-before-tab (/ indent tab-width) emacspeak-audio-indentation-after-tab
+ emacspeak-audio-indentation-tab-grouped-separator
+ emacspeak-audio-indentation-before-offset (% indent tab-width) emacspeak-audio-indentation-after-offset))))
(setq indent (propertize indent 'personality voice-indent))
(setq line (concat indent line)))
(when linenum
--
2.15.0
|May 1995 - Last Year |Current Year|
If you have questions about this archive or had problems using it, please contact us.