Published 2022-02-20.
Last modified 2024-02-21.
Time to read: 8 minutes.
ruby
collection.
For best results, install virtualized Ruby using rbenv
before
attempting to follow these instructions.
In mid-July 2023, Ruby LSP became the official Ruby plugin for Ruby development with Visual Studio Code. This is the GitHub project. The Ruby LSP documentation can be difficult to find.
Remove Old Ruby Extensions
Previously popular Visual Studio Code extensions for working with Ruby do not coexist with Ruby LSP. Remove them:
Installing Debug Support
Debugging Components
A diagram should help us understand how the different components of a Ruby debugging extension work for Visual Studio Code. I added Ruby components to a diagram provided in Introducing Logpoints and auto-attach from the Visual Studio Code documentation. Various implementations of debug adapters are listed here; we will use the VSCode rdbg Ruby Debugger.
You can see several components in the above diagram:
- The Ruby LSP Visual Studio Code plugin, which provides debugging, lint, semantic highlighting, and Intellisense support for Ruby. (The diagram just lumps this plugin with the Debugger UI).
- The
vscode-rdbg
gem, which uses the debug adaptor protocol to communicate between Visual Studio and thedebug
gem, which provides therdbg
debugger for Ruby. - The Ruby runtime.
Command-Line Debugger
Command-line debug support for Ruby is provided by the
debug
Ruby gem.
This gem installs the rdbg
command.
Debug
must be installed separately before the Visual Studio Code extension can debug Ruby code:
$ gem install debug Building native extensions. This could take a while... Successfully installed debug-1.8.0 Parsing documentation for debug-1.8.0 Done installing documentation for debug after 1 seconds 1 gem installed
Verify you have at least version 1.8.0:
$ gem info debug
*** LOCAL GEMS ***
debug (1.8.0, 1.7.1, 1.6.1, 1.5.0, 1.4.0) Author: Koichi Sasada Homepage: https://github.com/ruby/debug Licenses: Ruby, BSD-2-Clause Installed at (1.8.0): /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0 (1.7.1): /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0 (1.6.1): /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0 (1.5.0): /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0 (1.4.0): /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0
Debugging functionality for Ruby
Ensure that the rdbg
command that the debug
gem provides is on the PATH
:
$ which rdbg /home/mslinn/.rbenv/shims/rdbg
Help message:
$ rdbg -h rdbg [options] -- [debuggee options]
Debug console mode: -n, --nonstop Do not stop at the beginning of the script. -e DEBUG_COMMAND Execute debug command at the beginning of the script. -x, --init-script=FILE Execute debug command in the FILE. --no-rc Ignore ~/.rdbgrc --no-color Disable colorize --no-sigint-hook Disable to trap SIGINT -c, --command Enable command mode. The first argument should be a command name in $PATH. Example: 'rdbg -c bundle exec rake test'
-O, --open=[FRONTEND] Start remote debugging with opening the network port. If TCP/IP options are not given, a UNIX domain socket will be used. If FRONTEND is given, prepare for the FRONTEND. Now rdbg, vscode and chrome is supported. --sock-path=SOCK_PATH UNIX Domain socket path --port=PORT Listening TCP/IP port --host=HOST Listening TCP/IP host --cookie=COOKIE Set a cookie for connection
Debug console mode runs Ruby program with the debug console.
'rdbg target.rb foo bar' starts like 'ruby target.rb foo bar'. 'rdbg -- -r foo -e bar' starts like 'ruby -r foo -e bar'. 'rdbg -c rake test' starts like 'rake test'. 'rdbg -c -- rake test -t' starts like 'rake test -t'. 'rdbg -c bundle exec rake test' starts like 'bundle exec rake test'. 'rdbg -O target.rb foo bar' starts and accepts attaching with UNIX domain socket. 'rdbg -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234. 'rdbg -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234. 'rdbg target.rb -O chrome --port 1234' starts and accepts connecting from Chrome Devtools with localhost:1234.
Attach mode: -A, --attach Attach to debuggee process.
Attach mode attaches the remote debug console to the debuggee process.
'rdbg -A' tries to connect via UNIX domain socket. If there are multiple processes are waiting for the debugger connection, list possible debuggee names. 'rdbg -A path' tries to connect via UNIX domain socket with given path name. 'rdbg -A port' tries to connect to localhost:port via TCP/IP. 'rdbg -A host port' tries to connect to host:port via TCP/IP.
Other options: -v Show version number --version Show version number and exit -h, --help Print help --util=NAME Utility mode (used by tools) --stop-at-load Stop immediately when the debugging feature is loaded.
NOTE All messages communicated between a debugger and a debuggee are *NOT* encrypted. Please use the remote debugging feature carefully.
Visual Studio vscode-rdbg Extension
You also need to install the Visual Studio RDBG extension.
There is also an old extension called Ruby Debug, by Castwide. DO NOT INSTALL IT! REMOVE IT IF PRESENT. This old extension is easily confused with the VSCode extension you should install, VSCode rdbg Ruby Debugger by Koichi Sasada.
Rdbg v0.1.0 Works Better than v2.1.0
One of my computers will NOT run Koichi Sasada’s extension. Other computers work fine. I have no idea why. It seems other people have had this problem as well. The little blue spinner below the run button would never stop, and I would have to exit VSCode before trying again. I spent hours trying to get the blessed thing to work. Finally, I downgraded from v0.2.1, to v0.2.0, and finally to v0.1.0, and that version worked.
This is how to download and install v0.1.0 of Koichi Sasada’s extension:
- Open the Extensions view in the Visual Studio Code primary sidebar.
-
Find the extension that you installed called VSCode rdbg Ruby Debugger.
-
Hover over the extension panel and an information panel will appear to the right,
showing the currently installed version and the latest available version.
The above shows that v0.1.0 is installed, and v0.2.1 is available. This is actually the version you want installed, so if you see this there is no need to continue. However, if a different version is installed, please continue. -
Right-click on the extension and
select Install Another Version... from the menu that appears.
-
The Visual Studio Code Activity Bar will now show you all available versions of the extension.
Select version 0.1.0.
Because Visual Studio Code auto-updates all extensions by default, Ruby debugging may suddenly cease to work without warning. Read on to learn how to fix that.
Before Visual Studio Code v1.85.0, released on October 8, 2023, you could only
enable or suppress the auto-updating of all extensions.
This is accomplished by bringing up the control palette
(CTRL-Shift-P) and then typing Extensions: Disable Auto Updating Extensions.
You can update any of the other plugins manually; doing so will not cause rdbg
to be updated.
Visual Studio Code v1.85.0 introduced extension auto update control. Instead of using the Visual Studio Code control palette, the More actions icon of the Extensions tab can be used to display the Auto Update Extensions menu. The icon looks like three dots, as shown in the image below. I have numbered where you need to click, in order, to selectively enable extension auto-update.
Unfortunately, the control is the opposite of what we need and necessitates that you manually enable updates for dozens of extensions. I submitted an enhancement request. The following is an explanation of how to use the feature as it currently exists.
Using the control palette as described above to disable extension auto-update causes the
Auto Update Extensions menu to be set to None.
You want it to be set to Selected Extensions instead,
then you can selectively enable extensions to auto-update by right-clicking on an extension and either selecting
Auto Update or Auto Update All (From Publisher).
Do this for all extensions except rdbg
.
You can also enable auto-update for the currently displayed extension:
Recommended Extensions
VS Code prompts a user to install the recommended extensions when a workspace is opened for the first time.
The user can also review the list with the Extensions: Show Recommended Extensions command.
Define the recommended extensions by storing the following into your projects’s .vscode/extensions.json
:
{
// See https://go.microsoft.com/fwlink/?LinkId=827846
to learn about workspace recommendations.
// List of recommended extensions for this workspace.
"recommendations": [
"DavidAnson.vscode-markdownlint",
"devonray.snippet",
"groksrc.ruby",
"KoichiSasada.vscode-rdbg",
"hoovercj.ruby-linter",
"miguel-savignano.ruby-symbols",
"misogi.ruby-rubocop",
"neilding.language-liquid",
"redhat.vscode-yaml",
"shd101wyy.markdown-preview-enhanced",
"Shopify.ruby-extensions-pack",
"Shopify.ruby-lsp",
"sissel.shopify-liquid",
"timonwong.shellcheck",
"vayan.haml",
"vortizhe.simple-ruby-erb",
],
// List of extensions that should be removed.
"unwantedRecommendations": [
"castwide.solargraph",
"rebornix.Ruby",
"wingrunr21.vscode-ruby",
]
}
Settings
User Settings
User settings for Visual Studio Code are stored in a file called settings.json
.
The paths for that file differ for each OS that Visual Studio Code runs on.
Windows: %AppData%\
Linux: $HOME/.config/Code/User/settings.json
The following are the Ruby-specific settings that I use:
{ "[ruby]": { "editor.defaultFormatter": "Shopify.ruby-lsp", "editor.formatOnSave": true, "editor.formatOnType": true, "editor.tabSize": 2, "editor.insertSpaces": true, "editor.semanticHighlighting.enabled": true }, "debug.console.fontSize": 18, "debug.onTaskErrors": "abort", "debug.terminal.clearBeforeReusing": true, "ruby.rubocop.executePath": "/home/mslinn/.rbenv/shims/", "ruby.rubocop.useBundler": true, "rubyLsp.enableExperimentalFeatures": true, "rubyLsp.enabledFeatures": { "codeActions": true, "diagnostics": true, "documentHighlights": true, "documentLink": true, "documentSymbols": true, "foldingRanges": true, "formatting": true, "hover": true, "inlayHint": true, "onTypeFormatting": true, "selectionRanges": true, "semanticHighlighting": true, "completion": true, "codeLens": true, "definition": true, "workspaceSymbol": true }, "rubyLsp.formatter": "auto", "rubyLsp.rubyVersionManager": "rbenv", "telemetry.telemetryLevel": "off", }
WSL Settings
WSL settings override user settings. They are stored in
$HOME/
.
If adjusting user settings does not change behavior, examine WSL settings for a conflict.
Debugging
The ruby_lsp
type of launch configuration
uses rdbg
, and it does that by
launching a shell, which is slow.
So anything you can do with the ruby_lsp
launch type can also be done with the rdbg
launch type,
and using the rdbg
launch type will be faster.
The ruby_lsp
launch type is simpler to use than the rdbg
launch type,
but is less flexible and slower.
I prefer to debug Ruby programs by directly using rdbg
instead of ruby_lsp
, but
the rdbg
documentation is poorly written, contains unmentioned assumptions, and contains errors.
The next few sections contain a heavily edited version of the published documentation for the Visual Studio Code
rdbg
launch.json
options.
Debuggee Launch Configuration Settings
Automatically created launch configuration settings for rdbg
do not work on WSL/Ubuntu.
Read on to learn what is needed; I highlighted the most important points.
Definition: the debuggee is just the program to be debugged.
script
- The file name of the script to run. Default: the name of the active Ruby file in Visual Studio Code.
command
-
An executable Ruby command.
For example, you can specify
~/
. Default:.rbenv/ shims/ ruby ruby
(which is found along thePATH
). cwd
-
Directory to execute the program in.
Default:
${workspaceFolder}
args
-
The command line arguments passed to the program, as an array of strings.
Default:
[]
env
-
Additional environment variables to pass to the debugging (and debugged) process.
Default:
[]
useBundler
-
Invoke Ruby programs with
bundle exec
. The default value for this option istrue
if a file calledGemfile
is present in the directory tree where the script to execute resides; otherwise, the default value isfalse
.
Behavior settings
askParameters
-
Causes the user to be prompted for the entire command line before debugging. The response is remembered and offered as the value for the next launch. If the command line is always the same, use the other options to specify the command line instead of using this option.
For example, given the first launch configuration (
EXPERIMENT
) in the next section below and with the knowledge that the target directory contains a file calledGemfile
, the value offered to the user is:bundle exec ruby /mslinn.com/
blog/ bin/ gitUrls.rb $sitesUbuntu rdbgPath
-
Full path of the
rdbg
executable. Default: use thePATH
to locaterdbg
. debugPort
-
This option specifies how to communicate with the debuggee.
The default for most OSes is to open a UNIX Domain Socket, except for Windows, which defaults to opening a TCP/IP socket atlocalhost:0
. If the option is specified as a numeric string (e.g., "12345"), then a TCP/IP debug port onlocalhost
is opened with that value. If the option is specified ashostname:port
(e.g.,"hostname:12345"
), then a TCP/IP port on the specified remote host is opened using the given port.
You can specify that an unused port should be automatically chosen if the value of this option is set to"0"
; this requires v1.5.0+ of thedebug
gem. Version 1.5.0 was released on March 30, 2022, so you probably have a newer version. I have found that setting this value to"0"
is the most reliable option when debugging onlocalhost
, and that this option must be specified when running on WSL/Ubuntu. waitLaunchTime
-
This option is not required when using
debug
gem v1.5.0+. Opening a TCP/IP debug port requires a short delay for the operation to complete before the port can be used. By default, a 5000-millisecond (5 second) delay is used. useTerminal
-
If your program needs to read from
STDIN
, set this option. By default, all outputs toSTDIN
andSTDOUT
are shown in the debug console. This option creates a new terminal for executing the debug command. The creation process takes extra time. showProtocolLog
-
This option causes all DAP communication to be displayed.
Default:
false
Enable this option to debug your launch configuration.
When I use this option under WSL/Ubuntu, I see the following message on each launch. The message does not appear to be important; just ignore it:
bash: initialize_job_control: no job control in background: Bad file descriptor
Example Launch Configurations
{ "version": "0.2.0", "configurations": [ { "args": [ "$sitesUbuntu" ], "debugPort": "0", "name": "EXPERIMENT", "request": "launch", "script": "${workspaceRoot}/blog/bin/gitUrls.rb", "showProtocolLog": true, "type": "rdbg", }, { "debugPort": "0", "name": "Debug abc.rb with rdbg", "request": "launch", "script": "${workspaceRoot}lib/abc.rb", "type": "rdbg", }, { "debugPort": "0", "name": "Debug current file with rdbg", "request": "launch", "script": "${file}", "type": "rdbg", }, { "name": "Attach with rdbg", "debugPort": "0", "request": "attach", "type": "rdbg", }, { "args": [], "command": "rake", "debugPort": "0", "name": "Run rake test", "request": "launch", "script": "test", // launch rake test with debugger "type": "rdbg", }, { "args": [ "serve", "--livereload_port", "35721", "--force_polling", "--host", "0.0.0.0", "--port", "4001", "--future", "--incremental", "--livereload", "--drafts", "--unpublished" ], "debugPort": "0", "name": "Debug Jekyll", "request": "launch", "script": "./exe/jekyll", "type": "rdbg", }, ] }
When I use the first launch configuration above, called EXPERIMENT
,
the following appears in the Visual Studio Code output panel because showProtocolLog
is enabled:
"Running: /bin/bash -lic rdbg --command --open --stop-at-load --host=localhost --port=0 -- bundle exec ruby /var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb $sitesUbuntu" bash: initialize_job_control: no job control in background: Bad file descriptor [Start session] {"d":{},"f":"b8cde853-5fbd-4df3-a99f-463a1e68d2fa","g":"rdbg","h":"EXPERIMENT Debug gitUrls.rb with rdbg","i":{"uri":{"$mid":1,"fsPath":"/var/sitesUbuntu/www.mslinn.com","external":"file:///var/sitesUbuntu/www.mslinn.com","path":"/var/sitesUbuntu/www.mslinn.com","scheme":"file"},"name":"www.mslinn.com","index":0},"j":{"args":["$sitesUbuntu"],"debugPort":"0","name":"EXPERIMENT Debug gitUrls.rb with rdbg","request":"launch","script":"/var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb","showProtocolLog":true,"type":"rdbg","__configurationTarget":6,"rdbgExtensions":["traceInspector"],"rdbgInitialScripts":[]}} [VSCode->DA] {"command":"initialize","arguments":{"clientID":"vscode","clientName":"Visual Studio Code","adapterID":"rdbg","pathFormat":"path","linesStartAt1":true,"columnsStartAt1":true,"supportsVariableType":true,"supportsVariablePaging":true,"supportsRunInTerminalRequest":true,"locale":"en","supportsProgressReporting":true,"supportsInvalidatedEvent":true,"supportsMemoryReferences":true,"supportsArgsCanBeInterpretedByShell":true,"supportsMemoryEvent":true,"supportsStartDebuggingRequest":true},"type":"request","seq":1} [DA->VSCode] {"type":"response","command":"initialize","request_seq":1,"success":true,"message":"Success","body":{"supportsConfigurationDoneRequest":true,"supportsFunctionBreakpoints":true,"supportsConditionalBreakpoints":true,"supportTerminateDebuggee":true,"supportsTerminateRequest":true,"exceptionBreakpointFilters":[{"filter":"any","label":"rescue any exception","supportsCondition":true},{"filter":"RuntimeError","label":"rescue RuntimeError","supportsCondition":true}],"supportsExceptionFilterOptions":true,"supportsStepBack":true,"supportsEvaluateForHovers":true,"supportsCompletionsRequest":true},"seq":1} [DA->VSCode] {"type":"event","event":"initialized","seq":2} [DA->VSCode] {"type":"event","event":"output","body":{"category":"console","output":"Ruby REPL: You can run any Ruby expression here.\nNote that output to the STDOUT/ERR printed on the TERMINAL.\n[experimental]\n `,COMMAND` runs `COMMAND` debug command (ex: `,info`).\n `,help` to list all debug commands.\n"},"seq":3} [VSCode->DA] {"command":"launch","arguments":{"args":["$sitesUbuntu"],"debugPort":"0","name":"EXPERIMENT Debug gitUrls.rb with rdbg","request":"launch","script":"/var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb","showProtocolLog":true,"type":"rdbg","__configurationTarget":6,"rdbgExtensions":["traceInspector"],"rdbgInitialScripts":[],"__sessionId":"b8cde853-5fbd-4df3-a99f-463a1e68d2fa"},"type":"request","seq":2} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"categorized_under.rb","path":"/var/sitesUbuntu/www.mslinn.com/_plugins/categorized_under.rb"},"lines":[34],"breakpoints":[{"line":34}],"sourceModified":false},"type":"request","seq":3} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"configuration.rb","path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/jekyll-4.2.2/lib/jekyll/configuration.rb"},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":4} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"gitUrls.rb","path":"/var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb"},"lines":[46],"breakpoints":[{"line":46}],"sourceModified":false},"type":"request","seq":5} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"jekyll_plugins","path":"/var/sitesUbuntu/www.mslinn.com/blog/bin/jekyll_plugins"},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":6} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"makeAwsBucket","path":"/var/sitesUbuntu/www.mslinn.com/_bin/makeAwsBucket"},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":7} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"outline.rb","path":"/var/sitesUbuntu/www.mslinn.com/_plugins/outline.rb"},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":8} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"run.rb","path":"/var/sitesUbuntu/www.mslinn.com/_plugins/run.rb"},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":9} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"site_inspector.rb","path":"/var/sitesUbuntu/www.mslinn.com/_plugins/site_inspector.rb"},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":10} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"name":"site.rb","path":"/home/mslinn/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/jekyll-4.2.2/lib/jekyll/site.rb"},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":11} [VSCode->DA] {"command":"setFunctionBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":12} [VSCode->DA] {"command":"setExceptionBreakpoints","arguments":{"filters":[],"filterOptions":[]},"type":"request","seq":13} [DA->VSCode] {"type":"response","command":"launch","request_seq":2,"success":true,"message":"Success","seq":4} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":3,"success":true,"message":"Success","body":{"breakpoints":[{"verified":true}]},"seq":5} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":4,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":6} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":5,"success":true,"message":"Success","body":{"breakpoints":[{"verified":true}]},"seq":7} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":6,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":8} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":7,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":9} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":8,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":10} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":9,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":11} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":10,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":12} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":11,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":13} [DA->VSCode] {"type":"response","command":"setFunctionBreakpoints","request_seq":12,"success":true,"message":"Success","seq":14} [DA->VSCode] {"type":"response","command":"setExceptionBreakpoints","request_seq":13,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":15} [VSCode->DA] {"command":"evaluate","arguments":{"expression":",eval $stdout.sync=true","context":"repl"},"type":"request","seq":14} [DA->VSCode] {"type":"response","command":"evaluate","request_seq":14,"success":true,"message":"Success","body":{"result":"(rdbg:command) eval $stdout.sync=true","variablesReference":0},"seq":16} [VSCode->DA] {"command":"configurationDone","type":"request","seq":15} [DA->VSCode] {"type":"response","command":"configurationDone","request_seq":15,"success":true,"message":"Success","seq":17} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb"}},"seq":18} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged.rb"}},"seq":19} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/index.rb"}},"seq":20} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/object.rb"}},"seq":21} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/commit.rb"}},"seq":22} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/version.rb"}},"seq":23} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/repository.rb"}},"seq":24} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/reference.rb"}},"seq":25} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/walker.rb"}},"seq":26} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/tree.rb"}},"seq":27} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/tag.rb"}},"seq":28} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/branch.rb"}},"seq":29} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/diff.rb"}},"seq":30} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/diff/hunk.rb"}},"seq":31} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/diff/line.rb"}},"seq":32} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/diff/delta.rb"}},"seq":33} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/patch.rb"}},"seq":34} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/remote.rb"}},"seq":35} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/credentials.rb"}},"seq":36} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/attributes.rb"}},"seq":37} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/blob.rb"}},"seq":38} [DA->VSCode] {"type":"event","event":"loadedSource","body":{"reason":"new","source":{"path":"/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rugged-1.6.3/lib/rugged/submodule_collection.rb"}},"seq":39} [DA->VSCode] {"type":"event","event":"stopped","body":{"reason":"breakpoint","description":" BP - Line /var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb:46 (line)","text":" BP - Line /var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb:46 (line)","threadId":1,"allThreadsStopped":true},"seq":40} [VSCode->DA] {"command":"threads","type":"request","seq":16} [DA->VSCode] {"type":"response","command":"threads","request_seq":16,"success":true,"message":"Success","body":{"threads":[{"id":1,"name":"#1 /var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb:46:in `'"}]},"seq":41} [VSCode->DA] {"command":"threads","type":"request","seq":17} [DA->VSCode] {"type":"response","command":"threads","request_seq":17,"success":true,"message":"Success","body":{"threads":[{"id":1,"name":"#1 /var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb:46:in ` '"}]},"seq":42} [VSCode->DA] {"command":"stackTrace","arguments":{"threadId":1,"startFrame":0,"levels":20},"type":"request","seq":18} [DA->VSCode] {"type":"response","command":"stackTrace","request_seq":18,"success":true,"message":"Success","body":{"stackFrames":[{"id":1,"name":" ","line":46,"column":1,"source":{"name":"gitUrls.rb","path":"/var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb","sourceReference":0}}],"totalFrames":1},"seq":43} [VSCode->DA] {"command":"setBreakpoints","arguments":{"source":{"path":"/var/sitesUbuntu/www.mslinn.com/blog/bin/gitUrls.rb","name":"gitUrls.rb","sourceReference":0},"lines":[],"breakpoints":[],"sourceModified":false},"type":"request","seq":19} [DA->VSCode] {"type":"response","command":"setBreakpoints","request_seq":19,"success":true,"message":"Success","body":{"breakpoints":[]},"seq":44} [VSCode->DA] {"command":"continue","arguments":{"threadId":1},"type":"request","seq":20} [DA->VSCode] {"type":"response","command":"continue","request_seq":20,"success":true,"message":"Success","body":{"allThreadsContinued":true},"seq":45} [DA->VSCode] {"type":"event","event":"terminated","seq":46} [Error on session] Error: connection closed e: {} [VSCode->DA] {"command":"disconnect","arguments":{"restart":false,"terminateDebuggee":false},"type":"request","seq":21}
Jekyll Plugins
If you use Visual Studio Code, and you work in Ruby because you maintain a Jekyll website, you might find the following VS Code extensions helpful.
- Liquid provides syntax highlighting, formatting and snippet support for the liquid template language. Supports both Jekyll and Shopify variations.
jekyll-run
VS Code plugin.- Jekyll snippets for Visual Studio Code is a combination of both the sublime-jekyll package by @23maverick23 and the atom-jekyll package by @jasonhodges.
-
jekyll-post
makes it easier to create new articles for Jekyll-based websites using the Visual Studio Code editor. Using this extension, a user can create a new file with pre-filled ‘front matter’. The template for front matter can either be provided by the user, or the extension will use its built-in template.
Debugging an Installed Gem
Sometimes it is helpful to be able to debug an installed gem.
You can discover where a gem is installed by using bundle info --path
and adding the name of the gem.
$ bundle info --path jekyll_plugin_support /home/mslinn/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/jekyll_plugin_support-0.8.3
The installed gem can be loaded into Visual Studio Code
by typing code -a
and providing the path to the gem that you just obtained.
$ code -a /home/mslinn/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/jekyll_plugin_support-0.8.3
Here is a script that performs the above:
#!/usr/bin/env ruby require 'open3' def help progname = File.basename $PROGRAM_NAME printf <<~END_MSG #{progname} - edit installed gem in Visual Studio Code Syntax: #{progname} GEM_NAME END_MSG exit 1 end # @return String array containing resulting lines of running command def run_capture_stdout(command) # printf "Run #{command}\n".yellow stdout_str, status = Open3.capture2 command unless status.success? printf "Error: #{command} returned #{status}" exit status.to_i end stdout_str.strip.split end help if ARGV.empty? help if ARGV.length > 1 gem_path = run_capture_stdout("bundle info --path #{ARGV[0]}").first puts "Editing #{gem_path}" `code -a #{gem_path}`
To cause Visual Studio Code to load the source file containing the entry point for the jekyll_plugin_support
gem used in a project,
type the following from the Ruby project:
$ vsopen jekyll_plugin_support
About the Author
I, Mike Slinn, have been working with Ruby for a long time now. Back in 2005, I was the product marketing manager at CodeGear (the company was formerly known as Borland) for their 3rd Rail IDE. 3rd Rail supported Ruby and Ruby on Rails at launch.
In 2006, I co-chaired the Silicon Valley Ruby Conference on behalf of the SD Forum in Silicon Valley. As you can see, I have the t-shirt. I was the sole chairman of the 2007 Silicon Valley Ruby Conference.
Several court cases have come my way over the years in my capacity as a software expert witness. The court cases featured questions about IP misappropriation for Ruby on Rails programs. You can read about my experience as a software expert if that interests you.
I currently enjoy writing Jekyll plugins in Ruby for this website and others, as well as Ruby utilities.