markdown · 19471 bytes Raw Blame History

Language Server Protocol (LSP) Guide

What is LSP?

Language Server Protocol (LSP) is like having a smart assistant that understands your programming language. It provides IDE-like features such as:

  • Error detection as you type
  • Jump to definition of functions/variables
  • Find all references to a symbol
  • Auto-completion suggestions
  • Rename symbols across your entire project
  • Code formatting to keep style consistent
  • Quick fixes for common errors

Instead of building these features separately for each language, LSP uses a standardized protocol. This means fac can support Python, JavaScript, Fortran, Rust, and 100+ other languages using the same system!

How Does It Work?

┌─────────────┐          LSP Protocol          ┌──────────────────┐
│             │ ◄────────────────────────────► │  Language Server │
│  fac Editor │   (JSON messages over stdio)   │  (e.g., pylsp)   │
│             │                                 │                  │
└─────────────┘                                 └──────────────────┘
     │                                                    │
     │ You edit code                                     │ Analyzes code
     │ Send changes                                      │ Finds errors
     │ Request features                                  │ Provides completions

When you open a file in fac:

  1. fac starts the appropriate language server (e.g., pylsp for Python)
  2. fac tells the server what file you're editing
  3. As you type, fac sends your changes to the server
  4. The server analyzes your code and sends back diagnostics (errors/warnings)
  5. When you press F12, fac asks the server "where is this defined?"
  6. The server responds with the location, and fac jumps there

Quick Start

Step 1: Install a Language Server

Language servers are separate programs you install once. Here are the most common ones:

Python:

pip install python-lsp-server

JavaScript/TypeScript:

npm install -g typescript-language-server typescript

Rust:

rustup component add rust-analyzer

Fortran:

pip install fortls

Go:

go install golang.org/x/tools/gopls@latest

C/C++:

# On macOS with Homebrew
brew install llvm
# clangd comes with LLVM

# On Linux
sudo apt install clangd

See the Language Server Setup section below for detailed instructions.

Step 2: Open a File

Just open fac with a source code file:

fac my_script.py

That's it! If you have pylsp installed, fac will automatically:

  • Start the language server
  • Begin analyzing your code
  • Show errors/warnings with red/yellow markers in the gutter
  • Enable all LSP features

Step 3: Try It Out

  1. See errors: Look for E (error) or W (warning) in the left gutter
  2. View all diagnostics: Press F8 to open the diagnostics panel
  3. Jump to definition: Put cursor on a function name and press F12
  4. Find references: Press Shift+F12 to see everywhere a symbol is used
  5. Rename: Press F2 to rename a variable across all files
  6. Format code: Press Shift+Alt+F to auto-format

LSP Features Reference

1. Diagnostics (Errors & Warnings)

What it does: Shows syntax errors, type errors, and warnings as you code.

How to use:

  • Errors appear with E in the gutter (red)
  • Warnings appear with W in the gutter (yellow)
  • Put your cursor on a line with an error to see the message in the status bar
  • Press F8 to open the Diagnostics Panel showing all issues

Example:

def greet(name):
    print("Hello, " + nme)  # Error: 'nme' is not defined
    ^^^^^^^^^^^^^^^^^^^^
    E: Undefined name 'nme'

Keybinding:

  • F8 or Alt+E - Open/close diagnostics panel
  • j/k or / - Navigate issues in panel
  • Enter - Jump to selected issue
  • Esc - Close panel

2. Go to Definition (F12)

What it does: Jump to where a function, variable, or class is defined.

How to use:

  1. Put your cursor on a symbol (function name, variable, class, etc.)
  2. Press F12
  3. fac jumps to the definition (opens file in new tab if needed)
  4. Press Alt+, to jump back to where you were

Example:

# In main.py
result = calculate_total(items)
         ^^^^^^^^^^^^^^^
         Put cursor here, press F12

# Jumps to utils.py:
def calculate_total(items):  # ← You land here
    return sum(item.price for item in items)

Keybindings:

  • F12 or Ctrl+\ or Alt+G - Go to definition
  • Alt+, - Jump back (navigate backward in jump history)

Cross-file navigation: If the definition is in another file, fac automatically opens it in a new tab!


3. Find References (Shift+F12)

What it does: Find all places where a symbol is used across your entire project.

How to use:

  1. Put cursor on a symbol
  2. Press Shift+F12
  3. Browse references in the panel
  4. Press Enter to jump to a reference

Example:

# You want to find everywhere `calculate_total` is called
def calculate_total(items):
    ...

# Press Shift+F12 shows:
References to 'calculate_total':
  main.py:15:12  - result = calculate_total(items)
  test.py:23:8   - assert calculate_total([]) == 0
  utils.py:45:3  - total = calculate_total(cart.items)

Keybindings:

  • Shift+F12 or Alt+R - Find all references
  • j/k or / - Navigate references
  • Enter - Jump to selected reference
  • Esc - Close panel

4. Code Actions & Quick Fixes (Alt+.)

What it does: Get quick fixes for errors and refactoring suggestions.

How to use:

  1. Put cursor on a line with a diagnostic (error/warning)
  2. Press F10 or Alt+.
  3. Select an action from the menu
  4. Press Enter to apply it

