Résultats de recherche pour json

NodeJS et MongoDB : requête « JOIN » fonctionnelle

// Exemple copié collé et adapté sur stackoverflow :              
// http://stackoverflow.com/questions/15630770/node-js-check-if-path-is-file-or-directory
// http://stackoverflow.com/questions/7268033/basic-static-file-server-in-nodejs 
//                                                                               
var http = require('http'),                                            
    url = require('url'),                          
    fs = require('fs'),                            
    mongoose = require('mongoose'),                
    fileSystem = require('fs'),                    
    path = require('path');                        
var mimeTypes = {                                                                
    "html": "text/html",                 
    "jpeg": "image/jpeg",                
    "jpg": "image/jpeg",                 
    "png": "image/png",                  
    "js": "text/javascript",             
    "css": "text/css"};                  
                                                                                 
var server;                                                                      
var Schema = mongoose.Schema;                                                    
                                                                                 
mongoose.connect('mongodb://localhost/test');                          
var db = mongoose.connection;                                                    
                                                                                 
var creneauSchema = new Schema({                                                 
    libelle:    String,                                      
    date_debut: { type: Date, default: Date.now },           
    date_fin:   { type: Date, default: Date.now },           
    heure_debut: Number,                                     
    duree: Number,                                           
    creneauxJours_id: { type: Schema.Types.ObjectId, ref: 'CreneauJours' }
});                                                                              
var Creneau = db.model('Creneau', creneauSchema);                      
                                                                                 
var creneauJoursSchema = new Schema({                                            
    jours_semaine: [Number]                                  
});                                                                              
var CreneauJours = db.model('CreneauJours', creneauJoursSchema);       
                                                                                 
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {                                          
    console.log('DB connexion reussie');           
    //var cj = new CreneauJours({                            
    //    jours_semaine: [1,2,3,4,5]                         
    //});                                                    
    //cj.save(function (err) {                               
    //    if (err) { return console.log(err); }              
    //    console.log('Écriture réussie');
    //    var c = new Creneau({                              
    //        libelle: "Après midi à 16 heures",
    //        date_debut: new Date(2010, 1, 1),              
    //        date_fin:   new Date(2020, 1, 1),              
    //        heure_debut: 16,                               
    //        duree: 120,                                    
    //        creneauxJours_id: cj._id                       
    //    });                                                
    //    c.save(function (err) {                            
    //        if (err) { return console.log(err); }          
    //        console.log('Écriture 2 réussie');
    //    });                                                
    //});                                                    
    //return;                                                
                                                                                 
    server = http.createServer(function (request, response) {
        if (request.url=='/creneaux') {
            console.log("> JSON");
            Creneau  
            .find({})
            .select('_id libelle date_debut date_fin heure_debut duree creneauxJours_id')
            .populate('creneauxJours_id')
            .exec(function (err, c) {
                if (err) {
                    return console.log(err);
                }
                console.log(c);
                var retour='[';
                for (var i = 0; i < c.length; i++) {
                    retour += '{'
                        + 'id:' + JSON.stringify(c[i]._id)+', '
                        + 'libelle:' + JSON.stringify(c[i].libelle)+', '
                        + 'date_debut:' + c[i].date_debut+', '
                        + 'date_fin:' + c[i].date_fin+', '
                        + 'heure_debut:' + c[i].heure_debut+', '
                        + 'duree:' + c[i].duree+', '
                        + 'jours:[' + c[i].creneauxJours_id.jours_semaine + ']'
                        + '},';
                };
                /* Enlever la dernière virgule : */
                retour=retour.substr(0, retour.length-1)+']';
                response.writeHead(200, {
                    'Cache-Control': 'no-cache, must-revalidate',
                    'Expires': 'Mon, 26 Jul 1997 05:00:00 GMT',
                    'Content-type': 'application/json'
                });
                response.end(retour);
            });      
            // Stopper tout traitement :
            return;  
        }                                
        var uri = url.parse(request.url).pathname;
        var filename = path.join(process.cwd(), uri);
        console.log("> " + filename);
        fs.exists(filename, function(exists) {
            if ((!exists) || (fs.lstatSync(filename).isDirectory())) {
                console.log(">> fichier inexistant : " + filename);
                response.writeHead(200, {'Content-Type': 'text/plain'});
                response.write('404 Not Found\n');
                response.end();
                // Stopper tout traitement :
                return;
            }        
            var mimeType = mimeTypes[path.extname(filename).split(".")[1]];
            response.writeHead(200, {'Content-Type':mimeType});
                                                                                 
            var fileStream = fs.createReadStream(filename);
            fileStream.pipe(response);
        });                              
                                                                                 
    });                                                      
    // Listen on port 8000, IP defaults to 127.0.0.1         
    server.listen(8000);                                     
    // Put a friendly message on the terminal                
    console.log("Server running at http://127.0.0.1:8000/");
});

