I haven't touched this project in a very long while and I no longer use it myself, therefore I decided to archive this repository.
A Text Expander inspired text expander and text macro appication for Windows and Linux.
If you find this software useful, consider becoming a patron
Xpander is written python 3 and typescript. It runs on Windows and Linux, with possibility to port to more platforms.
You type an abbreviation and it's automatically expanded to (replaced with) a predefined block of text called a phrase. Both plain text and richtext with formating are supported. This is very useful when filling out forms, typing emails, coding or doing creative (yet repetetive) writing. Or any kind of writing, really.
Each phrase is stored as specially formatted JSON file.
By default they a placed in ~/.phrases
but you can change it in
settings.
Since these are small text files and Xpander is cross platform you can easily sync these between computers.
Of course there are bugs! Nothing major, just something to keep in mind while I iron them out.
Firefox web browser has a ridiculously slow event loop, so when programatically (like, really quickly) sending events, some get "swallowed" or dropped.
What this means in practice:
- When expanding a phrase sometimes one or two of the abbreviation characters get left behind.
- Enabling caret cycling with
Tab
key in settings disablesTab
key in most native applications. This happens because sending events directly to active window is wonky on windows. Usually you have to find active control and send the event directly to it instead. - Fill-in-the-blank window gets pushed to the background on first showing requiring to
alt-Tab
to it. This shouldn't happen when popping up a second, third, ... time.
Unlike some text expanders (I'm looking at you, Autokey), Xpander fully supports multiple keyboard layouts, meaning that when you change keyboard language you won't accidentally trigger phrases.
Other features include:
- Rich text support with formatting. If using richtext phrase in plaintext editor, Xpander automatically removes formatting to prevent artefacts.
- Templating macros. Xpander uses Jinja2 templating engine. Combined with other features this makes for a powerful and robust way to define phrases.
- Fill-in-the-blank fields in phrases. You can add information to your phrases at the time of expansion, with multiple field types, default values for when you don't need to change anything and linking of named fields (more below).
- Phrase embedding. You can use an already defined phrase as part of one or more bigger phrases.
- Clipboard (and mouse selection) embedding in phrases.
- Caret (cursor) repositioning after expansion. You can also define multiple caret insertion points and cycle between them with the tab key. Or if it causes issues with some applications, disable this feature in settings.
- Date and time formatting and math. With
time
function you can insert formatted dates, of current time, future or past. - Command running. Run an application or a shell script and use it's output in a phrase.
- Key macros. With the
key
function you can send key presses and combinations to applications. - Window filters. Define a filter by window class or title and the phrase will only expand in matching windows.
- And more!
Xpander only needs system installation of python 3.6+ to run. You can get it at python.org/.
Prebuilt packages of Xpander are available on releases page.
Phrase can be any text or in case of rich text any valid html. Defining html directly can be done, but is currently not very well supported. You should use the build-in rich text editor.
No special syntaxt is necessary, how ever if you want advanced functionallity here's the docs!
Since Xpander uses Jinja2 so you can get very advanced with phrase definitions. For full description of Jinja2 syntax go here.
Jinja2 allows variable expansion and function calls from the template (phrase).
For the sake of consistency, Xpander doesn't define any variables
and uses functions for almost everything.
Note that function arguments need to be quoted (either '
or "
)
unless otherwise noted. This doesn't apply to numerals.
Function | Arguments | Example | Explanation |
---|---|---|---|
time | period, unit, format | {{ time(-1, week, "%Y-%m-%d") }} | Outputs date one week ago like 2020-01-13 |
time | format | time(format="%B %d, %Y") | Ouputs current date like January 31, 2020 |
clipboard | - | {{ clipboard() }} | Inserts clipboard contents |
primary | - | {{ primary() }} | Inserts mouse selection contents on Linux, doesn't do anything on Windows |
key | key | {{ key("tab") }} | Sends a key press to the focused application |
key | key, state | {{ key("tab", "down") }} | Presses and holds/releases a key |
phrase | name | {{ phrase("signature") }} | Inserts expanded phrase contents |
run | command | run("cowsay Hello, World!") | Runs a command and inserts it's output |
run | command, dir, shell, stderr | run("echo Error", shell=True, stderr=False) | |
fillentry | name, default, width | fillentry("name", "Oz") | Displays a fill-in-the-blank dialog with single line text field |
fillmulti | name, default, width, height | fillmulti() | Displays a fill-in-the-blank dialog with multi line text field |
fillchoice | choice1, choice2, ..., name, default | fillchoice("red", "green", name="color", default="blue") | Displays a fill-in-the-blank dialog with multiple choice widget |
filloptional | text, name | filloptional("This text will only output if you check the box!") | Displays a block of text with a checkbox to toggle inclusion |
These are the tokens you can use in time
function.
For every posibillity check python's documentation on strftime
.
Token | Meaning | Example |
---|---|---|
%a | Weekday | Sun, Mon |
%A | Weekday | Sunday |
%d | Day of month | 31, 28 |
%b | Month | Jan, Feb |
%B | Month | January |
%y | Year | 99, 15 |
%Y | Year | 2020 |
%H | Hour (24) | 23, 12 |
%I | Hour (12) | 12, 9 |
%p | PM or AM | |
%M | Minute | 59, 05 |
%S | Second | 45, 09 |
%% | Percent sign | % |
Even though tokens provide addintional functionality they are not part of Jinja2 language.
Token | Meaning |
---|---|
$| | Insert caret (cursor) at this point. Can be inserted multiple times |
$+ | Override settings to keep trigger after expansion |
$- | Override settings to remove trigger after expansion |
I strongly recommend you install poetry and yarn for python and node dependency management respectively. You should also use nvm to install latest LTS of node.
nvm install --lts --latest-npm
nvm use --lts
First clone this repo
git clone https://github.com/masaeedu/xpander.git
Then install dependencies
poetry install
or
pip install -r requirements.txt
And
yarn install
or
npm install
Then just run
yarn start
or
npm start
To package run
yarn build_py
yarn dist
or alternativly
npm buold_py
npm dist