Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions DESIGN_MULTI_BUFFERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Conception du Système de Multi-Buffers pour `led`

## Objectif
Permettre à l'utilisateur de basculer entre le buffer principal (édition de fichier) et N buffers alternatifs indépendants. Ces buffers peuvent être utilisés pour saisir des commandes ou du texte temporaire sans affecter le fichier ouvert.

## Changements Structurels

### 1. État Global (`globals.py`)
Nous allons introduire une structure pour stocker l'état de chaque buffer.
- `GLOBALS["BUFFERS"]`: Une liste d'objets (dictionnaires) contenant l'état complet d'un buffer.
- `GLOBALS["CURRENT_BUFFER_INDEX"]`: L'index du buffer actuellement affiché.

Chaque objet buffer contiendra :
- `BUFFER` (les lignes)
- `LINE_INDEX`, `COLUMN_INDEX` (liste des longueurs de lignes)
- `LINE_BUFFER_LEFT`, `LINE_BUFFER_RIGHT`
- `FILENAME`
- `LEXER`
- `IS_FILE_SAVED`
- `TYPE`: `"FILE"` ou `"SCRATCH"`

### 2. Gestion des Événements (`base_events.py`)
- Ajout de `switch_buffer(direction)` : Sauvegarde l'état actuel dans `GLOBALS["BUFFERS"][current]` et charge `GLOBALS["BUFFERS"][new]`.
- Nouveaux raccourcis clavier :
- `CTRL_B` : Créer/Basculer vers le buffer suivant.
- `CTRL_G` : Revenir au buffer principal (index 0).
- `CTRL_E` : (Dans un buffer alternatif) Exécuter le contenu comme une commande shell ou commande led.

### 3. Interface Utilisateur (`ui.py`)
- Mise à jour du bandeau supérieur pour afficher l'index du buffer actuel (ex: `[1/3]`) et son type.
- Si le buffer est de type `"SCRATCH"`, afficher un indicateur visuel différent.

### 4. Exécution de Commandes
- Un nouveau module ou une fonction dans `base_events.py` pour traiter le contenu d'un buffer alternatif.

## Flux de Travail
1. Modifier `globals.py` pour initialiser la liste des buffers.
2. Créer une fonction de synchronisation dans `base_events.py`.
3. Intercepter les touches de basculement.
4. Adapter `ui.py`.
5. Implémenter la logique d'exécution.
49 changes: 48 additions & 1 deletion base_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,51 @@ def initBuffers():
GLOBALS["LINE_BUFFER_LEFT"] = GLOBALS["BUFFER"][GLOBALS["LINE_INDEX"]][:GLOBALS["COLUMN_INDEX"][GLOBALS["LINE_INDEX"]]]
GLOBALS["LINE_BUFFER_RIGHT"] = GLOBALS["BUFFER"][GLOBALS["LINE_INDEX"]][GLOBALS["COLUMN_INDEX"][GLOBALS["LINE_INDEX"]]:]

def save_current_buffer_state():
if not GLOBALS["BUFFERS"]: return
key = GLOBALS["CURRENT_BUFFER_KEY"]
state = {
"FILENAME": GLOBALS["FILENAME"],
"BUFFER": list(GLOBALS["BUFFER"]),
"LINE_INDEX": GLOBALS["LINE_INDEX"],
"COLUMN_INDEX": list(GLOBALS["COLUMN_INDEX"]),
"NUMBER_OF_DIGITS": GLOBALS["NUMBER_OF_DIGITS"],
"IS_FILE_SAVED": GLOBALS["IS_FILE_SAVED"],
"LEXER": GLOBALS["LEXER"],
"TYPE": GLOBALS["BUFFERS"][key].get("TYPE", "FILE")
}
GLOBALS["BUFFERS"][key] = state