NodeJS qui sert des fichiers et accède à MongoDB

// Exemple copié collé et adapté sur stackoverflow :
// http://stackoverflow.com/questions/15630770/node-js-check-if-path-is-file-or-directory
// http://stackoverflow.com/questions/7268033/basic-static-file-server-in-nodejs
//
var http = require('http'),
    url = require('url'),
    fs = require('fs'),
    mongoose = require('mongoose'),
    fileSystem = require('fs'),
    path = require('path');
var mimeTypes = {
    "html": "text/html",
    "jpeg": "image/jpeg",
    "jpg": "image/jpeg",
    "png": "image/png",
    "js": "text/javascript",
    "css": "text/css"};

var server;
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;

var personneSchema = new Schema({
  nom: String,
  prenom: String
});
var Personne = db.model('Personne', personneSchema);

db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
    console.log('DB connexion reussie');
    server = http.createServer(function (request, response) {
        if (request.url=='/personnes') {
            console.log("> JSON");
            Personne.find({}).select('nom prenom').exec(function (err, p) {
                if (err) {
                    return console.log(err);
                }
                var retour='[';
                for (var i = 0; i < p.length; i++) {
                    retour+='{'+ p[i].nom+', '+p[i].prenom+'},';
                };
                retour=retour.substr(0, retour.length-2)+']';
                response.writeHead(200, {
                    'Cache-Control': 'no-cache, must-revalidate',
                    'Expires': 'Mon, 26 Jul 1997 05:00:00 GMT',
                    'Content-type': 'application/json'
                });
                response.end(retour);
            });
            // Stopper tout traitement :
            return;
        }
        var uri = url.parse(request.url).pathname;
        var filename = path.join(process.cwd(), uri);
        console.log("> " + filename);
        fs.exists(filename, function(exists) {
            if ((!exists) || (fs.lstatSync(filename).isDirectory())) {
                console.log(">> fichier inexistant : " + filename);
                response.writeHead(200, {'Content-Type': 'text/plain'});
                response.write('404 Not Found\n');
                response.end();
                // Stopper tout traitement :
                return;
            }
            var mimeType = mimeTypes[path.extname(filename).split(".")[1]];
            response.writeHead(200, {'Content-Type':mimeType});

            var fileStream = fs.createReadStream(filename);
            fileStream.pipe(response);
        });

        //var p = new Personne({
        // nom: 'Pons',
        // prenom: 'Olivier'
        //});
        //p.save(function (err) {
        // if (err) {
        // return console.log(err);
        // }
        // var query = Personne.find();
        // query.select('nom prenom');
        // query.exec(function (err, p) {
        // if (err) return console.log(err);
        // for (var i = 0; i < p.length; i++) {
        // console.log(p[i].nom+' '+p[i].prenom);
        // };
        // console.log('Nombre total d\'enregistrements : '+p.length);
        // });
        //})
    });
    // Listen on port 8000, IP defaults to 127.0.0.1
    server.listen(8000);
    // Put a friendly message on the terminal
    console.log("Server running at http://127.0.0.1:8000/");
});

vim : configuration

Je partage mon fichier de configuration de vim, si vous avez des suggestions, n’hésitez pas :

set nocompatible
set nocompatible
filetype plugin on
syntax enable

set ignorecase
set paste
set ruler
set modeline

set showcmd

set nowrap
set textwidth=0
set wrapmargin=0
let g:leave_my_textwidth_alone=1

set expandtab
set autoindent
set smartindent
set softtabstop=4
set tabstop=4

" Dans un fichier php, lorsqu'on tape {<CR> alors
" il fait l'indentation automatique
set shiftwidth=4

set number
colorscheme desert
colorscheme torte
colorscheme zellner

set vb t_vb=