Example:

# Error: Missing import
result = json.loads(data)
         ^^^^
         Error: 'json' is not defined

# Press Ctrl+. shows:
Code Actions:
  → Import 'json'
    Ignore undefined name 'json'

# Select "Import 'json'" and fac adds:
import json  # ← Automatically added!

Common actions:

  • Add missing imports
  • Fix spelling errors in variable names
  • Extract method/function
  • Organize imports
  • Add type hints

Keybindings:

  • F10 or Alt+. - Open code actions menu
  • j/k or / - Navigate actions
  • 1-9 - Quick select action by number
  • Enter - Apply selected action
  • Esc - Close menu

Note: Code actions are context-sensitive. On a line without diagnostics, you'll only see global actions like "Organize imports" and "Fix all". Position cursor on a line with an error/warning to see specific fixes.


5. Rename Symbol (F2)

What it does: Rename a variable, function, or class everywhere it's used.

How to use:

  1. Put cursor on a symbol
  2. Press F2
  3. Type the new name
  4. Press Enter
  5. The symbol is renamed everywhere across all files!

Example:

# Before:
def calc(x, y):
    return x + y

result = calc(5, 3)
total = calc(10, 20)

# Put cursor on 'calc', press F2, type 'calculate'
# After:
def calculate(x, y):
    return x + y

result = calculate(5, 3)
total = calculate(10, 20)

Safe renaming: The language server understands your code's structure, so it won't accidentally rename:

  • String contents: "call calc function" stays unchanged
  • Comments: # calc is fast stays unchanged
  • Unrelated variables with the same name in different scopes

Keybinding:

  • F2 - Rename symbol
  • Type new name, press Enter to confirm
  • Press Esc to cancel

6. Document Symbols Outline (F4)

What it does: See an outline of all functions, classes, and variables in the current file.

How to use:

  1. Press F4 to open the symbols panel
  2. Type to filter symbols (fuzzy search)
  3. Press Enter to jump to a symbol

Example:

Document Symbols:
  [Class] User
    [Method] __init__
    [Method] validate
    [Property] full_name
  [Function] create_user
  [Function] delete_user
  [Variable] DEFAULT_TIMEOUT

Keybindings:

  • F4 or Alt+O - Open document symbols panel
  • Type to search (fuzzy matching)
  • j/k or / - Navigate symbols
  • Enter - Jump to selected symbol
  • Esc - Close panel

7. Workspace Symbols (F6)

What it does: Search for any symbol across your entire project (all files).

How to use:

  1. Press F6 to open workspace symbols
  2. Type part of a symbol name (fuzzy search)
  3. Navigate and press Enter to jump to it

Example:

# Type "calc"
Workspace Symbols:
  [Function] calculate_total      in utils.py
  [Function] calculator_init      in calculator.py
  [Class] Calculator              in calculator.py
  [Method] recalculate            in models.py
  [Variable] CALC_PRECISION       in config.py

Fuzzy search: You don't need to type the exact name:

  • calc matches calculate_total
  • ct matches calculate_total (first letters)
  • calctot matches calculate_total (consecutive)

Keybindings:

  • F6 or Alt+P - Open workspace symbols
  • Type to search across all files
  • j/k or / - Navigate results
  • Enter - Jump to symbol (opens file if needed)
  • Esc - Close panel

Pro tip: This is incredibly fast for navigating large codebases!


8. Signature Help

What it does: Shows function parameters and types as you're typing a function call.

