Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Pierre Balaye
Multiple Emacs Flavor Setup
Commits
598b6ae1
Commit
598b6ae1
authored
May 20, 2020
by
Pierre Balaye
Browse files
New strategy: with private layers
parent
689de28e
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
configs/spacemacs-default/dot-user-config.el
View file @
598b6ae1
(
defun
dotspacemacs/user-config-specific
()
(
ulys/config/org
)
(
ulys/config/ess
)
)
; ESS config
(
defun
ulys/config/ess
()
(
ulys/conf/ess-devtools-save-silentely
)
(
add-hook
'ess-mode-hook
(
lambda
()
(
define-key
ess-mode-map
(
kbd
";"
)
'ess-insert-assign
)
(
define-key
ess-mode-map
(
kbd
"C-;"
)
'ulys/conf/ess-insert-magrittr-pipe
)
(
define-key
ess-mode-map
(
kbd
"C-:"
)
'ulys/conf/ess-insert-right-assign-operator
)
(
define-key
ess-mode-map
(
kbd
"C-x C-j"
)
'ess-eval-line-invisibly-and-step
)
(
define-key
ess-mode-map
(
kbd
"C-`"
)
'ulys/conf/ess-backquote-from-dollar
)
(
define-key
ess-mode-map
(
kbd
"C-~"
)
'ulys/conf/ess-backquote-delete-df$
)
)))
(
defun
ulys/conf/ess-insert-magrittr-pipe
()
"Insert magrittr pipe at i.e. \"%>%\"."
(
interactive
)
(
insert
"\n %>% "
))
(
defun
ulys/conf/ess-insert-right-assign-operator
()
"Insert \"->\"."
(
interactive
)
(
insert
" -> "
))
(
defun
ulys/conf/ess-devtools-save-silentely
()
(
setq
ess-save-silently
t
))
(
defun
ulys/conf/ess-backquote-from-dollar
()
"Surround with backquotes form last $ till point."
(
interactive
)
(
insert
"`"
)
(
setq
initial-position
(
point
))
(
evil-find-char-to-backward
1
(
string-to-char
"$"
))
(
insert
"`"
)
(
goto-char
(
+
1
initial-position
)))
(
defun
ulys/conf/ess-backquote-delete-df$
()
(
interactive
)
(
ulys/conf/ess-backquote-from-dollar
)
(
evil-find-char-to-backward
1
(
string-to-char
"$"
))
(
setq
dollar-position
(
point
))
(
evil-backward-WORD-begin
)
(
evil-sp-delete
(
point
)
dollar-position
)
(
evil-find-char
1
(
string-to-char
"`"
))
(
evil-forward-char
)
)
;; Org config
(
defun
ulys/config/org
()
(
ulys/config/org/misc
)
(
ulys/config/org/babel
)
(
ulys/config/org-calendar
)
;; (ulys/config/org-minted)
;; (ulys/config/org-odt-export-latexml)
;; (ulys/config/org-capture)
;; (ulys/config/org-file-apps)
)
(
defun
ulys/config/org/misc
()
(
setq
org-list-allow-alphabetical
t
)
(
setq
org-hide-emphasis-markers
t
)
;; <sTAB => src block
(
require
'org-tempo
)
)
(
defun
ulys/config/org/babel
()
(
setq
org-src-window-setup
'current-window
)
;; FIXME julia bug - hack - have opened issue #13597
(
setq
inferior-julia-program-name
"julia"
)
(
custom-set-variables
'
(
org-babel-load-languages
(
quote
((
emacs-lisp
.
t
)
(
R
.
t
)
(
latex
.
t
)
(
shell
.
t
)
(
ditaa
.
t
)
(
julia
.
t
)
(
python
.
t
)
(
sql
.
t
)
)))
'
(
org-confirm-babel-evaluate
nil
)))
(
defun
ulys/org-insert-csv-as-table
(
filename
)
"Insert a csv file into the current buffer at point, and convert it to an org table."
(
interactive
(
list
(
ido-read-file-name
"csv file: "
)))
(
let*
((
start
(
point
))
(
end
(
+
start
(
nth
1
(
insert-file-contents
filename
)))))
(
org-table-convert-region
start
end
)))
(
defun
ulys/config/org-capture
()
(
setq
org-default-notes-file
"~/Nextcloud/org/tasks.org"
)
(
setq
org-capture-templates
'
((
"t"
"Thesis-related Task"
entry
(
file
"~/Nextcloud/org/thesis.org"
)
"** TODO %?"
:empty-lines
1
)
(
"u"
"Teaching-related Task"
entry
(
file
"~/Nextcloud/org/teaching.org"
)
"** TODO %?"
:empty-lines
1
)
(
"h"
"Hospital-related Task"
entry
(
file
"~/Nextcloud/org/hospital.org"
)
"** TODO %?"
:empty-lines
1
))))
(
defun
ulys/config/org-file-apps
()
(
defun
ulys/org-pdf-app
(
file-path
link-without-schema
)
"Open pdf file using pdf-tools and go to the specified page."
(
let*
((
page
(
if
(
not
(
string-match
"\\.pdf::\\([0-9]+\\)\\'"
link-without-schema
))
1
(
string-to-number
(
match-string
1
link-without-schema
)))))
(
find-file-other-window
file-path
)
(
pdf-view-goto-page
page
)))
(
setq
org-file-apps
'
((
auto-mode
.
emacs
)
(
"\\.x?html?\\'"
.
"firefox %s"
)
(
"\\.pdf\\(::[0-9]+\\)?\\'"
.
whatacold/org-pdf-app
)
(
"\\.gif\\'"
.
"eog \"%s\""
)
(
"\\.mp4\\'"
.
"vlc \"%s\""
)
(
"\\.mkv"
.
"vlc \"%s\""
))))
(
defun
ulys/config/org-calendar
()
(
setq
calendar-week-start-day
1
))
(
defun
ulys/org//capture-helper-capture-with-yank-method
(
method
arg
)
;; helper 1/2
(
defun
wrap-into-results-example
(
capture
)
(
concat
"#+RESULTS:\n"
"#+ATTR_LATEX: :options frame=lines\n"
"#+BEGIN_SRC R :eval no :tangle no\n"
capture
"\n#+END_SRC\n"
))
;; helper 2/2
(
defun
choose-process
(
arg
)
(
if
(
or
arg
;; user asks for selection
(
not
(
boundp
'R-process-target
))
;; target not set
;; or target is not set to an active process:
(
not
(
process-live-p
(
get-buffer-process
R-process-target
))))
(
setq
R-process-target
(
completing-read
"Choose R process: "
(
seq-map
(
lambda
(
el
)
(
buffer-name
(
process-buffer
el
)))
(
process-list
))))))
;; main
(
choose-process
arg
)
(
insert
(
wrap-into-results-example
(
funcall
method
R-process-target
))))
(
defun
ulys/org/tibble-capture
(
arg
)
"Let the user choose a R process, then kill last tibble output
in the process and insert it in current buffer in a org
#+RESULTS: format."
(
interactive
"P"
)
;; helper 1/3
(
defun
extract-nrows-from-tibble-first-line
(
line
)
"Extract the number N in the pattern: # A tibble N x M"
(
let*
((
line-without-commas
(
replace-regexp-in-string
","
""
line
))
(
x-position
(
string-match
" x"
line-without-commas
))
(
nrow-start-at
(
length
"# A tibble "
)))
(
string-to-number
(
substring
line-without-commas
nrow-start-at
x-position
))))
;; helper 3/3
(
defun
yank-last-tibble-from-buffer
(
buffer
)
(
interactive
)
(
save-current-buffer
(
set-buffer
buffer
)
(
search-backward
"tibble"
)
(
beginning-of-line
)
(
let*
((
tibble-beg
(
point
))
(
nrow
(
extract-nrows-from-tibble-first-line
(
thing-at-point
'line
t
)))
(
tibble-end
(
progn
(
message
"nrow: %d"
nrow
)
(
re-search-forward
(
concat
"^"
(
number-to-string
(
min
10
nrow
))))
(
while
(
search-forward
"#"
nil
t
))
;; t means no error
(
end-of-line
)
(
point
))))
(
buffer-substring
tibble-beg
tibble-end
))))
;; main
(
ulys/org//capture-helper-capture-with-yank-method
'yank-last-tibble-from-buffer
arg
))
(
defun
ulys/org/glimpse-capture
(
arg
)
"Let the user choose a R process, then kill last glimpse output
in the process and insert it in current buffer in a org
#+RESULTS: format."
(
interactive
"P"
)
;; helper 1
(
defun
extract-nb-vars-from-glimpse-second-line
(
line
)
"Extract the number N in the pattern: Variables: N"
(
let
((
nb-vars-start-at
(
length
"Varialbes: "
))
(
nb-vars-end-at
(
length
line
)))
(
string-to-number
(
substring
line
nb-vars-start-at
nb-vars-end-at
))))
;; helper 2
(
defun
suppress_$_in_front_of_lines
(
lines
)
(
replace-regexp-in-string
"^\$ "
""
lines
))
;; helper 3
(
defun
yank-last-glimpse-from-buffer
(
buffer
)
(
interactive
)
(
save-current-buffer
(
set-buffer
buffer
)
(
search-backward
"Observations: "
)
(
beginning-of-line
)
(
let*
((
glimpse-beg
(
point
))
(
nrow
(
progn
(
forward-line
)
(
extract-nb-vars-from-glimpse-second-line
(
thing-at-point
'line
t
))))
(
glimpse-end
(
progn
(
forward-line
nrow
)
(
end-of-line
)
(
point
))))
(
suppress_$_in_front_of_lines
(
buffer-substring
glimpse-beg
glimpse-end
)
))))
;; main
(
ulys/org//capture-helper-capture-with-yank-method
'yank-last-glimpse-from-buffer
arg
))
(
defun
ulys/config/org-minted
()
(
setq
org-latex-listings
'minted
org-latex-packages-alist
'
((
""
"minted"
))
org-latex-pdf-process
'
(
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
)))
(
defun
ulys/config/org-odt-export-latexml
()
(
setq
org-latex-to-mathml-convert-command
"latexmlmath \"%i\" --presentationmathml=%o"
))
(
defun
dotspacemacs/user-config-specific
())
configs/spacemacs-minimal/init.el
View file @
598b6ae1
This diff is collapsed.
Click to expand it.
configs/spacemacs-test/init.el
deleted
120000 → 0
View file @
689de28e
..
/spacemacs-minimal/init.el
\ No newline at end of file
configs/spacemacs-test/init.el
0 → 100644
View file @
598b6ae1
;; -*- mode: emacs-lisp; lexical-binding: t -*-
;; This file is loaded by Spacemacs at startup.
;; It must be stored in your home directory.
;; Determine specific config directory
(
setq
config-emacs-directory
(
replace-regexp-in-string
"flavors"
"configs"
user-emacs-directory
))
(
defun
load-config-file
(
filename
)
(
load
(
concat
config-emacs-directory
filename
)))
(
defun
dotspacemacs/layers
()
"Layer configuration:
This function should only modify configuration layer settings."
;; --------------------------------------------------
;; ------ Configuration common to all versions ------
;; --------------------------------------------------
;; Settings
(
setq-default
dotspacemacs-distribution
'spacemacs
dotspacemacs-enable-lazy-installation
nil
dotspacemacs-ask-for-lazy-installation
t
dotspacemacs-configuration-layer-path
(
list
(
concat
user-emacs-directory
"../../layers/"
))
dotspacemacs-additional-packages
'
()
dotspacemacs-frozen-packages
'
()
dotspacemacs-excluded-packages
'
()
dotspacemacs-install-packages
'used-but-keep-unused
)
;; Layers
(
setq-default
;; List of configuration layers to load.
dotspacemacs-configuration-layers
'
(
(
general
:location
local
)
(
smartparens
:location
local
)
(
dired
:location
local
)
(
pdfs
:location
local
)
)
)
;; --------------------------------------------------
;; ----- Configuration specific to this version -----
;; --------------------------------------------------
(
load-config-file
"dot-layers.el"
)
(
dotspacemacs/layers-specific
)
)
(
defun
dotspacemacs/init
()
"Instantiate Spacemacs core settings.
All `dotspacemacs-' variables with values set different than their defaults.
They are all defined in `~/.emacs.d/core/core-dotspacemacs.el'.
Check `dotspacemacs/get-variable-string-list' for all vars you can configure."
;; --------------------------------------------------
;; ------ Configuration common to all versions ------
;; --------------------------------------------------
(
setq-default
dotspacemacs-editing-style
'hybrid
dotspacemacs-startup-banner
100
dotspacemacs-startup-lists
'
(
(
agenda
.
10
)
(
todos
.
20
)
(
projects
.
5
)
(
recents
.
10
)
)
dotspacemacs-themes
'
(
spacemacs-dark
spacemacs-light
)
dotspacemacs-default-font
'
(
"Source Code Pro"
:size
13.0
:weight
normal
:width
normal
)
dotspacemacs-leader-key
"SPC"
dotspacemacs-emacs-command-key
"SPC"
dotspacemacs-emacs-leader-key
"M-m"
dotspacemacs-major-mode-emacs-leader-key
(
if
window-system
"<M-return>"
"C-M-m"
)
dotspacemacs-default-layout-name
"TODO"
dotspacemacs-display-default-layout
t
dotspacemacs-auto-resume-layouts
t
dotspacemacs-auto-generate-layout-names
t
dotspacemacs-auto-save-file-location
'original
dotspacemacs-enable-paste-transient-state
t
dotspacemacs-fullscreen-at-startup
t
dotspacemacs-mode-line-unicode-symbols
nil
dotspacemacs-line-numbers
'visual
dotspacemacs-search-tools
'
(
"ag"
"rg"
"pt"
"ack"
"grep"
)
dotspacemacs-whitespace-cleanup
'all
dotspacemacs-pretty-docs
t
)
;; --------------------------------------------------
;; ----- Configuration specific to this version -----
;; --------------------------------------------------
(
load-config-file
"dot-init.el"
)
(
dotspacemacs/init-specific
)
)
(
defun
dotspacemacs/user-env
()
"Environment variables setup.
This function defines the environment variables for your Emacs session. By
default it calls `spacemacs/load-spacemacs-env' which loads the environment
variables declared in `~/.spacemacs.env' or `~/.spacemacs.d/.spacemacs.env'.
See the header of this file for more information."
;; --------------------------------------------------
;; ------ Configuration common to all versions ------
;; --------------------------------------------------
;; --------------------------------------------------
;; ----- Configuration specific to this version -----
;; --------------------------------------------------
(
load-config-file
"dot-user-env.el"
)
(
dotspacemacs/user-env-specific
)
)
(
defun
dotspacemacs/user-init
()
"Initialization for user code:
This function is called immediately after `dotspacemacs/init', before layer
configuration.
It is mostly for variables that should be set before packages are loaded.
If you are unsure, try setting them in `dotspacemacs/user-config' first."
;; --------------------------------------------------
;; ------ Configuration common to all versions ------
;; --------------------------------------------------
;; --------------------------------------------------
;; ----- Configuration specific to this version -----
;; --------------------------------------------------
(
load-config-file
"dot-user-init.el"
)
(
dotspacemacs/user-init-specific
)
)
(
defun
dotspacemacs/user-load
()
"Library to load while dumping.
This function is called only while dumping Spacemacs configuration. You can
`require' or `load' the libraries of your choice that will be included in the
dump."
;; --------------------------------------------------
;; ------ Configuration common to all versions ------
;; --------------------------------------------------
;; --------------------------------------------------
;; ----- Configuration specific to this version -----
;; --------------------------------------------------
(
load-config-file
"dot-user-load.el"
)
(
dotspacemacs/user-load-specific
)
)
(
defun
dotspacemacs/user-config
()
"Configuration for user code:
This function is called at the very end of Spacemacs startup, after layer
configuration.
Put your configuration code here, except for variables that should be set
before packages are loaded."
;; --------------------------------------------------
;; ------ Configuration common to all versions ------
;; --------------------------------------------------
(
spacemacs/toggle-centered-point-globally-on
)
(
ulys/conf/dired
)
(
ulys/conf/kbd
)
;; --------------------------------------------------
;; ----- Configuration specific to this version -----
;; --------------------------------------------------
(
load-config-file
"dot-user-config.el"
)
(
dotspacemacs/user-config-specific
)
)
; dired config
(
defun
ulys/conf/dired
()
)
; kbd config
(
defun
ulys/conf/kbd
()
;; --- others
;; C-h to delete buffer and C-S-h for help
(
global-set-key
(
kbd
"C-h"
)
'spacemacs/kill-this-buffer
)
;; Simulates vim increment and decrement number
(
define-key
evil-normal-state-map
(
kbd
"C-a C-a"
)
'evil-numbers/inc-at-pt
)
(
define-key
evil-normal-state-map
(
kbd
"C-x C-x"
)
'evil-numbers/dec-at-pt
)
)
;; Do not write anything past this comment. This is where Emacs will
;; auto-generate custom variable definitions.
layers/dired/config.el
0 → 100644
View file @
598b6ae1
;; helpers
(
defun
ulys/dired-open-current-dir
()
(
interactive
)
(
spacemacs/dired
"."
))
(
spacemacs/set-leader-keys
"ad"
'ulys/dired-open-current-dir
)
(
with-eval-after-load
'evil-core
)
;; Auto-refresh dired on file change
(
add-hook
'dired-mode-hook
'auto-revert-mode
)
;; (hide .~undo-tree~ files)
(
setq
dired-omit-verbose
nil
)
(
add-hook
'dired-mode-hook
(
lambda
()
(
dired-omit-mode
)))
layers/dired/keybindings.el
0 → 100644
View file @
598b6ae1
(
spacemacs/set-leader-keys
"ad"
'ulys/dired-open-current-dir
)
;; I prefer C-h to kill buffer
;; (evil-define-key '(normal) dired-mode-map (kbd "C-h") 'dired-up-directory)
(
evil-define-key
'
(
normal
)
dired-mode-map
(
kbd
"C-j"
)
'evil-next-line
)
(
evil-define-key
'
(
normal
)
dired-mode-map
(
kbd
"C-k"
)
'evil-previous-line
)
(
evil-define-key
'
(
normal
)
dired-mode-map
(
kbd
"C-l"
)
'dired-find-alternate-file
)
layers/general/config.el
0 → 100644
View file @
598b6ae1
(
setq
undo-tree-auto-save-history
t
)
(
setq
vc-follow-symlinks
t
)
;; To edit .spacemacs without to be prompted each time
(
setq
hybrid-style-enable-hjkl-bindings
t
)
;; add time in powerline
(
display-time-mode
1
)
;; New frame will open fullscreen
(
add-to-list
'default-frame-alist
'
(
fullscreen
.
fullboth
))
;; Org config
(
setq
org-src-window-setup
'current-window
)
(
setq
org-list-allow-alphabetical
t
)
(
setq
org-hide-emphasis-markers
t
)
(
require
'org-tempo
)
;; (ulys/config/org-babel)
;; (ulys/config/org-calendar)
;; (ulys/config/org-minted)
;; (ulys/config/org-odt-export-latexml)
;; (ulys/config/org-capture)
;; (ulys/config/org-file-apps)
(
defun
ulys/org-insert-csv-as-table
(
filename
)
"Insert a csv file into the current buffer at point, and convert it to an org table."
(
interactive
(
list
(
ido-read-file-name
"csv file: "
)))
(
let*
((
start
(
point
))
(
end
(
+
start
(
nth
1
(
insert-file-contents
filename
)))))
(
org-table-convert-region
start
end
)))
(
defun
ulys/config/org-capture
()
(
setq
org-default-notes-file
"~/Nextcloud/org/tasks.org"
)
(
setq
org-capture-templates
'
((
"t"
"Thesis-related Task"
entry
(
file
"~/Nextcloud/org/thesis.org"
)
"** TODO %?"
:empty-lines
1
)
(
"u"
"Teaching-related Task"
entry
(
file
"~/Nextcloud/org/teaching.org"
)
"** TODO %?"
:empty-lines
1
)
(
"h"
"Hospital-related Task"
entry
(
file
"~/Nextcloud/org/hospital.org"
)
"** TODO %?"
:empty-lines
1
))))
(
defun
ulys/config/org-file-apps
()
(
defun
ulys/org-pdf-app
(
file-path
link-without-schema
)
"Open pdf file using pdf-tools and go to the specified page."
(
let*
((
page
(
if
(
not
(
string-match
"\\.pdf::\\([0-9]+\\)\\'"
link-without-schema
))
1
(
string-to-number
(
match-string
1
link-without-schema
)))))
(
find-file-other-window
file-path
)
(
pdf-view-goto-page
page
)))
(
setq
org-file-apps
'
((
auto-mode
.
emacs
)
(
"\\.x?html?\\'"
.
"firefox %s"
)
(
"\\.pdf\\(::[0-9]+\\)?\\'"
.
whatacold/org-pdf-app
)
(
"\\.gif\\'"
.
"eog \"%s\""
)
(
"\\.mp4\\'"
.
"vlc \"%s\""
)
(
"\\.mkv"
.
"vlc \"%s\""
))))
(
defun
ulys/config/org-calendar
()
(
setq
calendar-week-start-day
1
))
(
defun
ulys/config/org-babel
()
(
custom-set-variables
'
(
org-babel-load-languages
(
quote
((
emacs-lisp
.
t
)
(
R
.
t
)
(
latex
.
t
)
(
shell
.
t
)
(
ditaa
.
t
)
(
julia
.
t
)
(
python
.
t
)
(
sql
.
t
))))
'
(
org-confirm-babel-evaluate
nil
)))
(
defun
ulys/org//capture-helper-capture-with-yank-method
(
method
arg
)
;; helper 1/2
(
defun
wrap-into-results-example
(
capture
)
(
concat
"#+RESULTS:\n"
"#+ATTR_LATEX: :options frame=lines\n"
"#+BEGIN_SRC R :eval no :tangle no\n"
capture
"\n#+END_SRC\n"
))
;; helper 2/2
(
defun
choose-process
(
arg
)
(
if
(
or
arg
;; user asks for selection
(
not
(
boundp
'R-process-target
))
;; target not set
;; or target is not set to an active process:
(
not
(
process-live-p
(
get-buffer-process
R-process-target
))))
(
setq
R-process-target
(
completing-read
"Choose R process: "
(
seq-map
(
lambda
(
el
)
(
buffer-name
(
process-buffer
el
)))
(
process-list
))))))
;; main
(
choose-process
arg
)
(
insert
(
wrap-into-results-example
(
funcall
method
R-process-target
))))
(
defun
ulys/org/tibble-capture
(
arg
)
"Let the user choose a R process, then kill last tibble output
in the process and insert it in current buffer in a org
#+RESULTS: format."
(
interactive
"P"
)
;; helper 1/3
(
defun
extract-nrows-from-tibble-first-line
(
line
)
"Extract the number N in the pattern: # A tibble N x M"
(
let*
((
line-without-commas
(
replace-regexp-in-string
","
""
line
))
(
x-position
(
string-match
" x"
line-without-commas
))
(
nrow-start-at
(
length
"# A tibble "
)))
(
string-to-number
(
substring
line-without-commas
nrow-start-at
x-position
))))
;; helper 3/3
(
defun
yank-last-tibble-from-buffer
(
buffer
)
(
interactive
)
(
save-current-buffer
(
set-buffer
buffer
)
(
search-backward
"tibble"
)
(
beginning-of-line
)
(
let*
((
tibble-beg
(
point
))
(
nrow
(
extract-nrows-from-tibble-first-line
(
thing-at-point
'line
t
)))
(
tibble-end
(
progn
(
message
"nrow: %d"
nrow
)
(
re-search-forward
(
concat
"^"
(
number-to-string
(
min
10
nrow
))))
(
while
(
search-forward
"#"
nil
t
))
;; t means no error
(
end-of-line
)
(
point
))))
(
buffer-substring
tibble-beg
tibble-end
))))
;; main
(
ulys/org//capture-helper-capture-with-yank-method
'yank-last-tibble-from-buffer
arg
))
(
defun
ulys/org/glimpse-capture
(
arg
)
"Let the user choose a R process, then kill last glimpse output
in the process and insert it in current buffer in a org
#+RESULTS: format."
(
interactive
"P"
)
;; helper 1
(
defun
extract-nb-vars-from-glimpse-second-line
(
line
)
"Extract the number N in the pattern: Variables: N"
(
let
((
nb-vars-start-at
(
length
"Varialbes: "
))
(
nb-vars-end-at
(
length
line
)))