set backup
set backupdir=~/.vim/backup
set directory=~/.vim/tmp
set fileencodings=utf-8,ucs-bom,default,latin1
set scrolloff=5
set scrolloff=15
set undolevels=1000
nmap ;bw :. w! ~/.vimxfer<CR>
nmap ;br :r ~/.vimxfer<CR>
nmap ;ba :. w! >>~/.vimxfer<CR>

" Pour la macro gset, après j'utilise F3 :
" ça sert à transformer les trucs du genre :
" - @return string le nom ajouté ...
" par :
" - @return string Nom ajouté ...
map <F3> ^3w/ [a-zA-Z]<CR><RIGHT>v/\( \\|'\)<CR>xvU
" Macro qui réindente le bloc courant d'une seule tab à droite :
map <F4> Vi{9<lt>Vi{>

" Tell vim to remember certain things when we exit
"  '10 : marks will be remembered for up to 10 previously edited files
"  "100 : will save up to 100 lines for each register
"  :20 : up to 20 lines of command-line history will be remembered
"  % : saves and restores the buffer list
"  n... : where to save the viminfo files
set viminfo='10,\"100,:20,%,n~/.viminfo

" when we reload, tell vim to restore the cursor to the saved position
augroup JumpCursorOnEdit
 au!
 autocmd BufReadPost *
 \ if expand("<afile>:p:h") !=? $TEMP |
 \ if line("'\"") > 1 && line("'\"") <= line("$") |
 \ let JumpCursorOnEdit_foo = line("'\"") |
 \ let b:doopenfold = 1 |
 \ if (foldlevel(JumpCursorOnEdit_foo) > foldlevel(JumpCursorOnEdit_foo - 1)) |
 \ let JumpCursorOnEdit_foo = JumpCursorOnEdit_foo - 1 |
 \ let b:doopenfold = 2 |
 \ endif |
 \ exe JumpCursorOnEdit_foo |
 \ endif |
 \ endif
 " Need to postpone using "zv" until after reading the modelines.
 autocmd BufWinEnter *
 \ if exists("b:doopenfold") |
 \ exe "normal zv" |
 \ if(b:doopenfold > 1) |
 \ exe "+".1 |
 \ endif |
 \ unlet b:doopenfold |
 \ endif
augroup END

set backspace=2

inoremap <silent> <Bar>   <Bar><Esc>:call <SID>align()<CR>a

function! s:align()
  let p = '^\s*|\s.*\s|\s*$'
  if exists(':Tabularize') && getline('.') =~# '^\s*|' && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p)
    let column = strlen(substitute(getline('.')[0:col('.')],'[^|]','','g'))
    let position = strlen(matchstr(getline('.')[0:col('.')],'.*|\s*\zs.*'))
    Tabularize/|/l1
    normal! 0
    call search(repeat('[^|]*|',column).'\s\{-\}'.repeat('.',position),'ce',line('.'))
  endif
endfunction

autocmd BufNewFile  * silent! 0r ~/.vim/templates/%:e.tpl
autocmd BufNewFile  *.php call search('w', '', line("w$"))
autocmd BufNewFile,BufRead *.vhost.conf set filetype=apache
autocmd BufNewFile,BufRead *.json set filetype=yaml

let g:snips_author='Olivier Pons'
let g:snips_author_email='olivier.pons@gmail.com'

" ----------------------------------------
" Smarty syntax highlighter / Rappel il est dans ~/.vim/syntax
" Pris ici http://www.vim.org/scripts/script.php?script_id=1798 :
autocmd BufRead,BufNewFile *.tpl set filetype=smarty

" ----------------------------------------
" Truc de Stackoverflow : si ouverture d'un fichier htm(l) alors
" verifier s'il y a {* *} ou {(alphanum) $xx (alphanum)}
" et si c'est le cas appliquer la syntaxe Smarty (au dessus)
autocmd BufNewFile,BufRead *.htm call s:CheckForSmarty()
autocmd BufNewFile,BufRead *.html call s:CheckForSmarty()

function! s:CheckForSmarty()
  for n in range(1, line('$'))
    "if n > 100
    "  return
    "endif

    let line = getline(n)
    if line =~ '{.*$\k\+}' || line =~ '{\*.*\*}'
      set filetype=smarty
      return
    endif
  endfor
endfunction

" (!) Ultra important sinon *tous* les mappings sont désactivés :
set nopaste

" Code will highlight trailing whitespace in red:
highlight WhitespaceEOL ctermbg=red guibg=red
match WhitespaceEOL /\s\+$/

"highlight OverLength ctermbg=red ctermfg=white guibg=#592929
"match OverLength /\%>80v.\+/
set textwidth=80
set colorcolumn=+1
highlight ColorColumn ctermbg=8
highlight Folded term=standout ctermfg=216 guifg=1 guibg=2 ctermbg=8

" Raccourci : F7 = ouvrir le fichier sous le curseur, F8 = ouvrir en vsplit :
:nnoremap <F8> :vertical wincmd f<CR>
:nnoremap <F7> :wincmd f<CR>

Google Maps API

Tutoriel :

https://developers.google.com/maps/documentation/javascript/tutorial?hl=FR

Fichier JSON qu’il faut créer :

{
  pos: {
    "lat": 0.123123,
    "lng": 0.5934257
  },
  "titre": "Titre Ma maison",
  "contenu": "Maison de chez mes parents etc etc"
}

Exemple de début de code Javascript qui charge le document :


$.getJSON("maison.json")
.done(function (data) {
    /* Code qui crée une google map dans un div */
})
.error(function(obj) {
    alert('Erreur, regardez la console');
    console.log(obj);
});

Dans l’idéal, voici ce qu’il faudrait faire pour le ready() :

$(document).ready(function() {
    /* fonction qui lance le chargement du fichier JSON,
     * et le met dans le div concerné
     */
    ajaxChargeGoogleMaps(
        "maison_parents.json",
        "#id-map1"
    );
    ajaxChargeGoogleMaps(
        "maison_personnelle.json",
        "#id-map2"
    );
});

Php, AJAX et problèmes de cache sur iOS : comment les résoudre

J’ai expliqué qu’il fallait mettre, avant de faire le tout dernier ordre de sortie echo json_encode($resultat_final); les headers JSON.

header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');

On m’a demandé à quoi servaient les entête de cache. J’ai expliqué que ça servait à s’assurer que les interrogations AJAX se feraient toujours (notez le futur), c’est à dire à demander au navigateur de ne rien garder en cache.

Comme toujours, ma mémoire me fait défaut mais mon expérience reste, et je savais qu’il faut éviter tout risque de problème cache.
J’ai retrouvé une explication concrète du problème : certaines versions du navigateur Safari sur iOS6 ne réinterrogent pas les appels AJAX.

Il suffit donc de faire deux choses :

  • Soit modifier la configuration Apache (c’est pour ça que j’ai consacré quelques heures sur les hôtes virtuels et leur configuration) pour qu’il y ait ces entêtes par défaut :
    Header set Cache-Control "no-cache"
  • Soit faire ma solution directement en Php (mais ça implique de le faire dans tous les retours AJAX – ce qui ne gêne en rien pour les petits projets)
  • Soit préciser en JavaScript de modifier le header :
    $.ajaxSetup({
        type: 'POST',
        headers: { "cache-control": "no-cache" }
    });

Toutes les solutions sont prises via le site de questions/réponses de reférence : en Anglais ici.

ExtJs : dériver un Store « générique » et s’en servir

Ça fait plus d’une journée que je cherche comment faire un Store générique, c’est à dire que j’ai plusieurs Store qui sont tous basés sur le même modèle avec le même type de proxy, etc.

Donc au lieu de faire un copier coller pour chaque Store, j’ai cherché comment en faire un « générique » auquel je pourrai appliquer une configuration « par défaut ».

Voilà le code complet résultat, avec les fonctions qui gère les erreurs possibles renvoyées par Php (session expirée, problème d’écriture en base de données, etc).

Ce qui m’a pris le plus de temps à trouver c’est que pour « surcharger » le constructeur, ça n’est pas la fonction classique « initComponent: function(){ } » mais la fonction de base "constructor: function(config) { }".

Il ne faut, de plus, surtout pas oublier d’appeler le parent, non pas via this.callParent(); mais via this.callParent([config]);.

Ci suit du code, le code de plus d’une journée de travail, en deux parties (j’espère qu’il sauvera du temps à des personnes, ou qu’il les mettra sur la bonne voie !) :

  • première partie = la surcharge
  • seconde partie = exemple d’utilisation de cette surcharge

Première partie : code de la classe

Ext.define('Ext.data.StoreHandleErrors', {
    extend: 'Ext.data.Store',
    alias: 'data.storehandleerrors',

    constructor: function(config) {
        /* (!!) Réécriture par dessus certaines propriétés
         *      du proxy : si jamais elles existent déjà,
         *      elles vont être réécrites.
         */
        config.autoLoad= true;
        config.autoSync= true;
        config.proxy.type= 'ajax';
        config.proxy.reader= {
            type: 'json',
            successProperty: 'success',
            root: 'data',
            messageProperty: 'message'
        };  
        config.proxy.writer= {
            type: 'json',
            writeAllFields: true,
            root: 'data'
        };  
        config.proxy.listeners= {

            exception: function(proxy, response, operation) {

                var error=operation.getError(),
                    title='Erreur du serveur';

                if (error instanceof Array) {
                  error=error.join("
"); } switch(response.status) { case 200: if (response.responseText!='') { var b = Ext.JSON.decode(response.responseText); if (b.title) { title=b.title; } if (b.success==false) { if (b.timeout==true) { windowLoginPanel.show(); } } } break; case -1: var error= 'Le serveur met trop de temps à répondre'+ '

'+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; case 500: var error= 'Le serveur a une erreur interne.'+ '

'+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; default: var error= 'Erreur renvoyée par le serveur non gérée.
'+ 'Détails :
'+ response.statusText+ '

'+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; } Ext.MessageBox.show({ title: title, msg: error, icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK }); } }; this.callParent([config]); this.on( 'write', function(proxy, operation) { if ( (operation.action == 'create') || (operation.action == 'update') ) { var m = this.getById( parseInt( operation.resultSet.records[0].internalId ) ); } else if (operation.action == 'destroy') { var m = this.getAt(0); } if (m) { this.panelGridEtEdit.gsGrid.getSelectionModel().select(m); } else { this.panelGridEtEdit.gsGrid.getSelectionModel().deselectAll(); } Ext.example.msg( Ext.String.capitalize(operation.action), operation.resultSet.message ); }, this ); } });

Seconde partie : utilisation de la classe

    var storeAdresses = Ext.create('Ext.data.StoreHandleErrors', {
        model: 'Intranet.Adresse',
        proxy: {
            api: {
                read: '/json/intranet/liste/adresses/',
                create:  '/json/intranet/item/adresse/?mode=create',
                update:  '/json/intranet/item/adresse/?mode=update',
                destroy: '/json/intranet/item/adresse/?mode=destroy'
            }   
        }   
    }); 

ExtJS 4 et le MVC (modèle-vue-contrôleur) – howto

Ci suivent quelques notes que j’ai prises après toute une journée passée à créer en entier l’exemple qui fonctionne.
Vous pouvez télécharger, puis décompresser l’exemple en entier en cliquant ici.
Pour l’installer et le tester c’est très simple : le répertoire s’appele « siteinternet » et c’est là qu’est le site internet, il vous suffira d’afficher la page « http://localhost/intranet/gs.php ». Oui j’ai développé cet exemple dans un sous-répertoire « intranet » car ExtJS est destiné, pour ma part à faire uniquement de l’administration.

Voici ce qui fonctionne : la vision d’une liste :

Vision d'une liste avec ExtJS 4.x (juste la vision)

Et le mode édition :

Vision d'une liste avec ExtJS 4.x (mode édition d'une ligne)

Le plus intéressant c’est le modèle MVC.
Je vous laisse lire toute la documentation ici, ici et .

Maintenant je vous fais un résumé de ce que j’ai retenu :

L’architecture

Elle doit absolument suivre ce schéma :

`-- app
    |-- controller
    |-- data
    |-- model
    |-- store
    `-- view

———————
controller =
Ce qui assemble data + model + store + view En général les contrôleurs créent les vues et attendent des évenements pour agir en conséquence.

model =
Là où on définit les colonnes des ensembles de données. C’est là aussi où on définit en général où aller chercher les données par défaut (« proxy »).

store =
Là où on définit sur quels modèles on se base, et où on surcharge là où aller chercher les données (= redéfinition de « proxy »).

Règles de syntaxe à respecter :

store = noms au pluriel :
app/store/Stations.js
model = noms au singulier :
app/model/Station.js

Notation :

  • au début, de type « bosse de chameau »,
  • au milieu tout en minuscules,
  • à la fin, de type « bosse de chameau » :

MonApplication.model.UserList
MonApp.view.user.List
MonApp.view.user.User
Panda.view.NewStation
Panda.view.SongControls

Arbre complet des fichiers de l’exemple ici :

gs
|-- app
|   |-- controller
|   |   `-- Users.js
|   |-- data
|   |   |-- users.json
|   |   `-- usersUpdate.json
|   |-- model
|   |   `-- User.js
|   |-- store
|   |   `-- Users.js
|   `-- view
|       `-- user
|           |-- Edit.js
|           `-- List.js
`-- app.js

A partir de là, à vous de jouer.

Au début, ce n’est pas simple, mais au final, c’est extrêmement évolutif et on gagne énormément de temps. Un peu comme d’apprendre vim :).

vim : insérer nom du fichier courant

Tous mes fichiers php commencent ainsi :

 1 <?php
 2 /**
 3  * fichier decision.php
 4  *
 5  * @author Olivier Pons
 6  * @version 1.0
 7  * @since 1.0
 8  * @copyright Olivier Pons
 9  *
10  * @package Ajax
11  */
12

Comment faire de manière pratique, sous vim, pour s’assurer que la ligne :
* fichier decision.php
contient vraiment le bon nom du fichier.

C’est très simple (comme tout dans vim), mais il suffit de le savoir (comme tout dans vim) :

Je vais détailler pas à pas l’explication de la macro et au final la mettre en entier :

Il faut donner l’ordre en ligne de commande = deux points = « : »
Donc : :
Il faut lui dire de rechercher = pourcent = « % »
Donc : :%
Il faut lui dire que c’est une chaine qu’on recherche = s = « s »
Donc : :%s
Ensuite on précise qu’on a fini l’ordre = slash = « / »
Donc : :%s/
Ensuite on précise le premier paramètre = chaine à rechercher = « fichier  » = « fichier  »
Donc : :%s/fichier
Ensuite on précise que le premier paramètre est une expression régulière qui doit contenir la chaine à rechercher, mais aussi tout ce qui suit = « :%s/fichier \(.*\) »
Donc : :%s/fichier \(.*\)
NB : on est obligé de mettre des antislashes \(.*\) devant les parenthèses pour dire que ce sont des caractères spéciaux qui doivent être interprétés comme des commandes.
Puis premier paramètre = fini = slash = « / »
Donc : :%s/fichier \(.*\)/
Puis le second paramètre = ce qui va être remplacé. Là c’est comme pour les parenthèses juste au dessus : on précise que c’est un « calcul » a effectuer = signe « = » mais comme c’est un caractère à interpréter on est obligé de mettre l’antislash soit \=.
Donc : :%s/fichier \(.*\)/\=
NB : à partir du signe « \=« , vim sait que ce qui suit est un calcul, donc chaque parenthèse sera déjà interprétée comme un ordre, il n’y aura pas besoin de mettre d’antislash pour les caractères spéciaux telles que les parenthèses, et ce sur tout le paramètre en entier.
Ensuite on lui passe le calcul de l’expression que j’ai fait ainsi (à vous de l’adapter pour vous) : renvoyer le nom du fichier = expand('%') =» ici moi j’aurais « ./json_decision.php » ce qui ne me convient pas. Je voulais uniquement le nom du fichier, sans quoi que ce soit derrière. On peut préciser exactement quelle partie du nom on veut : tapez « :help expand » pour avoir toutes les possibilités. Ici, moi, je ne voulais que le nom du fichier sans rien derrière. Donc j’ai juste tapé : expand('%:t')
Puis second paramètre = fini = slash = « / »
Donc : :%s/fichier \(.*\)/\='fichier '.expand('%:t')/
Enfin en troisième paramètre, les options : il n’y en a aucune mais on aurait pu mettre « g » pour dire de faire ça de manière globale, soit :
:%s/fichier \(.*\)/\='fichier '.expand('%:t')/g

Mais comme je ne veux le faire qu’une seule fois, voici ma ligne finale :

:%s/fichier \(.*\)/\='fichier '.expand('%:t')

Donc en pratique : je liste tout un répertoire de fichiers php, que j’ouvre sous vim, et j’y applique une macro qui fait :
– rechercher/remplacer que je viens d’expliquer ;
– sauvegarde du fichier et on passe au suivant (« wn« ).

Ainsi, j’ai passé tous mes fichiers et tout a fonctionné comme sur des roulettes : je suis sûr que dans tout mon code, dans le commentaire de début, le nom du fichier est en adéquation avec le vrai nom !

Si vous avez des suggestions ou commentaires n’hésitez pas !