<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thiago Araújo Silva</title>
    <description>The latest articles on DEV Community by Thiago Araújo Silva (@thiagoa).</description>
    <link>https://dev.to/thiagoa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F52527%2F29fcb87f-9031-4dfd-b4cd-a05d7aad239f.jpeg</url>
      <title>DEV Community: Thiago Araújo Silva</title>
      <link>https://dev.to/thiagoa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thiagoa"/>
    <language>en</language>
    <item>
      <title>Ruby and Emacs Tip: Advanced Pry Integration</title>
      <dc:creator>Thiago Araújo Silva</dc:creator>
      <pubDate>Mon, 27 Aug 2018 12:28:03 +0000</pubDate>
      <link>https://dev.to/thiagoa/ruby-and-emacs-tip-advanced-pry-integration-33bk</link>
      <guid>https://dev.to/thiagoa/ruby-and-emacs-tip-advanced-pry-integration-33bk</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/pry/pry"&gt;Pry&lt;/a&gt; is one of those tools that you'll despise until you actually &lt;em&gt;learn&lt;/em&gt; what it can do for you. It's a window to the Ruby language, a land where things have extreme late-binding and can change at any time.&lt;/p&gt;

&lt;p&gt;With Pry, you can easily spelunk anything: edit, view, and navigate through source code; debug, play lines of code, and run shell commands. Doing the same with "puts debugging" or metaprogramming requires repetitive typing, tedious plumbing, third-party gems (&lt;a href="https://github.com/banister/method_source"&gt;method_source&lt;/a&gt;, anyone?) and won't give you syntax highlighting. You can run Ruby REPLs in &lt;a href="https://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt; (including Pry) with &lt;a href="https://github.com/nonsequitur/inf-ruby"&gt;inf-ruby&lt;/a&gt;, a package co-authored by Yukihiro Matsumoto, Ruby's BDFL. But there's so much more power to unlock!&lt;/p&gt;

&lt;p&gt;We will rely on Pry's &lt;a href="https://github.com/pry/pry/wiki/Editor-integration"&gt;editor integration&lt;/a&gt;, so the good news is that you can apply the same principles to your favorite text editor, as long as it supports a client-server architecture. &lt;a href="https://github.com/neovim/neovim"&gt;Neovim&lt;/a&gt; is one such example. Emacs, however, has a special trick up its sleeve: elisp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;p&gt;This post will guide you through integrating Pry into Emacs and ironing out a few annoyances that might arise during the process. Also, it will give you an idea of how to create Pry commands that reach back into Emacs via &lt;em&gt;elisp&lt;/em&gt;. Note that it won't teach you how to setup or use Emacs. Among others you will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run Pry from within Emacs,&lt;/li&gt;
&lt;li&gt;Seamlessly integrate Pry into Emacs,&lt;/li&gt;
&lt;li&gt;Edit and reload files without leaving Pry (nor Emacs!),&lt;/li&gt;
&lt;li&gt;Page through Pry's output,&lt;/li&gt;
&lt;li&gt;View a Ruby file in Emacs through Pry,&lt;/li&gt;
&lt;li&gt;Open a gem in Dired through Pry.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Emacs server
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;emacsclient&lt;/code&gt;, you can interact with a running Emacs session from the outside. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;emacsclient my_file.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command opens &lt;code&gt;my_file.rb&lt;/code&gt; in your current Emacs session. Note that before attempting to use &lt;code&gt;emacsclient&lt;/code&gt;, you'll need to start a server process with &lt;code&gt;M-x server-start&lt;/code&gt; (press &lt;code&gt;M-x&lt;/code&gt; in Emacs, type &lt;code&gt;server-start&lt;/code&gt;, and press &lt;code&gt;return&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;I want things to be as automated as possible, so I created an &lt;em&gt;elisp&lt;/em&gt; function to start the server for me when I open Emacs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;run-server&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="s"&gt;"Runs the Emacs server if it is not running"&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;'server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;unless&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;server-running-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;server-start&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;run-server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code can be saved in your &lt;code&gt;~/.emacs.d/init.el&lt;/code&gt; config file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Default editor configuration
&lt;/h2&gt;

