Skip to content

samtay/so

Repository files navigation

ciappveyorcratesMITPackaging status

A terminal interface for StackOverflow written in Rust

example usage

While I like the acronymso,this tool would actually be better described as se:an interface to the StackExchange network. In particular one thing that differentiates it fromsimilar toolsis that you can simultaneously search any number of sites in the StackExchange network:

#search using your default configuration
$ so howdoi reverse a listinPython

#search for a latex solution
$ so --site tex how to put tilde over character

#use google to search stackoverflow, askubuntu, and unix.stackexchange
$ so -e google -s askubuntu -s stackoverflow -s unix howdoi install linux

installation

Arch Linux

You can install the AUR package so(tracks latest release) or so-git(tracks master), e.g.

yay -S so-git

FreeBSD

You can install the packagesovia

pkg install so

NetBSD

You can install the packagesovia

pkgin install so

MacOS

You can install the homebrewformula

brew install so

Alternatively, you can useMacPortsto installso:

sudo port install so

Windows

If you havescoopyou can install via the extras bucket:

#add extras bucket
scoop bucket add extras

#install so
scoop install so

from source

For any OS you can install the cratesodirectly:

# everything but windows
cargo install so

# windows
cargo install so --no-default-features --features windows

For more information on the feature flags, seeselecting a backend.

release binaries

Static binaries are available on thereleases pagefor common Linux, MacOS, and Windows targets. You can quickly install the one you need to directoryDEST with:

curl --proto'=https'--tlsv1.2 -sSf https://samtay.github.io/so/install.sh \
|bash -s -- --to DEST

Right now I'm only building the most common targets, but in theory it should be easy to add more, so if you don't see what you are looking for just open an issue and I can add it. Here's a list of thesupported targets.If you don't know what you need, you can installrustc and open an issue with the output ofrustc -Vv | grep host | cut -d' ' -f2.

documentation

configuration

The configuration files for e.g. a userAlicecan be found in the following directories:

  • Linux:/home/alice/.config/so
  • Windows:C:\Users\Alice\AppData\Roaming\Sam Tay\so
  • MacOS:/Users/Alice/Library/Preferences/io.Sam-Tay.so

defaults

Theconfig.ymlfile lets you specify your CLI defaults. So if you dislike the lucky prompt, always search serverfault and unix.stackexchange, and want thefastest search engine,you can set your config file like this:

#config.yml
---
api_key:~
limit:10
lucky:false
sites:
-serverfault
-unix
search_engine:stackexchange

Runso --helpto see your current defaults.

themes

In the same directory you'll findcolors.tomlwhich is self-documented. The default theme attempts to blend in with your default terminal theme, but you can change it as necessary. In particular, you may want to change thehighlight_textif the current selection is difficult to read. There are some themes in thethemesdirectory as well.

system clipboard integration

There's a very primitive integration in place to copy the contents of the currently focused question or answer to the system clipboard. This requires some command in your PATH that can accept stdin and pipe to the clipboard. On mac & windows, this will work out of the box with the default set topbcopy &cliprespectively. On Linux, I've made the assumption thatxclipis likely the most popular, but if you use something else (e.g.wl-copyon wayland), you'll need to set the command directly:

#config.yml
---
copy_cmd:copy --option-to-take-stdin

api keys

If you want to use your ownStackExchange API Keyyou can set it via

so --set-api-key <KEY>

You can also choose to use no key by editing your configuration toapi_key: ~. If for some reason my API key is globally throttled, you can hit the StackExchange API with no key up to 300 times per day per IP, which I imagine is fine for most users.

search engines

The available search engines are StackExchange, DuckDuckGo, and Google. StackExchange will always be the fastest to search because it doesn't require an additional request or any HTML parsing; however, it is also very primitive. DuckDuckGo is in second place for speed, as its response HTML is much smaller than Google's. I've found that it performs well for my queries, so it is the default search engine.

DuckDuckGosometimes blocks requests,so it is no longer the default.

multi-site searching

As stated in thedocs,

If a single IP is making more than 30 requests a second, new requests will be dropped.

So, don't go crazy with the multi-site search, since it is all done in parallel. In particular, if you specify more than 30 sites, SE will likely ban you for a short time.

selecting a backend

If you're installing from source, you can choose from a number of available backend rendering engines. Note that the packagedefaultandwindowsfeature flags do not have an ncurses dependency, for the sake of portability. The default backend istermion,a bindless library in pure Rust which seems to work quite well on Linux, MacOS, BSD, and Redox. The windows backend is by default crossterm,and while its level of support is awesome, it does comes at a price in performance. On my machine, the app kind of flashes between draws. So if you are on Mac, Linux, or Redox, your best bet is to compile with default features which uses the termion backend. If you are on windows, use crossterm, but know it will be slightly jumpy.

If the crossterm folks figure out a fix for allowing ncurses to receiveresize events,and you have ncurses installedon your system, then the ncurses and pancurses backends are likely the most performant. Just know thatcurrentlyif you choose this option, and you run the--luckyprompt, you won't be able to resize the terminal window while the TUI is open.

Available backends:

  • termion-backend
  • ncurses-backend
  • pancurses-backend
  • crossterm-backend

E.g. to usencurses-backend:

cargo install so --no-default-features --features ncurses-backend

See more information about this choice here.

contributing

Warning:this was my first time writing Rust and there is very likely some non-idiomatic and straight up ugly code throughout this project, so don't come looking here for a good Rust example! That being said, I would love to improve the codebase. Feel free to check out thecontributing guidelinesand submit any refactoring issues or pull requests.

credits

Credit to my good friendCharlesfor logo design.