def load_buffer_state(key):
state = GLOBALS["BUFFERS"][key]
GLOBALS["FILENAME"] = state["FILENAME"]
GLOBALS["BUFFER"] = state["BUFFER"]
GLOBALS["LINE_INDEX"] = state["LINE_INDEX"]
GLOBALS["COLUMN_INDEX"] = state["COLUMN_INDEX"]
GLOBALS["NUMBER_OF_DIGITS"] = state["NUMBER_OF_DIGITS"]
GLOBALS["IS_FILE_SAVED"] = state["IS_FILE_SAVED"]
GLOBALS["LEXER"] = state["LEXER"]
GLOBALS["CURRENT_BUFFER_KEY"] = key
initBuffers()

def create_scratch_buffer():
state = {
"FILENAME": f"scratch_{len(GLOBALS['BUFFERS'])}",
"BUFFER": [""],
"LINE_INDEX": 0,
"COLUMN_INDEX": [0],
"NUMBER_OF_DIGITS": 1,
"IS_FILE_SAVED": True,
"LEXER": None,
"TYPE": "SCRATCH"
}
GLOBALS["BUFFERS"].append(state)
return len(GLOBALS["BUFFERS"]) - 1

def handle_go_to_main_buffer():
save_current_buffer_state()
load_buffer_state(0)


def get_max_digit_number(integer: int)->int:
if integer < 10: return 1
Expand Down Expand Up @@ -203,7 +248,9 @@ def handle_base_events(char: chr)->bool:
GLOBALS["COLUMN_INDEX"][GLOBALS["LINE_INDEX"]] += 4
GLOBALS["IS_FILE_SAVED"] = False


elif char == GLOBALS["CTRL_G_KEY"]:
handle_go_to_main_buffer()

else:
char_decoded = char.decode("utf-8","replace")
if char_decoded.isprintable():
Expand Down
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"code-color-scheme" : "zenburn"
"code-color-scheme" : "monokai"
}
8 changes: 7 additions & 1 deletion globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
GLOBALS = {}

#globals
GLOBALS["CURRENT_BUFFER_KEY"] = "main"
GLOBALS["BUFFERS"] = {}
GLOBALS["PAPERCLIP"] = None

# Les clés suivantes seront synchronisées avec GLOBALS["BUFFERS"][GLOBALS["CURRENT_BUFFER_KEY"]]
GLOBALS["FILENAME"] = None
GLOBALS["BUFFER"]: List[str] = None #lines of the opened file
GLOBALS["MODULE_BUFFER"]: List[str] = None # a display for modules
Expand All @@ -17,7 +22,6 @@
GLOBALS["NUMBER_OF_DIGITS"]: int = None
GLOBALS["IS_FILE_SAVED"]:bool = None
GLOBALS["LEXER"] = None
GLOBALS["PAPERCLIP"] = None

#KEY CODES
GLOBALS["ESCAPE_KEY"] = b"\x1b"
Expand Down Expand Up @@ -53,6 +57,8 @@
GLOBALS["CTRL_C_KEY"] = b"\x03"
GLOBALS["CTRL_X_KEY"] = b"\x18"
GLOBALS["CTRL_V_KEY"] = b"\x16"
GLOBALS["CTRL_B_KEY"] = b"\x02" # Switch/Create Buffer
GLOBALS["CTRL_G_KEY"] = b"\x07" # Go to Main Buffer

# reading the configuration
with open(CONFIG_PATH,"r") as config:
Expand Down
14 changes: 14 additions & 0 deletions led.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ def openFile(filename: str,line_index: int = 0):
except Exception:
GLOBALS["LEXER"] = TextLexer()

# Initialisation de la liste des buffers avec le fichier ouvert
from base_events import save_current_buffer_state
GLOBALS["BUFFERS"] = [{
"FILENAME": GLOBALS["FILENAME"],
"BUFFER": list(GLOBALS["BUFFER"]),
"LINE_INDEX": GLOBALS["LINE_INDEX"],
"COLUMN_INDEX": list(GLOBALS["COLUMN_INDEX"]),
"NUMBER_OF_DIGITS": GLOBALS["NUMBER_OF_DIGITS"],
"IS_FILE_SAVED": GLOBALS["IS_FILE_SAVED"],
"LEXER": GLOBALS["LEXER"],
"TYPE": "FILE"
}]
GLOBALS["CURRENT_BUFFER_KEY"] = "main"