&lt;p&gt;The next step is to set &lt;code&gt;emacsclient&lt;/code&gt; as your default editor. Save the following  lines in your shell config file (&lt;code&gt;.bash_profile&lt;/code&gt; for bash or &lt;code&gt;.zshenv&lt;/code&gt; for zsh):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;emacsclient
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;VISUAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$EDITOR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use a Mac computer and a GUI Emacs, Emacs won't inherit your shell environment variables. To overcome this issue, I recommend installing the &lt;code&gt;exec-path-from-shell&lt;/code&gt; package. Be sure to add MELPA to your package archives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;package-archives&lt;/span&gt;
      &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;"melpa"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"http://melpa.milkbox.net/packages/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gnu"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"http://elpa.gnu.org/packages/"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;package-initialize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;M-x package-refresh-contents&lt;/code&gt; to refresh the packages,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;M-x package-install&lt;/code&gt;, &lt;code&gt;exec-path-from-shell&lt;/code&gt;, and press &lt;code&gt;return&lt;/code&gt; to install the package.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, save this snippet in your &lt;code&gt;init.el&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;copy-shell-environment-variables&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;memq&lt;/span&gt; &lt;span class="nv"&gt;window-system&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;mac&lt;/span&gt; &lt;span class="nv"&gt;ns&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;exec-path-from-shell-initialize&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;copy-shell-environment-variables&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there's a gotcha: I prefer &lt;code&gt;nvim&lt;/code&gt; when I'm working on the terminal (which is rare these days because I run most of my shell commands within Emacs). For this reason, I set both editor variables via elisp and leave my shell variables unchanged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;setenv&lt;/span&gt; &lt;span class="s"&gt;"VISUAL"&lt;/span&gt; &lt;span class="s"&gt;"emacsclient"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;setenv&lt;/span&gt; &lt;span class="s"&gt;"EDITOR"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;getenv&lt;/span&gt; &lt;span class="s"&gt;"VISUAL"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Trying it out
&lt;/h2&gt;

