An opinionated modal editor to simplify code editing from the terminal

Overview

build badge

(I'm currently refactoring the platform layer. So we have to first finish this cleanup before we're able to continue adding features)

An opinionated modal editor to simplify code editing from the terminal

main screenshot

more screenshots

Pepper is an experiment of mine to simplify code editing from the terminal. It's mission is to be a minimal and fast code editor with an orthogonal set of both editing and navigation features.

default keybindings

scripting api

defining language syntaxes

config recipes

installation

binaries

Pepper is open-source, which means you're free to build it and access all of its features. However, to support the development, prebuilt binaries are available for purchase at itch.

vamolessa.itch.io/pepper

This will not only keep you updated with the latest features/fixes but also support further pepper development!

using cargo

Simply running cargo install pepper should get you up and running.

NOTE: for x11 users, you'll need to have both libxcb-shape0-dev and libxcb-xfixes0-dev in your system due to dependencies in the copypasta crate.

from source

git clone [email protected]:vamolessa/pepper.git
cd pepper
cargo install --path .

NOTE: installing from source still requires cargo (at least it's easier this way).

if you find a bug or need help

Please open an issue

goals

  • small, but orthogonal, set of editing primitives
  • mnemonic and easy to reach default keybindings (assuming a qwerty keyboard)
  • cross-plaftorm (Linux, Windows, Mac)
  • customizable through scripting
  • extensible through external cli tools
  • be as fast and reponsive as possible

non goals

  • support every possible workflow (it will never ever get close to feature parity with vim or emacs)
  • complex ui (like breadcumbs, floating windows, extra status bars, etc)
  • multiple viewports (leave that to your window manager/terminal multiplexer. instead clients can connect to each other and act together as if they're a single application)
  • undo tree
  • support for text encodings other than UTF-8
  • fuzzy file picker (you can integrate with fzf, skim, etc)
  • workspace wide search (you can integrate with grep, ripgrep, etc)
  • having any other feature that could be implemented by integrating an external tool

features

  • everything is reachable through the keyboard
  • modal editing (normal mode also selects text)
  • multiple cursors
  • caret style cursors (like most text editors, cursors can move past last line character and text is always inserted to its left)
  • text-objects
  • macros
  • lua scripting
  • client/server architecture
  • simple syntax highlighting
  • support for language server protocol

philosophy

In the spirit of Handmade, almost all features are coded from scratch using simple stable Rust code. These are the only external crates being used in the project (mainly because of crossplatform):

  • argh: provides good cli interface
  • fuzzy-matcher: fuzzy matching for the picker ui. it could be replaced, however it's implementation does not get in the way and has minimal dependencies
  • winapi (windows-only): needed to implement windows platform layer

modal editing

Pepper is modal which means keypresses do different things depending on which mode you're in. However, it's also designed to have few modes so the overhead is minimal. Most of the time, users will be in either normal or insert mode.

comparing to vim

Like Vim, you have to actively start text selection. However, unlike it, you can also manipulate selections in normal mode. Also, there's no 'action' then 'movement'. There's only selections and actions. That is, d will always only delete selected text. If the selection was empty, it does nothing.

Pepper expands on Vim's editing capabilities by supporting multiple cursors. This enables you to make several text transformations at once. Also, cursors behave like carets instead of blocks and can always go one-past-last-character-in-line.

comparing to kakoune

Like Kakoune, you can manipulate selections while in normal mode and actions always operate on selections. However, unlike it, normal mode remembers if you're selecting text or nor (think a pseudo-mode). This way, there's no need for extra alt- based keybindings.

Pepper is heavily inspired by Kakoune's selection based workflow and multiple cursors. However its cursors behave like caret ranges instead of block selections. That is, the cursor is not a one-char selection but only a visual cue to indicate the caret location.

development thread

It's possible to kinda follow Pepper's development history in this twitter thread

big features todo

  • linux platform layer
  • mac/bsd platform layer
  • language server protocol (in progress)
  • debug adapter protocol

support pepper development

Pepper is open-source, which means you're free to build it and access all of its features. However, to support the development, prebuilt binaries are available for purchase at itch.

Please consider purchasing in order to support both the development of new features and bug fixing. I'll be forever grateful :)

<iframe src="https://itch.io/embed/810985?border_width=0" width="206" height="165" frameborder="0"> pepper by Matheus Lessa </iframe>
Comments
  • LSP Support

    LSP Support

    Hello, in features in README there is information about LSP support, but I can't find any more information about this, is it working? By the way, awesome project, I'm really looking into replacing neovim in future.

    opened by gbaranski 9
  • Crash on 0.26

    Crash on 0.26

    Just installed 0.26, and get thread 'main' panicked at 'could not spawn server', /home/defaultuser/.cargo/registry/src/github.com-1ecc6299db9ec823/pepper-0.26.0/src/platforms/unix_utils.rs:87:13 note: run withRUST_BACKTRACE=1environment variable to display a backtrace

    Using SailfishOS (mobile). Previous version worked fine...

    opened by levone1 7
  • Yank/Paste does not work on macOS

    Yank/Paste does not work on macOS

    I just noticed that I can't yank (y) or paste (Y) on macOS even though my copy-command is set to pbcopy and paste-command is set to pbpaste. Nothing happens when pressing y and Y just clears the selection without every pasting anything from the clipboard.

    opened by hovsater 7
  • pepper panics when opening a file

    pepper panics when opening a file

    Most of the time, I can't open any file with pepper (latest git rev as of writing, pepper binary from the mine crate). The following is written to pepper-crash.txt:

    panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }', pepper/src/application.rs:351:55
    

    Judging from the source code, the problem seems to have something to do with updating the display upon opening a file. No idea how to fix it though :/

    opened by malte-v 6
  • QoL feature: respect completion for aliases

    QoL feature: respect completion for aliases

    Just a minor thing, but would be nice to have (and probably not hard): When I use :open ... I get file completion, but when I use :o ... I don't. (Same for self-defined aliases.)

    opened by leahneukirchen 6
  • Windows version crashes opening a file

    Windows version crashes opening a file

    Cargo built version v0.10.6 crashes when opening a file, either from the command line or with the open command: thread '' panicked at 'index out of bounds: the len is 0 but the index is 0', C:\Users\whein.cargo\registry\src\github.com-1ecc6299db9ec823\pepper-0.10.6\src\buffer.rs:364:10

    opened by wheineman 6
  • Pasting 100 characters crashes pepper

    Pasting 100 characters crashes pepper

    Use an empty buffer, insert mode, paste this string of 100 x: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.

    Pepper crashes:

    thread '<unnamed>' panicked at 'index out of bounds: the len is 1 but the index is 14', src/client.rs:276:23
    stack backtrace:
       0: rust_begin_unwind
                 at /rustc/3e99439f4dacc8ba0d2ca48d221694362d587927/library/std/src/panicking.rs:515:5
       1: core::panicking::panic_fmt
                 at /rustc/3e99439f4dacc8ba0d2ca48d221694362d587927/library/core/src/panicking.rs:92:14
       2: core::panicking::panic_bounds_check
                 at /rustc/3e99439f4dacc8ba0d2ca48d221694362d587927/library/core/src/panicking.rs:69:5
       3: pepper::command::CommandManager::eval_and_then_output
       4: pepper::editor::Editor::on_client_event
       5: pepper::application::ServerApplication::run_application
    

    Reproducible on pepper 1e231e3535e08b2d81.

    opened by leahneukirchen 6
  • Integrating with external processes

    Integrating with external processes

    👋 @vamolessa, this is not so much an issue than it is a question.

    I read that one of pepper's goals were Extensible through external cli tools on the Handmade Network's website. Is this true, and if so, how?

    I'm coming from dte and was hoping pepper would provide some of the same features as dte provides when it comes to integrating with external tools. dte has a section on External Commands and I've found the following really useful:

    | command | description | pepper equivalent | | ---------- | ----------- | ------------------ | | filter | Filter selected text or whole file through external command. | ? | | run | Run external command. | ? | | exec-open | Run external command and open all filenames listed on its standard output. | find-file (sort of) |

    The main thing in dte I find powerful is the concept of exec. In Unify commands that run external programs into a single "exec" command this concept is explored further where a single construct, exec, can be used to implement a handful of other useful commands.

    I really love being able to run :run tig blame $FILE to temporarily open tig's blame view on the current file and after exiting ending back in my editor. exec-open allows me to run an external program such as fzf and then see the selected files opened in dte.

    opened by hovsater 5
  • Support `map select` (create mapping for selection mode)

    Support `map select` (create mapping for selection mode)

    We currently have:

    map

    Creates a keyboard mapping for an editor mode. <mode> is one of normal, insert, command, readline and picker. <from> and <to> are a string of keys.

    • usage: map <mode> <from> <to>

    Unfortunate there is no support for mapping on selection mode, but if map select is support this will open up many possibility for user to make the editor way more convenient for examples:

    map normal "<backspace>" "cVcvhd" # Delete one character to the left
    map normal "<delete>" "cVcvld" # Delete one character to the right
    
    # Delete selection
    map select "<backspace>" "d"
    map select "<delete>" "d"
    
    # By default, these keys do nothing in normal mode anyway.
    # Let's make them more useful by select the whole line/buffer before doing the action:
    map normal "d" "Vd" # Delete the whole line in normal mode
    map normal "y" "Vy" # Copy the whole line in normal mode
    map normal "<c-y>" "V<c-y>" # Copy the whole line to register in normal mode
    map normal "cs" "gkghvgjglcs" # Search whole buffer and select all match
    map normal "cS" "gkghvgjglcS" # Search whole buffer and select everything that not match
    map normal "CS" "gkghvgjglCS" # Search whole buffer and select everything that not match
    
    # Make those keys use selection instead of the whole line/buffer in selection mode:
    # (not sure if this is necessary, perhaps `map normal` shouldn't effect selection mode)
    map select "d" "d"
    map select "y" "y"
    map select "<c-y>" "<c-y>"
    map select "cs" "cs"
    map select "cS" "cS"
    map select "CS" "CS"
    
    opened by NNBnh 4
  • Add set the search pattern to the main selection key

    Add set the search pattern to the main selection key

    From Kakoune's keys docs:

    * : set the search pattern to the main selection (automatically detects word boundaries). Alt-* : set the search pattern to the main selection (verbatim, no smart detection).

    I imagine it will be implemented with only one key * to set the search pattern to the main selection that:

    • ~~In normal mode it will automatically detects word boundaries.~~
    • In selection mode it will set it verbatimly, no smart detection.
    opened by NNBnh 4
  • Bug while installing/compiling with `cargo`

    Bug while installing/compiling with `cargo`

    Here are the logs:

    ❯ cargo install pepper-plugin-lsp
        Updating crates.io index
      Downloaded pepper-plugin-lsp v0.13.0
      Downloaded 1 crate (36.1 KB) in 1.08s
      Installing pepper-plugin-lsp v0.13.0
      Downloaded pepper v0.26.1
      Downloaded libc v0.2.124
      Downloaded 2 crates (717.4 KB) in 2.07s
       Compiling libc v0.2.124
       Compiling pepper v0.26.1
    error[E0277]: expected a `Fn<(char,)>` closure, found `[char; 4]`
       --> /home/nnb/.cargo/registry/src/github.com-1ecc6299db9ec823/pepper-0.26.1/src/command.rs:180:48
        |
    180 |             self.0 = self.0.trim_start_matches(&[' ', '\t', '\n', '\r']);
        |                                                ^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn<(char,)>` closure, found `[char; 4]`
        |
        = help: the trait `Fn<(char,)>` is not implemented for `[char; 4]`
        = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&[char; 4]`
        = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&[char; 4]`
    
    error[E0277]: expected a `Fn<(char,)>` closure, found `[char; 2]`
       --> /home/nnb/.cargo/registry/src/github.com-1ecc6299db9ec823/pepper-0.26.1/src/command.rs:272:44
        |
    272 |         self.0 = self.0.trim_start_matches(&[' ', '\t']);
        |                                            ^^^^^^^^^^^^ expected an `Fn<(char,)>` closure, found `[char; 2]`
        |
        = help: the trait `Fn<(char,)>` is not implemented for `[char; 2]`
        = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&[char; 2]`
        = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&[char; 2]`
    
    error[E0277]: expected a `Fn<(char,)>` closure, found `[char; 9]`
       --> /home/nnb/.cargo/registry/src/github.com-1ecc6299db9ec823/pepper-0.26.1/src/command.rs:217:26
        |
    217 |             match s.find(&[' ', '\t', '\n', '\r', '"', '\'', '{', '}', '#']) {
        |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn<(char,)>` closure, found `[char; 9]`
        |
        = help: the trait `Fn<(char,)>` is not implemented for `[char; 9]`
        = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&[char; 9]`
        = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&[char; 9]`
    
    For more information about this error, try `rustc --explain E0277`.
    error: failed to compile `pepper-plugin-lsp v0.13.0`, intermediate artifacts can be found at `/tmp/cargo-installJcnE6N`
    
    Caused by:
      could not compile `pepper` due to 3 previous errors
    
    ❯ cargo install pepper
        Updating crates.io index
      Installing pepper v0.26.1
       Compiling libc v0.2.124
       Compiling pepper v0.26.1
    error[E0277]: expected a `Fn<(char,)>` closure, found `[char; 4]`
       --> /home/nnb/.cargo/registry/src/github.com-1ecc6299db9ec823/pepper-0.26.1/src/command.rs:180:48
        |
    180 |             self.0 = self.0.trim_start_matches(&[' ', '\t', '\n', '\r']);
        |                                                ^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn<(char,)>` closure, found `[char; 4]`
        |
        = help: the trait `Fn<(char,)>` is not implemented for `[char; 4]`
        = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&[char; 4]`
        = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&[char; 4]`
    
    error[E0277]: expected a `Fn<(char,)>` closure, found `[char; 2]`
       --> /home/nnb/.cargo/registry/src/github.com-1ecc6299db9ec823/pepper-0.26.1/src/command.rs:272:44
        |
    272 |         self.0 = self.0.trim_start_matches(&[' ', '\t']);
        |                                            ^^^^^^^^^^^^ expected an `Fn<(char,)>` closure, found `[char; 2]`
        |
        = help: the trait `Fn<(char,)>` is not implemented for `[char; 2]`
        = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&[char; 2]`
        = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&[char; 2]`
    
    error[E0277]: expected a `Fn<(char,)>` closure, found `[char; 9]`
       --> /home/nnb/.cargo/registry/src/github.com-1ecc6299db9ec823/pepper-0.26.1/src/command.rs:217:26
        |
    217 |             match s.find(&[' ', '\t', '\n', '\r', '"', '\'', '{', '}', '#']) {
        |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn<(char,)>` closure, found `[char; 9]`
        |
        = help: the trait `Fn<(char,)>` is not implemented for `[char; 9]`
        = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&[char; 9]`
        = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&[char; 9]`
    
    For more information about this error, try `rustc --explain E0277`.
    error: failed to compile `pepper v0.26.1`, intermediate artifacts can be found at `/tmp/cargo-installq78vuM`
    
    Caused by:
      could not compile `pepper` due to 3 previous errors
    

    I'm running NixOS 21.11

    opened by NNBnh 4
  • Add align selections

    Add align selections

    Align selections is a crucial and very frequently use action (example) that I really miss when switch to Pepper. From Kakoune's keys docs:

    & : Align selections, align the cursor of each selection by inserting spaces before the first character of each selection.

    enhancement 
    opened by NNBnh 2
  • Support combines selections from the register with the current ones and the other way around.

    Support combines selections from the register with the current ones and the other way around.

    This would help a lot with manipulate complex multi selection. From Kakoune's keys docs:

    Alt-z combines selections from the register with the current ones, whereas Alt-Z combines current selections with the ones in the register; a menu is then displayed which waits for one of the following additional keys:

    • a append selections.
    • u keep a union of selections.
    • i keep an intersection of selections.
    • < select the selection with the leftmost cursor for each pair.
    • > select the selection with the rightmost cursor for each pair.
    • + select the longest selection
    • - select the shortest selection.

    (I don't think <, >, + and - is useful)

    This require #54 to be done.

    enhancement 
    opened by NNBnh 2
  • [Plugin] Support auto close and rename tag

    [Plugin] Support auto close and rename tag

    Following issue #46:

    Pepper would be great if it have the quality-of-life-improvement features from two of the most popular VScode plugins: Auto Close Tag and Auto Rename Tag:

    Auto Close Tag

    From the "Auto Rename Tag" VScode plugin:

    Automatically add HTML/XML close tag, same as Visual Studio IDE or Sublime Text does:

    • Automatically add closing tag when you type in the closing bracket of the opening tag
    • After closing tag is inserted, the cursor is between the opening and closing tag
    • Set the tag list that would not be auto closed
    • Automatically close self-closing tag
    • Support auto close tag as Sublime Text 3
    • Use Keyboard Shortcut or Command Palette to add close tag manually

    usage

    Auto Rename Tag:

    From the "Auto Rename Tag" VScode plugin:

    When you rename one HTML/XML tag, automatically rename the paired HTML/XML tag

    usage

    If you find this suggestion it's suitable to be built-in with the editor, feel free to label this issue with "Plugin" or "Plugin Idea".

    plugin request 
    opened by NNBnh 1
  • [Plugin] Display the color of color-hex-codes, color functions

    [Plugin] Display the color of color-hex-codes, color functions

    Display the color of color-hex-codes and color functions is pretty helpful for writing CSS and UI design... VScode support this feature by default, while NeoVim have an acceptable plugin vim-hexokinase that do the job:

    gif

    I hope Pepper could support for coloring:

    • 6 digit hex codes (#FFFFFF).
    • 3 digit hex codes (#FFF).
    • RGB functions (rgb(100%, 100%, 100%), rgb(255, 255, 255)).
    • RGBA functions (rgba( ... )).
    • HSL functions (hsl( ... )).
    • HSLA functions (hsla( ... )).

    With styling options:

    • Background.
    • Foreground.
    • Virtual (display a small colored square on the right).
    • Sign column (a column next to the line numbers).

    If you find this suggestion it's suitable to be built-in with the editor, feel free to label this issue with "Plugin" or "Plugin Idea".

    plugin request 
    opened by NNBnh 1
  • [Plugin] Support Tree-sitter

    [Plugin] Support Tree-sitter

    From Tree-sitter's website:

    Tree-sitter is a parser generator tool and an incremental parsing library. It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited. Tree-sitter aims to be:

    • General enough to parse any programming language.
    • Fast enough to parse on every keystroke in a text editor.
    • Robust enough to provide useful results even in the presence of syntax errors.
    • Dependency-free so that the runtime library (which is written in pure C) can be embedded in any application.

    I think this is the most important feature that missing in Pepper.

    wontfix plugin request 
    opened by NNBnh 2
Releases(v0.5.5)
Owner
Matheus Lessa Rodrigues
Hi! I'm Matheus. I make gaems @bitcake. Code bender. Audio acolyte. Have u ever went fast
Matheus Lessa Rodrigues
TIF is a terminal_image_format. (theres no TIF editor, so i made TIF images through a hex editor lol)

Colors these are the colors you can use when displaying images on the terminal BYTES: 5A = BLUE 5B = BLACK 5C = RED 5D = GREEN 5E = PURPLE 5F = WHITE

buzz 4 Jun 21, 2022
Dip editor: Multi-platform Text editor purely written in Rust

dip editor Multi-platform Text editor purely written in Rust, supercharged by Bevy game engine and Dioxus UI framework. heavily in development Why Gam

Junichi Sugiura 162 Sep 24, 2022
A terminal-based text editor written in Rust

Iota Iota is a terminal-based text-editor written in Rust. Here's what it looks like right now, editing itself. Motivation Iota was born out of my fru

Greg Chapple 1.5k Sep 20, 2022
An independent Rust text editor that runs in your terminal!

Ox editor Ox is a code editor that runs in your terminal. About The Project Ox is a code editor. It was written in Rust using ANSI escape sequences. I

null 2.8k Sep 27, 2022
ReVi is a cross-platform terminal based Vim inspired text editor.

ReVi Table Of Contents: About Usage Install Clone && Installing Development Q&A KeyBindings Roadmap Changelog About ReVi is a cross-platform terminal

null 30 Aug 25, 2022
A simple terminal-based editor made in rust!

ELuna Editor The terminal-based editor for europa lang. Goals Be as minimal as possible, but retain conveniences found in other editors. Do not add fe

Junhao 3 May 25, 2022
eBPF terminal editor

TBM - Terminal Blueprint Meddler A TUI application for fooling around inside eBPF files. Installation cargo install tbm Usage Currently, only prints

Rafael Ortiz 1 Jan 18, 2022
A text editor in ≤1024 lines of code, written in Rust

Kibi: A text editor in ≤1024 lines of code, written in Rust A configurable text editor with UTF-8 support, incremental search, syntax highlighting, li

Ilaï Deutel 839 Sep 24, 2022
Rustpad is an efficient and minimal collaborative code editor, self-hosted, no database required

Rustpad is an efficient and minimal open-source collaborative text editor based on the operational transformation algorithm

Eric Zhang 2.4k Sep 25, 2022
A package manager for the Lite-XL code editor

Lite-XL Package Manager (lpm) (Under Development) lpm is an attempt to create a package manager for the Lite-XL code editor. It's primary goal is to p

Debarchito Nath 9 Aug 29, 2022
My own personal code editor built with Rust + OpenGL

Glyph This is my personal code editor that I am building for fun and to get more familiar with OpenGL. Glyph currently supports Vim keybinds, syntax h

Zack Radisic 72 Sep 26, 2022
Lightning-fast and Powerful Code Editor written in Rust

Lapce Lightning-fast and Powerful Code Editor written in Rust About Lapce is written in pure Rust, with UI in Druid. It's using Xi-Editor's Rope Scien

Lapce 18k Sep 26, 2022
Aspiring vim-like text editor

Rim Rim is an aspiring Vim-like text editor written in Rust. Current state Rim is in an early prototype stage. This means that you can load, edit and

Mathias Hällman 547 Sep 24, 2022
A modern editor with a backend written in Rust.

Xi Editor (pronounced "Zigh") A modern editor with a backend written in Rust. Maintenance status: The xi-editor project is not currently under active

null 19.6k Sep 27, 2022
An experimental next-generation Electron-based text editor

Attention: GitHub has decided not to move forward with any aspect of this project. We'll archive the repository in case anybody finds value here, but

Atom Archive 8.6k Sep 22, 2022
Web base text editor written in rust

Ultron Ultron is a web based monospace text-editor with syntax highlighting, completely written in rust. I wrote this code editor for my very specific

Jovansonlee Cesar 59 Aug 8, 2022
A save editor for Mass Effect Trilogy

Trilogy Save Editor A save editor for Mass Effect Trilogy A bit late but just in time ! This software is similar to Gibbed's save editors (and forks)

Karlitos 109 Sep 13, 2022
Rust-based traffic editor for RMF

Traffic Editor III Welcome to Traffic Editor III. install stuff Unfortunately we need a newer Rust than what comes with Ubuntu 20.04. First make sure

null 1 Nov 26, 2021
Borderlands 3 Save/Profile Editor for Windows/MacOS and Linux!

Borderlands 3 Save Editor A tool to help you modify your Borderlands 3 Saves and Profiles. Currently it runs on Windows, Mac OS and Linux. It supports

Zak 178 Sep 19, 2022