How to use: Just start typing a function call with (, and a tooltip appears:

Example:

# You type:
result = calculate_total(
                        ^
                        Cursor here

# Tooltip shows:
calculate_total(items: list[Item], tax_rate: float = 0.0) -> float
                ^^^^^
                Current parameter highlighted

Keybindings:

  • Appears automatically when you type (
  • Type , to move to next parameter
  • Auto-dismisses when you type )

Works with:

  • Regular functions
  • Class constructors
  • Methods
  • Overloaded functions (shows all signatures)

9. Document Formatting (Shift+Alt+F)

What it does: Automatically formats your code according to style guidelines.

How to use:

  1. Press Shift+Alt+F
  2. Your code is instantly formatted

Example:

# Before:
def greet(  name,age  ):
  if age>18:
        print(  "Hello, "+name )
  else:print("Hi, "+name)

# After (Shift+Alt+F):
def greet(name, age):
    if age > 18:
        print("Hello, " + name)
    else:
        print("Hi, " + name)

Respects:

  • .editorconfig settings
  • Language-specific style guides (PEP 8 for Python, etc.)
  • Project configuration files (.pylintrc, pyproject.toml, etc.)

Keybinding:

  • Shift+Alt+F - Format entire document

Formatters by language:

  • Python: black, autopep8, or yapf (configured in pylsp)
  • JavaScript: prettier
  • Rust: rustfmt
  • Go: gofmt

10. Command Palette (Ctrl+P)

What it does: Quick access to all LSP commands without remembering keybindings.

How to use:

  1. Press Ctrl+P
  2. Type to search commands (fuzzy search)
  3. Press Enter to execute

Available commands:

Command Palette:
  [LSP] Go to Definition
  [LSP] Find References
  [LSP] Rename Symbol
  [LSP] Code Actions
  [LSP] Document Symbols
  [LSP] Workspace Symbols
  [LSP] Format Document
  [File] Save File
  [Navigate] Jump Back
  ... and 40+ more!

Keybindings:

  • Ctrl+P - Open command palette
  • Type to search commands
  • Enter - Execute selected command
  • Esc - Close palette

Language Server Setup

Python (pylsp)

Install:

pip install python-lsp-server

# Optional plugins for more features:
pip install python-lsp-black      # Black formatting
pip install pylsp-mypy            # Type checking
pip install python-lsp-ruff       # Fast linting

What you get:

  • Error detection (syntax, undefined variables)
  • Auto-completion
  • Go to definition / Find references
  • Rename symbol
  • Code formatting (with black)
  • Type checking (with mypy)

Configuration: Create ~/.config/pylsp/config.json:

{
  "plugins": {
    "black": {"enabled": true},
    "mypy": {"enabled": true}
  }
}

JavaScript/TypeScript (typescript-language-server)

Install:

npm install -g typescript-language-server typescript

What you get:

  • Error detection (TypeScript type errors)
  • Auto-completion with type information
  • Refactoring (extract function, rename, etc.)
  • Import management
  • JSDoc support

Works with:

  • JavaScript (.js)
  • TypeScript (.ts, .tsx)
  • JSX/React files

Rust (rust-analyzer)

Install:

rustup component add rust-analyzer

What you get:

  • Instant error detection
  • Powerful type inference
  • Macro expansion
  • Cargo integration
  • Inline type hints

Note: Works best with Cargo.toml in your project root.


Fortran (fortls)

Install:

pip install fortls

What you get:

  • Syntax error detection
  • Module/subroutine navigation
  • Variable completion
  • Signature help
  • Hover documentation

Configuration: Create .fortls in your project root:

{
  "lowercase_intrinsics": true,
  "hover_signature": true,
  "use_signature_help": true
}

Go (gopls)

Install:

go install golang.org/x/tools/gopls@latest

What you get:

  • Error detection
  • Auto-imports
  • Refactoring tools
  • Test integration
  • Fast navigation

C/C++ (clangd)

Install:

# macOS
brew install llvm

# Ubuntu/Debian
sudo apt install clangd

# Arch
sudo pacman -S clang

What you get:

  • Real-time error checking
  • Include path completion
  • Cross-reference navigation
  • Refactoring support

Configuration: Create compile_commands.json in project root:

# With CMake:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .

# With Make:
bear -- make

Troubleshooting

"No language server found"

Problem: fac can't find the language server executable.

Solution:

  1. Make sure the language server is installed:

    which pylsp          # For Python
    which rust-analyzer  # For Rust
    which gopls          # For Go
    
  2. Make sure the executable is in your PATH:

    echo $PATH
    
  3. Try running the language server manually:

    pylsp --help
    

"LSP features not working"

Problem: File opens but no diagnostics/features appear.

Solution:

  1. Check if the server started:

    • Look in fac's logs (if available)
    • The server might have crashed on startup
  2. Check file extension matches language:

    • .py → Python
    • .rs → Rust
    • .f90, .f95 → Fortran
  3. Make sure the file is in a proper project structure:

    • Python: Have a setup.py or pyproject.toml?
    • Rust: Have a Cargo.toml?
    • Some servers need project metadata

"Diagnostics are slow/delayed"

Problem: Errors appear several seconds after typing.

Explanation: This is normal! Language servers analyze your code:

  • Simple syntax errors: ~100ms
  • Type checking: 500ms-2s
  • Full project analysis: 2-10s

Tips:

  • fac debounces changes (waits 500ms after you stop typing)
  • Large projects take longer
  • First-time analysis is slower (builds cache)

"Server keeps crashing"

Problem: LSP features work then suddenly stop.

Solution:

  1. Check server version:

    pylsp --version
    
  2. Update the language server:

    pip install --upgrade python-lsp-server
    
  3. Check for conflicting plugins/extensions

  4. Restart fac


"Formatting changes my code unexpectedly"

Problem: Shift+Alt+F makes unwanted changes.

Solution:

  1. Check your formatter configuration

  2. Many formatters respect configuration files:

    • Python: pyproject.toml or .pylintrc
    • JavaScript: .prettierrc
    • Rust: rustfmt.toml
  3. Configure line length, indentation, etc. in those files


Tips & Tricks

1. Use Jump Stack for Navigation

After using F12 to jump to a definition:

  • Press Alt+, to jump back
  • Works across multiple jumps (maintains history)
  • Great for exploring unfamiliar codebases

2. Combine Search Features

  • Ctrl+F - Search text in current file
  • F4 - Search symbols in current file
  • F6 - Search symbols across project
  • Shift+F12 - Find all usages of current symbol

3. Fix Errors Faster

When you see an error:

  1. Press F8 to see all errors
  2. Navigate to each error
  3. Press Ctrl+. to see quick fixes
  4. Apply fixes with Enter

4. Rename Safely

Before renaming:

  • Press Shift+F12 to see all references
  • Verify it's safe to rename
  • Press F2 to rename everywhere at once

5. Format on Save

Many language servers support format-on-save:

  • Press Ctrl+S to save
  • File is automatically formatted
  • Keeps your code style consistent

LSP Keybindings Quick Reference

Feature Keybinding What It Does
Diagnostics Panel F8 or Alt+E Show all errors/warnings
Go to Definition F12 or Ctrl+\ or Alt+G Jump to where symbol is defined
Find References Shift+F12 or Alt+R Find all usages of symbol
Code Actions F10 or Alt+. Quick fixes and refactorings
Rename Symbol F2 Rename across entire project
Document Symbols F4 or Alt+O Outline of current file
Workspace Symbols F6 or Alt+P Search symbols across project
Format Document Shift+Alt+F Auto-format code
Command Palette Ctrl+P Access all commands
Jump Back Alt+, Return to previous location

Note: Alt+key combinations work better in terminals than Ctrl+Shift combinations.


Supported Languages

fac can work with any language that has an LSP server. Here are popular ones:

Language Server Installation
Python pylsp pip install python-lsp-server
JavaScript/TypeScript typescript-language-server npm install -g typescript-language-server
Rust rust-analyzer rustup component add rust-analyzer
Go gopls go install golang.org/x/tools/gopls@latest
C/C++ clangd brew install llvm or apt install clangd
Java jdtls Download from Eclipse
Ruby solargraph gem install solargraph
PHP intelephense npm install -g intelephense
Bash bash-language-server npm install -g bash-language-server
Fortran fortls pip install fortls
Lua lua-language-server Download from GitHub
HTML/CSS vscode-html-languageserver npm install -g vscode-html-languageserver-bin

For more language servers, visit: https://microsoft.github.io/language-server-protocol/implementors/servers/


What's Next?

Now that you understand LSP in fac:

  1. Install language servers for your languages
  2. Practice the keybindings - they'll become second nature
  3. Explore your codebase with F6 and F12
  4. Let LSP catch errors before you run your code
  5. Refactor confidently with F2 and Ctrl+.

Welcome to IDE-level coding in the terminal! 🚀

View source
1 # Language Server Protocol (LSP) Guide
2
3 ## What is LSP?
4
5 **Language Server Protocol (LSP)** is like having a smart assistant that understands your programming language. It provides IDE-like features such as:
6
7 - **Error detection** as you type
8 - **Jump to definition** of functions/variables
9 - **Find all references** to a symbol
10 - **Auto-completion** suggestions
11 - **Rename** symbols across your entire project
12 - **Code formatting** to keep style consistent
13 - **Quick fixes** for common errors
14
15 Instead of building these features separately for each language, LSP uses a standardized protocol. This means `fac` can support Python, JavaScript, Fortran, Rust, and 100+ other languages using the same system!
16
17 ## How Does It Work?
18
19 ```
20 ┌─────────────┐ LSP Protocol ┌──────────────────┐
21 │ │ ◄────────────────────────────► │ Language Server │
22 │ fac Editor │ (JSON messages over stdio) │ (e.g., pylsp) │
23 │ │ │ │
24 └─────────────┘ └──────────────────┘
25 │ │
26 │ You edit code │ Analyzes code
27 │ Send changes │ Finds errors
28 │ Request features │ Provides completions
29 ```
30
31 When you open a file in `fac`:
32 1. `fac` starts the appropriate language server (e.g., `pylsp` for Python)
33 2. `fac` tells the server what file you're editing
34 3. As you type, `fac` sends your changes to the server
35 4. The server analyzes your code and sends back diagnostics (errors/warnings)
36 5. When you press F12, `fac` asks the server "where is this defined?"
37 6. The server responds with the location, and `fac` jumps there
38
39 ## Quick Start
40
41 ### Step 1: Install a Language Server
42
43 Language servers are separate programs you install once. Here are the most common ones:
44
45 **Python:**
46 ```bash
47 pip install python-lsp-server
48 ```
49
50 **JavaScript/TypeScript:**
51 ```bash
52 npm install -g typescript-language-server typescript
53 ```
54
55 **Rust:**
56 ```bash
57 rustup component add rust-analyzer
58 ```
59
60 **Fortran:**
61 ```bash
62 pip install fortls
63 ```
64
65 **Go:**
66 ```bash
67 go install golang.org/x/tools/gopls@latest
68 ```
69
70 **C/C++:**
71 ```bash
72 # On macOS with Homebrew
73 brew install llvm
74 # clangd comes with LLVM
75
76 # On Linux
77 sudo apt install clangd
78 ```
79
80 See the **Language Server Setup** section below for detailed instructions.
81
82 ### Step 2: Open a File
83
84 Just open `fac` with a source code file:
85
86 ```bash
87 fac my_script.py
88 ```
89
90 That's it! If you have `pylsp` installed, `fac` will automatically:
91 - Start the language server
92 - Begin analyzing your code
93 - Show errors/warnings with red/yellow markers in the gutter
94 - Enable all LSP features
95
96 ### Step 3: Try It Out
97
98 1. **See errors**: Look for `E` (error) or `W` (warning) in the left gutter
99 2. **View all diagnostics**: Press `F8` to open the diagnostics panel
100 3. **Jump to definition**: Put cursor on a function name and press `F12`
101 4. **Find references**: Press `Shift+F12` to see everywhere a symbol is used
102 5. **Rename**: Press `F2` to rename a variable across all files
103 6. **Format code**: Press `Shift+Alt+F` to auto-format
104
105 ---
106
107 ## LSP Features Reference
108
109 ### 1. Diagnostics (Errors & Warnings)
110
111 **What it does:** Shows syntax errors, type errors, and warnings as you code.
112
113 **How to use:**
114 - Errors appear with `E` in the gutter (red)
115 - Warnings appear with `W` in the gutter (yellow)
116 - Put your cursor on a line with an error to see the message in the status bar
117 - Press `F8` to open the **Diagnostics Panel** showing all issues
118
119 **Example:**
120 ```python
121 def greet(name):
122 print("Hello, " + nme) # Error: 'nme' is not defined
123 ^^^^^^^^^^^^^^^^^^^^
124 E: Undefined name 'nme'
125 ```
126
127 **Keybinding:**
128 - `F8` or `Alt+E` - Open/close diagnostics panel
129 - `j`/`k` or `↑`/`↓` - Navigate issues in panel
130 - `Enter` - Jump to selected issue
131 - `Esc` - Close panel
132
133 ---
134
135 ### 2. Go to Definition (F12)
136
137 **What it does:** Jump to where a function, variable, or class is defined.
138
139 **How to use:**
140 1. Put your cursor on a symbol (function name, variable, class, etc.)
141 2. Press `F12`
142 3. `fac` jumps to the definition (opens file in new tab if needed)
143 4. Press `Alt+,` to jump back to where you were
144
145 **Example:**
146 ```python
147 # In main.py
148 result = calculate_total(items)
149 ^^^^^^^^^^^^^^^
150 Put cursor here, press F12
151
152 # Jumps to utils.py:
153 def calculate_total(items): # ← You land here
154 return sum(item.price for item in items)
155 ```
156
157 **Keybindings:**
158 - `F12` or `Ctrl+\` or `Alt+G` - Go to definition
159 - `Alt+,` - Jump back (navigate backward in jump history)
160
161 **Cross-file navigation:** If the definition is in another file, `fac` automatically opens it in a new tab!
162
163 ---
164
165 ### 3. Find References (Shift+F12)
166
167 **What it does:** Find all places where a symbol is used across your entire project.
168
169 **How to use:**
170 1. Put cursor on a symbol
171 2. Press `Shift+F12`
172 3. Browse references in the panel
173 4. Press `Enter` to jump to a reference
174
175 **Example:**
176 ```python
177 # You want to find everywhere `calculate_total` is called
178 def calculate_total(items):
179 ...
180
181 # Press Shift+F12 shows:
182 References to 'calculate_total':
183 main.py:15:12 - result = calculate_total(items)
184 test.py:23:8 - assert calculate_total([]) == 0
185 utils.py:45:3 - total = calculate_total(cart.items)
186 ```
187
188 **Keybindings:**
189 - `Shift+F12` or `Alt+R` - Find all references
190 - `j`/`k` or `↑`/`↓` - Navigate references
191 - `Enter` - Jump to selected reference
192 - `Esc` - Close panel
193
194 ---
195
196 ### 4. Code Actions & Quick Fixes (Alt+.)
197
198 **What it does:** Get quick fixes for errors and refactoring suggestions.
199
200 **How to use:**
201 1. Put cursor on a line with a diagnostic (error/warning)
202 2. Press `F10` or `Alt+.`
203 3. Select an action from the menu
204 4. Press `Enter` to apply it
205
206 **Example:**
207 ```python
208 # Error: Missing import
209 result = json.loads(data)
210 ^^^^
211 Error: 'json' is not defined
212
213 # Press Ctrl+. shows:
214 Code Actions:
215 Import 'json'
216 Ignore undefined name 'json'
217
218 # Select "Import 'json'" and fac adds:
219 import json # ← Automatically added!
220 ```
221
222 **Common actions:**
223 - Add missing imports
224 - Fix spelling errors in variable names
225 - Extract method/function
226 - Organize imports
227 - Add type hints
228
229 **Keybindings:**
230 - `F10` or `Alt+.` - Open code actions menu
231 - `j`/`k` or `↑`/`↓` - Navigate actions
232 - `1`-`9` - Quick select action by number
233 - `Enter` - Apply selected action
234 - `Esc` - Close menu
235
236 **Note:** Code actions are context-sensitive. On a line without diagnostics, you'll only see global actions like "Organize imports" and "Fix all". Position cursor on a line with an error/warning to see specific fixes.
237
238 ---
239
240 ### 5. Rename Symbol (F2)
241
242 **What it does:** Rename a variable, function, or class everywhere it's used.
243
244 **How to use:**
245 1. Put cursor on a symbol
246 2. Press `F2`
247 3. Type the new name
248 4. Press `Enter`
249 5. The symbol is renamed everywhere across all files!
250
251 **Example:**
252 ```python
253 # Before:
254 def calc(x, y):
255 return x + y
256
257 result = calc(5, 3)
258 total = calc(10, 20)
259
260 # Put cursor on 'calc', press F2, type 'calculate'
261 # After:
262 def calculate(x, y):
263 return x + y
264
265 result = calculate(5, 3)
266 total = calculate(10, 20)
267 ```
268
269 **Safe renaming:** The language server understands your code's structure, so it won't accidentally rename:
270 - String contents: `"call calc function"` stays unchanged
271 - Comments: `# calc is fast` stays unchanged
272 - Unrelated variables with the same name in different scopes
273
274 **Keybinding:**
275 - `F2` - Rename symbol
276 - Type new name, press `Enter` to confirm
277 - Press `Esc` to cancel
278
279 ---
280
281 ### 6. Document Symbols Outline (F4)
282
283 **What it does:** See an outline of all functions, classes, and variables in the current file.
284
285 **How to use:**
286 1. Press `F4` to open the symbols panel
287 2. Type to filter symbols (fuzzy search)
288 3. Press `Enter` to jump to a symbol
289
290 **Example:**
291 ```
292 Document Symbols:
293 [Class] User
294 [Method] __init__
295 [Method] validate
296 [Property] full_name
297 [Function] create_user
298 [Function] delete_user
299 [Variable] DEFAULT_TIMEOUT
300 ```
301
302 **Keybindings:**
303 - `F4` or `Alt+O` - Open document symbols panel
304 - Type to search (fuzzy matching)
305 - `j`/`k` or `↑`/`↓` - Navigate symbols
306 - `Enter` - Jump to selected symbol
307 - `Esc` - Close panel
308
309 ---
310
311 ### 7. Workspace Symbols (F6)
312
313 **What it does:** Search for any symbol across your **entire project** (all files).
314
315 **How to use:**
316 1. Press `F6` to open workspace symbols
317 2. Type part of a symbol name (fuzzy search)
318 3. Navigate and press `Enter` to jump to it
319
320 **Example:**
321 ```
322 # Type "calc"
323 Workspace Symbols:
324 [Function] calculate_total in utils.py
325 [Function] calculator_init in calculator.py
326 [Class] Calculator in calculator.py
327 [Method] recalculate in models.py
328 [Variable] CALC_PRECISION in config.py
329 ```
330
331 **Fuzzy search:** You don't need to type the exact name:
332 - `calc` matches `calculate_total`
333 - `ct` matches `calculate_total` (first letters)
334 - `calctot` matches `calculate_total` (consecutive)
335
336 **Keybindings:**
337 - `F6` or `Alt+P` - Open workspace symbols
338 - Type to search across all files
339 - `j`/`k` or `↑`/`↓` - Navigate results
340 - `Enter` - Jump to symbol (opens file if needed)
341 - `Esc` - Close panel
342
343 **Pro tip:** This is incredibly fast for navigating large codebases!
344
345 ---
346
347 ### 8. Signature Help
348
349 **What it does:** Shows function parameters and types as you're typing a function call.
350
351 **How to use:**
352 Just start typing a function call with `(`, and a tooltip appears:
353
354 **Example:**
355 ```python
356 # You type:
357 result = calculate_total(
358 ^
359 Cursor here
360
361 # Tooltip shows:
362 calculate_total(items: list[Item], tax_rate: float = 0.0) -> float
363 ^^^^^
364 Current parameter highlighted
365 ```
366
367 **Keybindings:**
368 - Appears automatically when you type `(`
369 - Type `,` to move to next parameter
370 - Auto-dismisses when you type `)`
371
372 **Works with:**
373 - Regular functions
374 - Class constructors
375 - Methods
376 - Overloaded functions (shows all signatures)
377
378 ---
379
380 ### 9. Document Formatting (Shift+Alt+F)
381
382 **What it does:** Automatically formats your code according to style guidelines.
383
384 **How to use:**
385 1. Press `Shift+Alt+F`
386 2. Your code is instantly formatted
387
388 **Example:**
389 ```python
390 # Before:
391 def greet( name,age ):
392 if age>18:
393 print( "Hello, "+name )
394 else:print("Hi, "+name)
395
396 # After (Shift+Alt+F):
397 def greet(name, age):
398 if age > 18:
399 print("Hello, " + name)
400 else:
401 print("Hi, " + name)
402 ```
403
404 **Respects:**
405 - `.editorconfig` settings
406 - Language-specific style guides (PEP 8 for Python, etc.)
407 - Project configuration files (`.pylintrc`, `pyproject.toml`, etc.)
408
409 **Keybinding:**
410 - `Shift+Alt+F` - Format entire document
411
412 **Formatters by language:**
413 - Python: `black`, `autopep8`, or `yapf` (configured in `pylsp`)
414 - JavaScript: `prettier`
415 - Rust: `rustfmt`
416 - Go: `gofmt`
417
418 ---
419
420 ### 10. Command Palette (Ctrl+P)
421
422 **What it does:** Quick access to all LSP commands without remembering keybindings.
423
424 **How to use:**
425 1. Press `Ctrl+P`
426 2. Type to search commands (fuzzy search)
427 3. Press `Enter` to execute
428
429 **Available commands:**
430 ```
431 Command Palette:
432 [LSP] Go to Definition
433 [LSP] Find References
434 [LSP] Rename Symbol
435 [LSP] Code Actions
436 [LSP] Document Symbols
437 [LSP] Workspace Symbols
438 [LSP] Format Document
439 [File] Save File
440 [Navigate] Jump Back
441 ... and 40+ more!
442 ```
443
444 **Keybindings:**
445 - `Ctrl+P` - Open command palette
446 - Type to search commands
447 - `Enter` - Execute selected command
448 - `Esc` - Close palette
449
450 ---
451
452 ## Language Server Setup
453
454 ### Python (pylsp)
455
456 **Install:**
457 ```bash
458 pip install python-lsp-server
459
460 # Optional plugins for more features:
461 pip install python-lsp-black # Black formatting
462 pip install pylsp-mypy # Type checking
463 pip install python-lsp-ruff # Fast linting
464 ```
465
466 **What you get:**
467 - Error detection (syntax, undefined variables)
468 - Auto-completion
469 - Go to definition / Find references
470 - Rename symbol
471 - Code formatting (with black)
472 - Type checking (with mypy)
473
474 **Configuration:**
475 Create `~/.config/pylsp/config.json`:
476 ```json
477 {
478 "plugins": {
479 "black": {"enabled": true},
480 "mypy": {"enabled": true}
481 }
482 }
483 ```
484
485 ---
486
487 ### JavaScript/TypeScript (typescript-language-server)
488
489 **Install:**
490 ```bash
491 npm install -g typescript-language-server typescript
492 ```
493
494 **What you get:**
495 - Error detection (TypeScript type errors)
496 - Auto-completion with type information
497 - Refactoring (extract function, rename, etc.)
498 - Import management
499 - JSDoc support
500
501 **Works with:**
502 - JavaScript (`.js`)
503 - TypeScript (`.ts`, `.tsx`)
504 - JSX/React files
505
506 ---
507
508 ### Rust (rust-analyzer)
509
510 **Install:**
511 ```bash
512 rustup component add rust-analyzer
513 ```
514
515 **What you get:**
516 - Instant error detection
517 - Powerful type inference
518 - Macro expansion
519 - Cargo integration
520 - Inline type hints
521
522 **Note:** Works best with `Cargo.toml` in your project root.
523
524 ---
525
526 ### Fortran (fortls)
527
528 **Install:**
529 ```bash
530 pip install fortls
531 ```
532
533 **What you get:**
534 - Syntax error detection
535 - Module/subroutine navigation
536 - Variable completion
537 - Signature help
538 - Hover documentation
539
540 **Configuration:**
541 Create `.fortls` in your project root:
542 ```json
543 {
544 "lowercase_intrinsics": true,
545 "hover_signature": true,
546 "use_signature_help": true
547 }
548 ```
549
550 ---
551
552 ### Go (gopls)
553
554 **Install:**
555 ```bash
556 go install golang.org/x/tools/gopls@latest
557 ```
558
559 **What you get:**
560 - Error detection
561 - Auto-imports
562 - Refactoring tools
563 - Test integration
564 - Fast navigation
565
566 ---
567
568 ### C/C++ (clangd)
569
570 **Install:**
571 ```bash
572 # macOS
573 brew install llvm
574
575 # Ubuntu/Debian
576 sudo apt install clangd
577
578 # Arch
579 sudo pacman -S clang
580 ```
581
582 **What you get:**
583 - Real-time error checking
584 - Include path completion
585 - Cross-reference navigation
586 - Refactoring support
587
588 **Configuration:**
589 Create `compile_commands.json` in project root:
590 ```bash
591 # With CMake:
592 cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .
593
594 # With Make:
595 bear -- make
596 ```
597
598 ---
599
600 ## Troubleshooting
601
602 ### "No language server found"
603
604 **Problem:** `fac` can't find the language server executable.
605
606 **Solution:**
607 1. Make sure the language server is installed:
608 ```bash
609 which pylsp # For Python
610 which rust-analyzer # For Rust
611 which gopls # For Go
612 ```
613
614 2. Make sure the executable is in your `PATH`:
615 ```bash
616 echo $PATH
617 ```
618
619 3. Try running the language server manually:
620 ```bash
621 pylsp --help
622 ```
623
624 ---
625
626 ### "LSP features not working"
627
628 **Problem:** File opens but no diagnostics/features appear.
629
630 **Solution:**
631 1. Check if the server started:
632 - Look in `fac`'s logs (if available)
633 - The server might have crashed on startup
634
635 2. Check file extension matches language:
636 - `.py` → Python
637 - `.rs` → Rust
638 - `.f90`, `.f95` → Fortran
639
640 3. Make sure the file is in a proper project structure:
641 - Python: Have a `setup.py` or `pyproject.toml`?
642 - Rust: Have a `Cargo.toml`?
643 - Some servers need project metadata
644
645 ---
646
647 ### "Diagnostics are slow/delayed"
648
649 **Problem:** Errors appear several seconds after typing.
650
651 **Explanation:** This is normal! Language servers analyze your code:
652 - Simple syntax errors: ~100ms
653 - Type checking: 500ms-2s
654 - Full project analysis: 2-10s
655
656 **Tips:**
657 - `fac` debounces changes (waits 500ms after you stop typing)
658 - Large projects take longer
659 - First-time analysis is slower (builds cache)
660
661 ---
662
663 ### "Server keeps crashing"
664
665 **Problem:** LSP features work then suddenly stop.
666
667 **Solution:**
668 1. Check server version:
669 ```bash
670 pylsp --version
671 ```
672
673 2. Update the language server:
674 ```bash
675 pip install --upgrade python-lsp-server
676 ```
677
678 3. Check for conflicting plugins/extensions
679
680 4. Restart `fac`
681
682 ---
683
684 ### "Formatting changes my code unexpectedly"
685
686 **Problem:** `Shift+Alt+F` makes unwanted changes.
687
688 **Solution:**
689 1. Check your formatter configuration
690 2. Many formatters respect configuration files:
691 - Python: `pyproject.toml` or `.pylintrc`
692 - JavaScript: `.prettierrc`
693 - Rust: `rustfmt.toml`
694
695 3. Configure line length, indentation, etc. in those files
696
697 ---
698
699 ## Tips & Tricks
700
701 ### 1. Use Jump Stack for Navigation
702
703 After using F12 to jump to a definition:
704 - Press `Alt+,` to jump back
705 - Works across multiple jumps (maintains history)
706 - Great for exploring unfamiliar codebases
707
708 ### 2. Combine Search Features
709
710 - `Ctrl+F` - Search text in current file
711 - `F4` - Search symbols in current file
712 - `F6` - Search symbols across project
713 - `Shift+F12` - Find all usages of current symbol
714
715 ### 3. Fix Errors Faster
716
717 When you see an error:
718 1. Press `F8` to see all errors
719 2. Navigate to each error
720 3. Press `Ctrl+.` to see quick fixes
721 4. Apply fixes with `Enter`
722
723 ### 4. Rename Safely
724
725 Before renaming:
726 - Press `Shift+F12` to see all references
727 - Verify it's safe to rename
728 - Press `F2` to rename everywhere at once
729
730 ### 5. Format on Save
731
732 Many language servers support format-on-save:
733 - Press `Ctrl+S` to save
734 - File is automatically formatted
735 - Keeps your code style consistent
736
737 ---
738
739 ## LSP Keybindings Quick Reference
740
741 | Feature | Keybinding | What It Does |
742 |---------|-----------|--------------|
743 | **Diagnostics Panel** | `F8` or `Alt+E` | Show all errors/warnings |
744 | **Go to Definition** | `F12` or `Ctrl+\` or `Alt+G` | Jump to where symbol is defined |
745 | **Find References** | `Shift+F12` or `Alt+R` | Find all usages of symbol |
746 | **Code Actions** | `F10` or `Alt+.` | Quick fixes and refactorings |
747 | **Rename Symbol** | `F2` | Rename across entire project |
748 | **Document Symbols** | `F4` or `Alt+O` | Outline of current file |
749 | **Workspace Symbols** | `F6` or `Alt+P` | Search symbols across project |
750 | **Format Document** | `Shift+Alt+F` | Auto-format code |
751 | **Command Palette** | `Ctrl+P` | Access all commands |
752 | **Jump Back** | `Alt+,` | Return to previous location |
753
754 **Note:** Alt+key combinations work better in terminals than Ctrl+Shift combinations.
755
756 ---
757
758 ## Supported Languages
759
760 `fac` can work with **any** language that has an LSP server. Here are popular ones:
761
762 | Language | Server | Installation |
763 |----------|--------|--------------|
764 | Python | `pylsp` | `pip install python-lsp-server` |
765 | JavaScript/TypeScript | `typescript-language-server` | `npm install -g typescript-language-server` |
766 | Rust | `rust-analyzer` | `rustup component add rust-analyzer` |
767 | Go | `gopls` | `go install golang.org/x/tools/gopls@latest` |
768 | C/C++ | `clangd` | `brew install llvm` or `apt install clangd` |
769 | Java | `jdtls` | Download from Eclipse |
770 | Ruby | `solargraph` | `gem install solargraph` |
771 | PHP | `intelephense` | `npm install -g intelephense` |
772 | Bash | `bash-language-server` | `npm install -g bash-language-server` |
773 | Fortran | `fortls` | `pip install fortls` |
774 | Lua | `lua-language-server` | Download from GitHub |
775 | HTML/CSS | `vscode-html-languageserver` | `npm install -g vscode-html-languageserver-bin` |
776
777 For more language servers, visit: https://microsoft.github.io/language-server-protocol/implementors/servers/
778
779 ---
780
781 ## What's Next?
782
783 Now that you understand LSP in `fac`:
784
785 1. **Install language servers** for your languages
786 2. **Practice the keybindings** - they'll become second nature
787 3. **Explore your codebase** with `F6` and `F12`
788 4. **Let LSP catch errors** before you run your code
789 5. **Refactor confidently** with `F2` and `Ctrl+.`
790
791 Welcome to IDE-level coding in the terminal! 🚀