initBuffers()

def init(argv: List[str]):
Expand Down
13 changes: 11 additions & 2 deletions ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ def render():
save_status_char = "\x1b[1;32m~\x1b[0;0m" if GLOBALS["IS_FILE_SAVED"] else "\x1b[1;35m~\x1b[0;0m"
current_digit_number = get_max_digit_number(GLOBALS["LINE_INDEX"]+1)
cursor_coordinates = f'\x1b[{1 + (GLOBALS["COLUMN_INDEX"][GLOBALS["LINE_INDEX"]] + GLOBALS["NUMBER_OF_DIGITS"] + 3) // columns_number};{1 + (GLOBALS["COLUMN_INDEX"][GLOBALS["LINE_INDEX"]] + GLOBALS["NUMBER_OF_DIGITS"] + 3) % columns_number}f'
highlighted_buffer = highlight(GLOBALS["LINE_BUFFER_LEFT"] + GLOBALS["LINE_BUFFER_RIGHT"],GLOBALS["LEXER"],Terminal256Formatter(style=CONFIG["code-color-scheme"]))[:-1]

# Gestion du lexer pour les buffers scratch (souvent None)
lexer = GLOBALS["LEXER"]
from pygments.lexers import TextLexer
if lexer is None: lexer = TextLexer()

highlighted_buffer = highlight(GLOBALS["LINE_BUFFER_LEFT"] + GLOBALS["LINE_BUFFER_RIGHT"],lexer,Terminal256Formatter(style=CONFIG["code-color-scheme"]))[:-1]

#building the file display buffer
inf = max(0,GLOBALS["LINE_INDEX"]-((lines_number-displayed_lines_number)//2))
Expand Down Expand Up @@ -55,4 +61,7 @@ def render():
file_highlighted_buffer = f'{top_file_buffer if len(top_file_buffer) > 0 else ""}\x1b[1;31m{GLOBALS["LINE_INDEX"]+1}{" " * (GLOBALS["NUMBER_OF_DIGITS"] - get_max_digit_number(GLOBALS["LINE_INDEX"]+1))} > \x1b[7;39m{GLOBALS["BUFFER"][GLOBALS["LINE_INDEX"]]}\x1b[0;0m{fill_line(len(GLOBALS["BUFFER"][GLOBALS["LINE_INDEX"]])+ 3 + GLOBALS["NUMBER_OF_DIGITS"],columns_number)}\n{bottom_file_buffer}'

#actual rendering
print(f'\x1b[1;1f\x1b[0;33m{GLOBALS["LINE_INDEX"]+1}\x1b[0;0m{" " * (GLOBALS["NUMBER_OF_DIGITS"] - current_digit_number)} {save_status_char} {highlighted_buffer}{" " * ((columns_number - 3 - GLOBALS["NUMBER_OF_DIGITS"] - len(GLOBALS["LINE_BUFFER_LEFT"] + GLOBALS["LINE_BUFFER_RIGHT"])) % columns_number)}\n{"—"*columns_number}\n{file_highlighted_buffer}{" "*(lines_number-displayed_lines_number)*columns_number}{cursor_coordinates}',end="",flush=True)
header = f'\x1b[0;33m{GLOBALS["LINE_INDEX"]+1}\x1b[0;0m{" " * (GLOBALS["NUMBER_OF_DIGITS"] - current_digit_number)} {save_status_char} {highlighted_buffer}'
padding = " " * (max(0, columns_number - (3 + GLOBALS["NUMBER_OF_DIGITS"] + len(GLOBALS["LINE_BUFFER_LEFT"] + GLOBALS["LINE_BUFFER_RIGHT"]))))

print(f'\x1b[1;1f{header}{padding}\n{"—"*columns_number}\n{file_highlighted_buffer}{" "*(lines_number-displayed_lines_number)*columns_number}{cursor_coordinates}',end="",flush=True)