&lt;p&gt;Run &lt;code&gt;M-x shell&lt;/code&gt; (Emacs' shell), find an existing file, and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ $EDITOR&lt;/span&gt; existing-file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, you are still in Emacs, and the file opened right before your eyes. Meanwhile, the Pry buffer is blocked with the message "&lt;em&gt;Waiting for Emacs...&lt;/em&gt;". It's waiting for you to edit the file, save it, and press &lt;code&gt;C-x #&lt;/code&gt; (&lt;code&gt;server-edit&lt;/code&gt;) to terminate the connection, which closes the file and unblocks the shell. &lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Pry
&lt;/h2&gt;

&lt;p&gt;You need a few settings to make Pry play nice with Emacs. Save these lines in your &lt;code&gt;~/.pryrc&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'INSIDE_EMACS'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="no"&gt;Pry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;correct_indent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="no"&gt;Pry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Pry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'VISUAL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Pry.config.correct_indent = false&lt;/code&gt; fixes an annoying issue with the command prompt.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Pry.config.pager = false&lt;/code&gt; tells Pry not to use &lt;code&gt;less&lt;/code&gt; as a pager. Why? Because Pry runs under &lt;em&gt;comint.el&lt;/em&gt;, a library that allows an ordinary Emacs buffer to communicate with an inferior shell process - in our case, a Pry REPL. It doesn't support interactive programs such as less, but on the other hand, the buffer itself is a pager.&lt;/li&gt;
&lt;li&gt;Finally, we tell Pry to use whatever is set to the &lt;code&gt;VISUAL&lt;/code&gt; environment variable as its editor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running Pry from within Emacs
&lt;/h2&gt;

&lt;p&gt;Nothing special to do. Just ensure you've installed the &lt;code&gt;inf-ruby&lt;/code&gt; package and that your project is configured to use Pry. &lt;code&gt;inf-ruby&lt;/code&gt; provides many commands to spin up a Ruby REPL, like &lt;code&gt;inf-ruby-console-rails&lt;/code&gt; for example. For Rails projects, you can install the &lt;code&gt;pry-rails&lt;/code&gt; gem and call it a day. The &lt;code&gt;projectile-rails&lt;/code&gt; package, which I thoroughly recommend, has a convenient shortcut for this: &lt;code&gt;C-c p r&lt;/code&gt; (&lt;code&gt;projectile-rails-console&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Editing and reloading code
&lt;/h2&gt;

&lt;p&gt;This is where things start to get fun. Let's suppose you're not getting an expected return value out of a certain gem. The name of the troublesome method is &lt;code&gt;MyGem.do_thing&lt;/code&gt;, which is called by &lt;code&gt;MyApp.do_thing&lt;/code&gt;. Let's edit &lt;code&gt;MyGem.do_thing&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;edit&lt;/span&gt; &lt;span class="no"&gt;MyGem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;do_thing&lt;/span&gt;
&lt;span class="no"&gt;Waiting&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="no"&gt;Emacs&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And insert a debug statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyGem&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;do_thing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pry&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now save the file with &lt;code&gt;C-x C-s&lt;/code&gt; and press &lt;code&gt;C-x #&lt;/code&gt; to terminate the &lt;code&gt;emacsclient&lt;/code&gt; connection. Boom! Pry will load your new changes and you'll be taken back to the Pry prompt! Finally, run &lt;code&gt;MyApp.do_thing&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;do_thing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;From&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/Users/&lt;/span&gt;&lt;span class="n"&gt;thiago&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asdf&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;installs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my_gem&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my_gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt; &lt;span class="no"&gt;MyGem&lt;/span&gt;&lt;span class="c1"&gt;#do_thing:&lt;/span&gt;

    &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_thing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'pry'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome, you've hit the breakpoint, so you might want to inspect the state of your application to figure out what's wrong. Now you can debug the world without leaving Emacs! Pry's &lt;a href="https://github.com/pry/pry/wiki/Editor-integration#using-the-edit-command"&gt;edit&lt;/a&gt; command is extremely handy because you don't need to know where the gem or the method are stored on disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paging through source code
&lt;/h2&gt;

&lt;p&gt;In Pry, you can read the source code of anything with the &lt;code&gt;show-source&lt;/code&gt; command (or &lt;code&gt;$&lt;/code&gt;). Let's take a look at &lt;code&gt;ActiveRecord::Base#establish_connection&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;establish_connection&lt;/span&gt;

&lt;span class="no"&gt;From&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/Users/&lt;/span&gt;&lt;span class="n"&gt;thiago&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asdf&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;installs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;activerecord&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;active_record&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;connection_handling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="no"&gt;Owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ConnectionHandling&lt;/span&gt;
&lt;span class="no"&gt;Visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;public&lt;/span&gt;
&lt;span class="no"&gt;Number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="ss"&gt;lines: &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;establish_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"Anonymous class is not allowed."&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;DEFAULT_ENV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_sym&lt;/span&gt;
  &lt;span class="n"&gt;spec_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;"primary"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connection_specification_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spec_name&lt;/span&gt;

  &lt;span class="n"&gt;resolver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ConnectionAdapters&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ConnectionSpecification&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configurations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;spec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;symbolize_keys&lt;/span&gt;
  &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spec_name&lt;/span&gt;

  &lt;span class="n"&gt;connection_handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;establish_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet fits into a single screen, but what to do when it doesn't? You can press &lt;code&gt;return&lt;/code&gt; (&lt;code&gt;comint-send-input&lt;/code&gt;) to run &lt;code&gt;show-source&lt;/code&gt; and either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scroll back up with &lt;code&gt;M-v&lt;/code&gt; until reaching the start of the output, then &lt;code&gt;C-v&lt;/code&gt; to scroll down, or;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;C-c C-r&lt;/code&gt; (&lt;code&gt;comint-show-output&lt;/code&gt;) to make the cursor jump to the start of the output, then &lt;code&gt;C-v&lt;/code&gt; to scroll down. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second option is a clear winner. However, I've gotten tired of always running &lt;code&gt;comint-show-output&lt;/code&gt;, so I came up with my own automation. I've created the following function and mapped it to &lt;code&gt;&amp;lt;C-return&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Save this code in init.el&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;comint-send-input-stay-on-line&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;call-interactively&lt;/span&gt; &lt;span class="ss"&gt;'comint-send-input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;run-with-timer&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;
                  &lt;span class="no"&gt;nil&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;call-interactively&lt;/span&gt; &lt;span class="ss"&gt;'comint-show-output&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;define-key&lt;/span&gt; &lt;span class="nv"&gt;comint-mode-map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;C-return&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;'comint-send-input-stay-on-line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It runs &lt;code&gt;comint-show-output&lt;/code&gt; right after &lt;code&gt;comint-send-input&lt;/code&gt;. There's an interval of 0.05 seconds between the commands to avoid a race condition, time enough for the output to be available before you can actually return to it.&lt;/p&gt;

&lt;p&gt;The cool thing is that this shortcut works with any comint prompt, even &lt;code&gt;M-x shell&lt;/code&gt;. I'm not sure if there's an easier solution to this problem, so if you know of any please leave it up in the comments :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing a file through Pry
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;show-source&lt;/code&gt; is cool but it's not enough. Often times I want to open the corresponding Ruby file in another buffer, where I have &lt;code&gt;enh-ruby-mode&lt;/code&gt; and a bunch of other tools at my disposal. The default &lt;code&gt;edit&lt;/code&gt; command is a no-go because it blocks the Pry prompt and waits for an edit to be made. Also, the buffer usually gets closed in the end.&lt;/p&gt;

&lt;p&gt;Luckily, we can use &lt;code&gt;edit -n&lt;/code&gt; to bypass the blocking behavior. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;edit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="no"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will open the file for the &lt;code&gt;Foo&lt;/code&gt; module with the cursor pointed at the &lt;code&gt;bar&lt;/code&gt; class method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open a gem in Dired through Pry
&lt;/h2&gt;

&lt;p&gt;Opening a gem is something I need to do surprisingly often. Sometimes I want to look into the files or just search within the gem's source code. And I'll be happy if I can avoid a trip to GitHub, which also requires going through the trouble of pointing the gem at the specific version that my app is using. To showcase what a custom command looks like, I also don't want to use the &lt;code&gt;bundle open&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Here's a supposed Pry command to open a gem in Dired:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# `ggem` is a mnemonic to "go to gem"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ggem&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note that Pry commands have a special syntax. They are not calls to Ruby methods.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's apply divide and conquer to make it work. First, we need a way to open a directory in Emacs. Go to a terminal and type in the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;emacsclient &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'(dired-jump nil "~")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flip back to Emacs, and you will see a Dired window with the cursor positioned at your home directory. Awesome! The &lt;code&gt;-e&lt;/code&gt; flag to &lt;code&gt;emacsclient&lt;/code&gt; allows us to run an arbitrary string of &lt;em&gt;elisp&lt;/em&gt; code, so we've run the &lt;code&gt;dired-jump&lt;/code&gt; function and passed our home directory (&lt;code&gt;~&lt;/code&gt;) as the second argument.&lt;/p&gt;

&lt;p&gt;Now let's create a Ruby method to wrap this call. Save it in &lt;code&gt;~/.pryrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The function accepts an arbitrary path&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;emacs_open_in_dired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt; &lt;span class="sx"&gt;%{emacsclient -e '(dired-jump nil "#{path}")'}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to find the gem's directory. In the above example, the gem is &lt;code&gt;graphql-batch&lt;/code&gt;. Here's a method that will return the directory as a &lt;code&gt;Pathname&lt;/code&gt; object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gem_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gem_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;gem_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Specification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gem_name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;gem_dir&lt;/span&gt; 
  &lt;span class="no"&gt;Pathname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gem_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we've gathered all the pieces, let's create the Pry command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a shorthand to create and add a command at the same time&lt;/span&gt;
&lt;span class="no"&gt;Pry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_command&lt;/span&gt; &lt;span class="s1"&gt;'ggem'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="s1"&gt;'Open a gem dir in Emacs dired'&lt;/span&gt;
  &lt;span class="n"&gt;banner&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;'BANNER'&lt;/span&gt;&lt;span class="sh"&gt;
  Usage: ggem GEM_NAME

  Example: ggem propono
&lt;/span&gt;&lt;span class="no"&gt;  BANNER&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;
    &lt;span class="n"&gt;gem_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Opens the gem's lib folder in Dired&lt;/span&gt;
    &lt;span class="n"&gt;emacs_open_in_dired&lt;/span&gt; &lt;span class="n"&gt;gem_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gem_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="s1"&gt;'lib'&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MissingSpecError&lt;/span&gt;
    &lt;span class="c1"&gt;# do nothing&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, the command should now be working! You can use it with any gem, as long as it's declared in your Gemfile!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this post was useful to you. There's so much you can do with these tools that I haven't even scratched the surface! Emacs is a great editor, and the combination of Ruby and elisp gives you almost endless possibilities. With &lt;code&gt;inf-ruby&lt;/code&gt; you can also do cool things such as sending Ruby code from a buffer to the REPL process, so I encourage you to explore it in detail!&lt;/p&gt;

&lt;p&gt;If Pry isn't already the &lt;em&gt;heart&lt;/em&gt; of your Ruby workflow, I recommend you make the leap. If you work with Ruby, it's a life-changing tool. In the next post, I will show you how to run RSpec tests productively.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>emacs</category>
      <category>pry</category>
      <category>elisp</category>
    </item>
  </channel>
</rss>
