1. Overview
This project is being developed as the successor to vim-iced and, as same as vim-iced, is heavily inspired by CIDER.
The goal of this project is to provide a server program that serves as the foundation for a Clojure development environment and its interface, enabling it to theoretically offer a Clojure development environment to any editor.
Joeun smiled. “Elin, the wild apple that grows in the mountains. What a nice name.”
2. Getting Started
2.1. Requirements
2.2. Installation
This is an example of installation using vim-plug.
Plug 'liquidz/elin'
call dein#add('liquidz/elin')
Elin does not map any keys by default. If you want to use the default key mappings, see Key mappings.
2.3. Quick start
For quick start, you don’t need to create any project! Just open a Clojure file and run the following command.
$ vim foo.clj
# Execute the following command in Vim/Neovim
# :ElinInstantConnect babashka
You will to connect REPL, so let’s execute the next command.
:ElinEval (+ 1 2 3 4 5)
2.3.1. Start in your project
In the example above, we used a simple case with Babashka, but if you already have a Clojure project, you can get started by following the steps below.
First, start the REPL with the following command. Alternatively, you can also start the REPL within the Elin server using the ElinJackIn command.
$ clj -Sdeps '{:deps {nrepl/nrepl {:mvn/version "1.3.0"} cider/cider-nrepl {:mvn/version "0.50.2"}}}' -M -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]" --interactive
Once the REPL is running, connect to the REPL using the ElinConnect command.
3. Evaluation
The evaluation of S-expression is the most important element in REPL driven development.
3.1. Ranges
There are 3 main ranges to evaluation in elin.
-
current expression
-
current list
-
current top list
See the following figure for the concrete ranges.
(defn plus [foo bar]
(+ foo bar)) ; When the cursor is on foo
; <-> Current expression
; <---------> Current list
; <------------------> Current top list
If you enable default key mappings, following key mappings are available.
Feature | Default key mapping |
---|---|
Evaluate current expression |
|
Evaluate current list |
|
Evaluate current top list |
|
3.2. Results
For example, in ElinEvalCurrentTopList, the handler.evaluate/evaluate-current-top-list handler is called, so the following interceptors are executed.
interceptor.evaluate/output-eval-result-to-cmdline will output the evaluated result to command-line. interceptor.evaluate/set-eval-result-to-virtual-text will show the evaluated result as a popup at the end of line. However, the displayed result is only the returned value, so for example, the contents output by println are not displayed.
The contents output to standard output are displayed on the Information buffer.
3.2.1. Yank
interceptor.evaluate/yank-eval-result will yank the evaluated result to numbered registers. Like vim’s behavior, elin shifts the previous result of register 1 into register 2, 2 into 3, and so forth.
4. Completion
Elin provides only omni completion by default.
It is set to omnifunc for clojure
filetype automatically.
Vim has a <C-x><C-o> key mapping for omni completion.
4.1. Auto completion
Auto completion feature is provided as external elin plugins like follows.
Plugin | Description |
---|---|
Completion source for neoclide/coc.nvim |
|
Completion source for hrsh7th/nvim-cmp |
5. Formatting
Elin does not provide a default formatter for now. The reason is that for format checks in CI, external tools such as cljfmt, cljstyle, or clojure-lsp are commonly used, and a formatter that only works within the editor is often unnecessary.
However, if you blocked when saving files in namespaces with large amounts of code due to the formatting entire buffer, you can use the elin-format plugin to format only the current form.
6. Navigation
6.1. Jump to definition
Elin provides the following command to jump to the definition of the symbol under the cursor.
Command | Default key mapping |
---|---|
|
This command supports jumping to:
-
Qualified symbols
-
Local bindings
-
Protocol implementations
6.2. Refer usages
For browsing locations that refers to the symbol under the cursor, the following commannds are useful.
Command | Default key mapping |
---|---|
|
|
|
When only one location is found, the cursor will jump to the location immediately. Otherwise, the locations will be added to the location list.
6.3. Other navigations
6.3.1. Cycle source and test code
You can cycle source file and test file for current namespace.
Command | Default key mapping |
---|---|
|
For example, when you are in foo.core
, ElinCycleSourceAndTest command will open the file which has foo.core-test
namespace.
If there is no corresponding file, elin suggests pseudo file path to create new namespace.
7. Lookup
There are some commands to lookup the documentation of the symbol under the cursor.
Command | Default key mapping | Description |
---|---|---|
|
Lookup docstring |
|
|
Lookup source code |
|
|
Lookup ClojureDocs |
7.1. Lookup results
By default, the results of ElinLookup and ElinShowSource are shown in a popup, and the results of ElinShowClojureDocs are shown in information buffer and temporal buffer.
The result format is defined by configuration file as a mustache format.
Command | Template |
---|---|
8. Namespace
Elin provides the following commands for namespace operations.
Command | Default key mapping | Description |
---|---|---|
|
Evaluate |
|
|
Allow selection of the available namespaces in Selectors, and add the selected one to the |
|
|
Add the missing libspec for the symbol under the cursor to the |
9. Testing
Elin can integrate with clojure.test, and provides following test commands.
Command | Default key mapping | Description |
---|---|---|
|
Run a test under cursor |
|
|
Run a test under cursor with focusing current |
|
|
Run all tests in current namespace |
|
|
Rerun the last tests |
|
|
Rerun the last failed tests |
9.1. Testing results
Elin operates testing results with the following interceptors by default.
Interceptor | Operation |
---|---|
Show results in command line |
|
Record results in Temporal buffer and Information buffer |
|
Set error positions to quickfix |
|
Place signs to the error positions |
9.2. Testing on plain nREPL
Elin will use cider-nrepl's testing feature if it is enabled, but it can provide equivalent test integration even if cider-nrepl is not enabled.
Therefore, when running tests, you don’t need to be concerned about whether cider-nrepl is enabled on the connected nREPL server. You can run tests and view the results using the same keymap.
10. ClojureScript
Elin only supports shadow-cljs for now.
10.1. shadow-cljs
To start CLJS REPL with shadow-cljs, you need following steps.
-
Start to watch
-
$ npx shadow-cljs watch YOUR-BUILD-ID
-
-
Access shadow-cljs’s HTTP server in your browser
-
Connect to the nREPL
-
Execute ElinConnect command to connect to the nREPL.
-
For shadow-cljs, cljs-repl will be started automatically after connection.
-
You don’t need to specify your build ID anymore.
-
11. Skeleton
Elin provides code skeleton when you open new clojure files.
Currently, following extensions are supported.
-
*.clj
-
*.cljs
-
*.cljc
11.1. Skeleton template
Skeleton feature is provided by the interceptor.autocmd/skeleton interceptor, and the template is defined by configuration file as a mustache format.
The default templates are as follows:
File extension | Template |
---|---|
*.clj |
|
*.cljs |
|
*.cljc |
12. Debugging
12.1. Macro
Expanding macro is important for writing/debugging macros. Elin provides following commands.
Command | Default key mapping |
---|---|
|
Expanding results are shown in the Temporal buffer and Information buffer.
12.2. #dbg and #break
Elin supports CIDER’s #dbg
and #break
reader literals.
The easiest way is to put #dbg
to your code, and evaluate it.
(defn fib [n]
#dbg (loop [a 0 b 1 n n]
(if (<= n 0)
a
(recur b (+ a b) (dec n)))))
Once you evaluate (fib 10)
, debugger will launch.
This feature is implemented by the interceptor.debug/process-debugger interceptor.
13. Buffer
13.1. Information buffer
All information on Elin, such as the content of standard output during evaluation and test results, is recorded in this buffer. To show/clear the information buffer, use the following commands.
Command | Default key mapping |
---|---|
ElinToggleInfoBuffer |
|
ElinClearInfoBuffer |
|
13.2. Temporal buffer
This buffer temporarily displays content that is newly recorded in the Information buffer when the Information buffer is not currently visible. It is used, for example, to display test results or macro expansion results.
This buffer automatically closes when the Information buffer is displayed.
14. Configuration
14.1. Vim/Neovim
14.1.1. Key mappings
Elin does not map any keys by default.
If you want to use the default key mappings, set g:elin_enable_default_key_mappings
to true.
let g:elin_enable_default_key_mappings = v:true
Default key mappings use <Leader>
as a prefix.
If you want to change it to <LocalLeader>
, set g:elin_default_key_mapping_leader
.
let g:elin_default_key_mapping_leader = '<LocalLeader>'
14.1.2. Selectors
To choose an item from multiple candidates, Elin uses a selector. The behavior of the selector differs between Vim and Neovim.
Vim
It has its own implementation, and its behavior can be modified through selector plugins.
You can change which selector plugin to use by setting the selector name in g:elin#internal#select#selector
.
" Requires junegunn/fzf.vim
let g:elin#internal#select#selector = 'fzf'
Neovim
Elin uses vim.ui.select().
Therefore, you can use your preferred plugin to modify the behavior of vim.ui.select()
like follows.
14.1.3. Status line
elin#status
function returns the nREPL connection status text, and you can use it in the status line.
let g:lightline = {
\ 'tabline': {
\ 'right': [['filetype', 'bufnum' ], ['elin'] ]
\ },
\ 'component_function': {
\ 'elin': 'elin#status',
\ },
\ }
14.1.4. Integration with other plugins
There are some Plugin that can be used with Elin.
Plugin | Description | URL |
---|---|---|
coc.nvim |
Completion source |
|
nvim-cmp |
Completion source |
|
telescope.nvim |
File selector |
14.2. Server configuration files
All of elin server’s behavior is defined in resources/config.edn, and all of these can be modified through the configuration file.
The configuration files are loaded in the following order. Settings loaded later take precedence.
-
Plugin configuration
-
User configuration
-
$XDG_CONFIG_HOME/elin/config.edn
-
$HOME/.config/elin/config.edn
-
-
Project local configuration
-
.elin/config.edn
-
14.3. Server configuration structure
In the configuration file, settings are primarily written on a per-component basis.
{;; Log settings
:log { ... }
;; HTTP server component settings
:http-server { ... }
;; Interceptor component settings
:interceptor { ... }
;; Handler component settings
:handler { ... }
;; Clj-kondo component settings
:clj-kondo { ... }}
14.3.1. Handler and Interceptor
As a user, you will configure mainly Handler and Interceptor, which are the core components of Elin. Both are configured using four keys: includes, excludes, config-map, or uses.
includes
:includes
enables the specified handlers/interceptors.
{:handler {:includes [elin.handler.connect/connect]}}
excludes
:excludes
disables handlers/interceptors that were enabled by previously loaded settings.
If both :includes
and :excludes
are specified within the same configuration, :includes
should be prioritized.
{:handler {:excludes [elin.handler.connect/connect]}}
config-map
:config-map
specifies the settings related to handlers/interceptors.
{:handler {:config-map {elin.handler.connect/connect {:param "value"}}}}
In the case of handlers, you can specify interceptors that are only active when the handler is being processed.
{:handler {:config-map {elin.handler.connect/connect {:interceptor {:includes [dummy/interceptor]}}}}}
uses
:uses
is syntactic sugar for :includes
and :config-map
, and the following two are equivalent.
{:uses [foo {:bar "baz"}]}
{:includes [foo]
:config-map {foo {:bar "baz"}}}
14.4. Overriding default behaviors
As explained in Server configuration files, the default settings can be overridden by user or project-local configurations.
14.4.1. Overriding config-map
Let’s focus on the feature that displays evaluation results as virtual text.
By default, the highlight setting for results displayed as virtual text is DiffText
, so you can override this configuration with your preferred highlight setting.
First, you need to investigate how this feature is configured.
By tracing the handler from ElinEvalCurrentTopList, you will find that handler.evaluate/evaluate-current-top-list handler is called.
In the help section under Using interceptors
, you can see that interceptor.evaluate/set-eval-result-to-virtual-text is set as the interceptor to be executed.
Looking at the help for the interceptor, you’ll discover that you can change the highlight setting using the highlight
key.
Now, following Server configuration files, create a user configuration file and save it with the following content.
This will change the default highlight setting from DiffText
to Title
in interceptor.evaluate/set-eval-result-to-virtual-text.
{:interceptor {:config-map {elin.interceptor.evaluate/set-eval-result-to-virtual-text {:highlight "Title"}}}}
14.4.2. Replacing the interceptor
ElinLookup displays results in a popup by default, but you can change it to append them to the Information buffer instead.
By tracing the handler from ElinLookup, you will find that handler.lookup/lookup handler is called.
In the help section under Using interceptors
, you can see that interceptor.handler/show-result-as-popup is set as the interceptor to be executed.
On the other hand, Built-in Interceptors includes interceptor.handler/append-result-to-info-buffer. Similar to interceptor.handler/show-result-as-popup, this interceptor is executed on calling handlers, so by replacing it, you can change the behavior of ElinLookup.
{:handler {:uses [elin.handler.lookup/lookup
{:interceptor {:excludes [elin.interceptor.handler/show-result-as-popup]
:uses [elin.interceptor.handler/append-result-to-info-buffer
{:show-temporarily? true}]}}]}}
15. Plugin
The plugins are tagged with the elin-clj-plugin
topic on GitHub, so you can view the list from the following link.
15.1. Your plugin
For Vim/Neovim, it searches for elin/plugin.edn
in the runtime path and handle the directory containing the plugin.edn
file as a plugin.
{:name "YOUR PLUGIN NAME"
;; OPTIONAL: Your plugin configuration
:export {:handler { ... }
:interceptor { ... }}}
The Elin server adds to the classpath the directory containing plugin.edn
and applies the configurations defined under the :export
key in plugin.edn
.
If :export
is not defined, the Elin server only adds the directory to the classpath and takes no further action.
For the actual processing, please refer to the code for handlers/interceptors in the Elin core or existing plugins.
16. Handlers
Handlers process requests from the host editor.
16.1. Built-in Handlers
16.1.1. handler.callback/callback
No document.
16.1.2. handler.complete/complete
Returns comletion candidates.
16.1.3. handler.connect/connect
Connect to nREPL server.
Default key mapping: <Leader>'
16.1.4. handler.connect/disconnect
Disconnect from nREPL server.
16.1.5. handler.connect/instant
Launch nREPL server of the specified project and connect to it.
16.1.6. handler.connect/jack-in
Launch nREPL server according to the project detected from the current file and connect to it.
Default key mapping: <Leader>"
16.1.7. handler.connect/switch
Switch the current nREPL connection to another connected one.
16.1.8. handler.debug/disable-debug-log
No document.
16.1.9. handler.debug/enable-debug-log
No document.
16.1.10. handler.debug/nrepl-request
Request any message to nREPL server. This handler is for debugging.
16.1.11. handler.evaluate/evaluate
Evaluate specified code.
Using interceptors
16.1.12. handler.evaluate/evaluate-at-mark
Evaluate top list at mark.
Default key mapping: <Leader>ea
16.1.13. handler.evaluate/evaluate-current-buffer
Evaluate current buffer.
Default key mapping: <Leader>eb
Using interceptors
16.1.14. handler.evaluate/evaluate-current-expr
Evaluate current expression.
Default key mapping: <Leader>ei
16.1.15. handler.evaluate/evaluate-current-list
Evaludate current list.
Default key mapping: <Leader>ee
16.1.16. handler.evaluate/evaluate-current-top-list
Evaludate current top list.
Default key mapping: <Leader>et
16.1.17. handler.evaluate/evaluate-namespace-form
Evaluate ns form in current buffer.
Default key mapping: <Leader>en
Using interceptors
16.1.18. handler.evaluate/expand-1-current-list
Expand macro once.
Default key mapping: <Leader>em
Using interceptors
16.1.19. handler.evaluate/interrupt
Interrupt running evaluation.
Default key mapping: <Leader>eq
Using interceptors
16.1.20. handler.evaluate/print-last-result
Print last evaluation result to InfoBuffer.
Default key mapping: <Leader>ep
16.1.21. handler.evaluate/reload
Reload all changed files with tonsky/clj-reload.
Default key mapping: <Leader>enr
Using interceptors
16.1.22. handler.evaluate/reload-all
Reload all files.
Default key mapping: <Leader>enR
Using interceptors
16.1.23. handler.evaluate/undef
Undefine symbol at cursor position.
Default key mapping: <Leader>eu
Using interceptors
16.1.24. handler.evaluate/undef-all
Undefine all symbols in current namespace.
Default key mapping: <Leader>eU
Using interceptors
16.1.25. handler.lookup/lookup
Look up symbol at cursor position.
Default key mapping: K
Using interceptors
16.1.26. handler.lookup/show-clojuredocs
Show clojuredocs of symbol at cursor position.
Default key mapping: <Leader>hc
Using interceptors
16.1.27. handler.lookup/show-source
Show source code of symbol at cursor position.
Default key mapping: <Leader>hs
Using interceptors
16.1.28. handler.namespace/add-libspec
Add libspec to namespace form.
Default key mapping: <Leader>ran
Using interceptors
16.1.29. handler.namespace/add-missing-libspec
Add missing libspec to namespace form.
Default key mapping: <Leader>ram
Using interceptors
16.1.30. handler.navigate/cycle-source-and-test
Cycle source code and test code.
Default key mapping: tt
Using interceptors
16.1.31. handler.navigate/jump-to-definition
Jump to the definition of the symbol under the cursor.
Default key mapping: <C-]>
Using interceptors
16.1.32. handler.navigate/local-references
No document.
Default key mapping: <Leader>blr
Using interceptors
16.1.33. handler.navigate/references
Find the places where the symbol under the cursor is used, and jump if there is only one. If there are multiple, add them to the location list.
Default key mapping: <Leader>br
Using interceptors
16.1.34. handler.test/rerun-last-failed-tests
Rerun last failed tests.
Default key mapping: <Leader>tr
16.1.35. handler.test/rerun-last-tests
Rerun last tests.
Default key mapping: <Leader>tl
16.1.36. handler.test/run-test-under-cursor
Run test under cursor.
Default key mapping: <Leader>tt
16.1.37. handler.test/run-tests-in-ns
Run test in current namespace.
Default key mapping: <Leader>tn
17. Interceptors
Interceptors intercept various processes and change their behavior.
17.1. Built-in Interceptors
17.1.1. interceptor.autocmd/clj-kondo-analyzing
Executed on autocmd fired.
No document.
17.1.2. interceptor.autocmd/deinitialize
Executed on autocmd fired.
No document.
17.1.3. interceptor.autocmd/ns-load
Executed on autocmd fired.
No document.
17.1.4. interceptor.autocmd/skeleton
Executed on autocmd fired.
Set skeleton to current new buffer.
Variable | Description |
---|---|
|
File path |
|
Inferred namespace |
|
Source file namespace (only available on test file ) |
|
|
17.1.5. interceptor.autocmd/switch-connection
Executed on autocmd fired.
No document.
17.1.6. interceptor.code-change/show-code-changed-result
Executed on changing code.
No document.
17.1.7. interceptor.connect/cleanup-jacked-in-process
Executed on disconnection.
No document.
17.1.8. interceptor.connect/connected
Executed on connection.
No document.
17.1.9. interceptor.connect/detect-clojure-port
Executed on connection.
No document.
17.1.10. interceptor.connect/raw-message-channel
Executed on connection.
No document.
17.1.11. interceptor.connect.shadow-cljs/detect-shadow-cljs-port
Executed on connection.
No document.
17.1.12. interceptor.debug/initialize-debugger
Executed on connection.
No document.
17.1.13. interceptor.debug/process-debugger
Executed on communicating with nREPL server.
No document.
17.1.14. interceptor.evaluate/eval-with-context
Executed on evaluation.
No document.
17.1.15. interceptor.evaluate/output-eval-result-to-cmdline
Executed on evaluation.
Output evaluated result to cmdline.
17.1.16. interceptor.evaluate/set-eval-result-to-virtual-text
Executed on evaluation.
Set evaluated result to virtual text.
key | type | description |
---|---|---|
format |
string |
Format of virtual text. It can contain the following placeholders: |
highlight |
string |
Highlight group for virtual text. |
align |
string |
Alignment of virtual text. Possible values are: |
close-after |
integer |
Close virtual text after the specified number of milliseconds. |
17.1.17. interceptor.evaluate/unwrap-comment-form
Executed on evaluation.
No document.
17.1.18. interceptor.evaluate/yank-eval-result
Executed on evaluation.
Yank evaluated result.
17.1.19. interceptor.handler/append-result-to-info-buffer
Executed on calling handler.
Interceptor to show handler result temporarily.
17.1.20. interceptor.handler/handling-error
Executed on calling handler.
No document.
17.1.21. interceptor.handler/jump-to-file
Executed on calling handler.
Interceptor to jump to specified file.
17.1.22. interceptor.handler/show-result-as-popup
Executed on calling handler.
Interceptor to show handler result as popup.
17.1.23. interceptor.nrepl/eval-ns
Executed on requesting to nREPL server.
Interceptor to delete ns keyword from nREPL request on evaluating ns form.
17.1.24. interceptor.nrepl/normalize-path
Executed on requesting to nREPL server.
Interceptor to normalize path on nREPL response.
17.1.25. interceptor.nrepl/nrepl-output
Executed on communicating with nREPL server.
Interceptor to intercept nREPL output. This interceptor executes interceptors with e.c.interceptor/output kind.
17.1.26. interceptor.nrepl/output-result-to-cmdline
Executed on requesting to nREPL server.
Interceptor to output nREPL result as message.
17.1.27. interceptor.nrepl/progress
Executed on requesting to nREPL server.
Interceptor to show progress popup on nREPL request.
17.1.28. interceptor.output/print-output
Executed on output from nREPL server.
Interceptor to print output on nREPL to InfoBuffer.
Output format can be configured like below:
{:interceptor {:config-map {elin.interceptor.output/print-output
{:format "{{text}}"}}}}
Available variables: - type: Output type - text: Output text
17.1.29. interceptor.test/append-test-result-to-info-buffer
No document.
17.1.30. interceptor.test/apply-test-result-to-quickfix
No document.
17.1.31. interceptor.test/focus-current-testing
Executed on testing.
Re evaluate the current top list with focusing on the current testing form.
17.1.32. interceptor.test/output-test-result-to-cmdline
No document.
17.1.33. interceptor.test/parse-test-result
Executed on testing.
No document.
17.1.34. interceptor.test/store-last-failed-test-query
No document.
17.1.35. interceptor.test/update-test-result-sign
No document.
18. Host
18.1. Vim/Neovim
18.1.1. Commands
ElinConnect
Calls handler.connect/connect handler.
ElinInstantConnect
Calls handler.connect/instant handler.
ElinDisconnect
Calls handler.connect/disconnect handler.
ElinJackIn
Calls handler.connect/jack-in handler.
ElinSwitchConnection
Calls handler.connect/switch handler.
ElinEval
Calls handler.evaluate/evaluate handler.
ElinEvalCurrentExpr
Calls handler.evaluate/evaluate-current-expr handler.
ElinEvalCurrentList
Calls handler.evaluate/evaluate-current-list handler.
ElinEvalCurrentTopList
Calls handler.evaluate/evaluate-current-top-list handler.
ElinEvalCurrentBuffer
Calls handler.evaluate/evaluate-current-buffer handler.
ElinEvalNsForm
Calls handler.evaluate/evaluate-namespace-form handler.
ElinEvalAtMark
Calls handler.evaluate/evaluate-at-mark handler.
ElinEvalInContext
Calls handler.evaluate/evaluate-current-list handler with the following interceptors:
ElinPrintLastResult
Calls handler.evaluate/print-last-result handler.
ElinInterrupt
Calls handler.evaluate/interrupt handler.
ElinUndef
Calls handler.evaluate/undef handler.
ElinUndefAll
Calls handler.evaluate/undef-all handler.
ElinReload
Calls handler.evaluate/reload handler.
ElinReloadAll
Calls handler.evaluate/reload-all handler.
ElinMacroExpand1CurrentList
Calls handler.evaluate/expand-1-current-list handler.
ElinAddLibspec
Calls handler.namespace/add-libspec handler.
ElinAddMissingLibspec
Calls handler.namespace/add-missing-libspec handler.
ElinJumpToDefinition
Calls handler.navigate/jump-to-definition handler.
ElinReferences
Calls handler.navigate/references handler.
ElinLocalReferences
Calls handler.navigate/local-references handler.
ElinLookup
Calls handler.lookup/lookup handler.
ElinShowSource
Calls handler.lookup/show-source handler.
ElinShowClojureDocs
Calls handler.lookup/show-clojuredocs handler.
ElinTestUnderCursor
Calls handler.test/run-test-under-cursor handler.
ElinTestFocusedCurrentTesting
Calls handler.test/run-test-under-cursor handler with the following interceptors:
ElinTestInNs
Calls handler.test/run-tests-in-ns handler.
ElinTestLast
Calls handler.test/rerun-last-tests handler.
ElinTestLastFailed
Calls handler.test/rerun-last-failed-tests handler.
ElinCycleSourceAndTest
Calls handler.navigate/cycle-source-and-test handler.
ElinEnableDebugLog
Calls handler.debug/enable-debug-log handler.
ElinDisableDebugLog
Calls handler.debug/disable-debug-log handler.
19. Cheatsheet
Based on default key mappings. |
Connection
|
|
|
||||||||||||||||||||
|
|
|
||||||||||||||||||||
Others
|